数据结构之线性表

第二章   线性表

线性表是最基本、最简单、也是最常用的一种数据结构。

一  顺序表

1 定义

顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。

2 实践

定义顺序表类型,写出向顺序表中某位置插入数据(insert),删除某位置数据(delete),显示所有数据(traversing),根据位置取元素(getelem),定位某数据(location)的算法,并实现集合A=AUB。

typedef  int ElemType;
typedef int status ;

typedef struct
{
	ElemType *elem;
	int length ;
	int size ;
}SqList;

int main()
{
	SqList LA,LB ;
	int i ,n,temp,H;
	init_List(LA) ;
	init_List(LB) ;
	printf("输入集合A的数据个数:");
	scanf("%d",&n) ;
	printf("输入集合A的所有数据(空格隔开):");
	for(i=1;i<=n;i++)
	{
		scanf("%d",&temp);
		insertlist(LA,LA.length+1,temp) ;
	}

	printf("输入集合B的数据个数:");
	scanf("%d",&n) ;
	printf("输入集合B的所有数据(空格隔开):");
	for(i=1;i<=n;i++)
	{
		scanf("%d",&temp);
		insertlist(LB,LB.length+1,temp) ;
	}
	printf("求A=AUB,按1\n");
	printf("求A=AnB,按其他数字\n");
	scanf("%d",&H);
	if(H==1)
	{
		unionlist(LA,LB);
		printf("两个集合的并集为:");
		traveList(LA);
	}
	else
	{
		SqList S;
	        init_List(S);
		intersectionlist(LA,LB,S);
		printf("两个集合的交集为:");
		traveList(S);
	}

	system("pause");
	return 0;
}

status equal(ElemType a,ElemType b)
{
	return a==b;
}
status init_List(SqList &L) //表初始化
{
	L.elem=(ElemType*)malloc(100*sizeof(ElemType));
	if(!L.elem) return 0 ;
	L.length=0 ;
	L.size=100 ;
	return OK ;
}


int locateList(SqList L,int e,int (*compare)(int ,int))
{
	int i=1 ;
	while( i<=L.length)
	{
		if(compare(L.elem[i-1],e)) return i ;
		i++ ;
	}
	return 0  ;
}



status getelem(SqList L,int i,ElemType &e)//取表中第i个数据给e
{
  if(i<1||i>L.length)  return 0;
  e = L.elem[i-1];
  return OK ;
}



void traveList(SqList L)
{
	int i ;
	for(i=1;i<=L.length ;i++)
	    printf("%d ",L.elem[i-1]);

}

status insertlist(SqList &L,int i,ElemType e)//向表中第i个位置插入数据
{
	ElemType *newbase,*p,*q ;
	if(i<1||i>L.length+1) return 0 ;
	if(L.length>=L.size)
	{
		newbase=(ElemType*)realloc(L.elem,(L.size+20)*sizeof(ElemType));
		if(!newbase) return 0;
		L.elem=newbase;
		L.size+=20 ;
	}
	q=L.elem+i-1;
	for(p=L.elem+L.length-1;p>=q;p--)
		*(p+1)=*p ;
	*q=e ;
	L.length++ ;
	return OK ;
}


void unionlist(SqList &LA,SqList LB)//求LA=LA U LB
{
    int i,e;
    for(i=1;i<=LB.length;i++)
    {
      getelem(LB,i,e);
      if(!locateList(LA,e,equal))
         insertlist(LA,LA.length,e);
    }
}
void intersectionlist(SqList LA,SqList LB,SqList &S)//求LA=LA n LB
{

    int i,e,k=1;
    for(i=1;i<=LB.length;i++)
    {
       getelem(LB,i,e);
       if(locateList(LA,e,equal))
       {
	   insertlist(S,k,e);
	   k++;
       }

    }
}

  

二  链表

1 定义

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

2 实践

定义单链表类型,写出向单链表中某位置插入数据(insert),删除某位置数据(delete),显示所有数据(traversing),根据位置取元素(getelem),定位某数据(location)的算法,并实现集合A=AUB。

typedef  int ElemType;
typedef int Status ;

typedef struct node
{
	ElemType data;
	struct node *next ;
}node,*link;

int main()
{
	link LA,LB ;
	int n;
	printf("建立集合A:");
	createlist(LA);   
	traveList(LA);    
	transposition(LA);
	traveList(LA);     
	printf("建立集合B:");
	createlist(LB);
	traveList(LB);  
	printf("求A=AUB,按1\n");
	printf("求A=AnB,按其他数字\n");
	scanf("%d",&n);
	if(n==1)
	{
		unionlist(LA,LB);
		printf("两个集合的并集为:");
	}
	else
	{
		intersection_list(LA,LB);
		printf("两个集合的交集为:");
	}
	traveList(LA);
	system("pause");
	return 0;
}

Status equal(ElemType a,ElemType b)
{
	return a==b;
}
//带头结点的单链表表初始化
Status init_List(link &L)
{
  L=(node*)malloc(sizeof(node));
  if(!L)  return 0;
  L->next=NULL;
  return OK ;
}
//按某种比较方式找和e相关的元素,找到返回元素所在结点地址,找不到返回空
link locateList(link L,ElemType e,int (*compare)(int ,int))
{
	link p=L->next ;
	while( p )
	{
		if(compare(p->data,e)) return p ;
    p=p->next;
	}
    return NULL  ;
}
void traveList(link L)//遍历带头结点单链表
{
	link p=L->next ;
	while( p )
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}

Status createlist(link &L )//建立带头结点单链表
{
	int n ,i;
	link s;
	printf("输入数据个数:");
	scanf("%d",&n) ;
	printf("输入%d所有数据:\n",n);
	L=(link)malloc(sizeof(node)) ;
	if(!L) return 0;
	L->next=NULL ;
	for(i=1;i<=n;i++)
	{
		s=(link)malloc(sizeof(node)) ;
		if(!s) return 0;
		s->next=NULL ;
		scanf("%d",&s->data);
		s->next=L->next ;
		L->next=s ;
	}
	return 1;
}
//向带头结点的单链表中第i个位置插入数据
Status insertlist(link &L,int i,ElemType e)
{
  link p,s;
  p=L;
  int j=0;
  while(j<i-1&&p!=NULL)
  {
    p=p->next;
    j++;
  }
  if(p!=NULL)
  s=(node*)malloc(sizeof(node));
  if(!s) return 0;
  s->data=e;
  s->next=p->next;
  p->next=s;
  return OK ;
}
//从向带头结点的单链表中删除第i个位置数据
Status dellist(link &L,int i)
{
  link p,q;
  p=L;
  int j=0;
  while(p!=NULL&&j<i-1)
  {
     p=p->next;
     j++;
  }
  if(p&&p->next)
  {
      q=p->next;
      p->next=q->next;
  }
  free(q);
  return OK ;
}
//求两个集合的并集
void unionlist(link &LA,link LB)
{
	link pb;
	pb=LB->next ;
	while(pb)
	{
		if(!locateList(LA,pb->data,equal) )
		    insertlist(LA,1,pb->data) ;
		pb=pb->next ;
	}
}
//求两个集合的交集
void intersection_list(link &LA,link LB)
{
	link pb;
	int i=0;
	pb=LA->next ;
	while(pb)
	{
		i++;
		if(!locateList(LB,pb->data,equal))
		{
		    dellist(LA,i) ;
		    i--;
		}

		pb=pb->next ;
	}
}
//转置
void transposition(link &L)
{
	  link p1,p2;
	  p1=L->next;
	  p2=NULL;
	  while(p1)
	 {
		L->next=p1->next;
		p1->next=p2;
		p2=p1;
		p1=L->next;
	 }
	 L->next=p2;
}

  

posted @ 2018-02-06 19:42  ~欢  阅读(310)  评论(0)    收藏  举报