C_线性表(ADT)-顺序表的表示和实现

顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存储就称之为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。(解释和图片来自百度百科)


将表中元素一个接一个的存入一组连续的存储单元中,这种存储结构顺序结构




 基本操作的实现:单个顺序表的构造,判空,插入,删除,排序,清空,销毁,返回前驱以及后继

线性表的定义:

typedef struct{
	ElemType *elem;
	int length;
	int listsize;
}List;

线性表基本操作:

1.InitList(&L)
/*操作结果:构造一个空的线性表*/


2.DestroyList(&L)
/*初始条件:线性表L已存在*/
/*操作结果:销毁线性表L*/


3.ClearList(&L)
/*初始条件:线性表L已存在*/
/*操作结果:将L重置为空表*/


4.ListEmpty(L)
/*初始条件:线性表L已存在*/
/*操作结果:若L为空表,则返回TRUE,否则返回FALSE*/

5.ListLength(L)
/*初始条件:线性表L已存在*/
/*操作结果:返回L中数据元素个数*/

6.GetElem(L,i,&e)
/*初始条件:线性表L已存在,1≤i≤LIST_SIZE*/
/*操作结果:用e返回L中第i个数据元素的值*/

7.LocatElem(L,e,compare())
/*初始条件:线性表L已存在,compaer()是数据元素判断函数*/
/*操作结果:返回L中第1个与e满足关系compaer()的数据元素的位序。若这样的数据元素不存在,则返回0*/

8.PriorElem(L,cur_e,&pre_e)
/*初始条件:线性表L已存在*/
/*操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义*/
  
9.NextElem(L,cur_e,&next_e)
/*初始条件:线性表L已存在*/
/*操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后续,否则操作失败,next_e无定义*/

10.ListInsert(&L,i,e)
/*初始条件:线性表L已存在*/
/*操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1*/

11.ListDelete(&L,i,&e)
/*初始条件:线性表L已存在*/
/*操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1*/

顺序表函数的实现===================

构造一个空的线性表L:

Status InitList(List &L)
{
	L.elem=(ElemType*)malloc(LIST_SIZE*sizeof(ElemType));
	//if(!L.elem) exit(OVERFLOW);  如果内存申请失败程序异常退出
	L.length=0;
	L.listsize=LIST_SIZE;
	printf("成功构造一个空的线性表\n");
	return OK; 
}


摧毁线性表L:

Status DestoryList(List &L)
{
	if(L.elem) free(L.elem);//释放内存空间
	L.elem=NULL;
	L.length=0;
	L.listsize=0; 
	return OK; 
}

  关于线性表的清空与销毁:顺序表是由指针elem和变量length两部分组成。清空当然只需令length=0就行了。length是变化的,插入和删除会相应的增加和减少,并且会对length进行边界判断;而且其他操作也会和length作比较的,若length=0了根本就无法访问顺序表中的元素了,销毁的话顺序表首地址指针释放,顺序表就不存在了!

判断线性表是否是空表:

Status ListEmpty(List L)
{
	if(!L.listsize){
		 return TRUE;
	}else{
		return FALSE;
	}
}

返回线性表中的个数:

Status ListLength(List L)
{
	return L.length;	
}

将L重置为空表:

 

Status ClearList(List &L)
{
	L.length=0;
	return L.length; 
}

用e返回L中第i个数据元素的值:

Status GetElem(List L,int i,ElemType &e)
{
    	e=L.elem[i-1];
    	return e;
}

前驱结点的寻找:

Status PriorElem(List L,int cur_e,int &pre_e)
{
   	for(int i=1;i<L.length;i++)
   	{
	   if(L.elem[i]==cur_e)
	   {
   		pre_e=L.elem[i-1];
		   return pre_e; 
		}   	
    }
}

后续结点的寻找:

Status NextElem(List L,int cur_e,int &next_e)
{
	for(int i=1;i<L.length;i++)
	{
		if(L.elem[i]==cur_e)
		{
			next_e=L.elem[i+1];
		}
		return next_e;
	}
}

在L中第i个位置之前插入新的数据元素e,L的长度加1:

Status ListInsert(List &L,int i,ElemType e)
{
    ElemType *q,*p,*newbase;
	if (i<1||i>L.length+1) return ERROR;
	if (L.length>=L.listsize){
		 newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
		   if (!newbase) return(OVERFLOW);
		   L.elem=newbase;
		    L.listsize+=LISTINCREMENT;
	}
	 q=&(L.elem[i-1]);
	 for(p=&(L.elem[L.length-1]);p>=q;--p)   *(p+1)=*p;
	 *q=e;
     ++L.length;
     return OK;
		
}

删除L的第i个数据元素,并用e返回其值,L的长度减1:

Status ListDelete(List &L,int i,ElemType &e)
{
	ElemType *p,*q;
  	if ((i<1)||(i>L.length)) return ERROR;
  	p=&(L.elem[i-1]);
  	e= *p;
  	q=(L.elem+L.length-1);
 	 for (++p;p<=q;++p) *(p-1)=*p;
  	--L.length;
  	return OK;
}


嗯下面就是在VC上面进行的测试:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LIST_SIZE 100
#define LISTINCREMENT 10
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
typedef int ElemType;
typedef int Status;
typedef struct{
	ElemType *elem;
	int length;
	int listsize;
}List;

/*操作结果:构造一个空的线性表*/
Status InitList(List &L)
{
	L.elem=(ElemType*)malloc(LIST_SIZE*sizeof(ElemType));
	//if(!L.elem) exit(OVERFLOW);  如果内存申请失败程序异常退出
	L.length=0;
	L.listsize=LIST_SIZE;
	printf("成功构造一个空的线性表\n");
	return OK; 
}

/*初始条件:线性表L已存在*/
/*操作结果:销毁线性表L*/
Status DestoryList(List &L)
{
	if(L.elem) free(L.elem);//释放内存空间
	L.elem=NULL;
	L.length=0;
	L.listsize=0; 
	return OK; 
}

/*初始条件:线性表L已存在*/
/*操作结果:将L重置为空表*/
Status ClearList(List &L)
{
	L.length=0;
	return L.length; 
}

/*初始条件:线性表L已存在*/
/*操作结果:若L为空表,则返回TRUE,否则返回FALSE*/
Status ListEmpty(List L)
{
	if(!L.listsize){
		 return TRUE;
	}else{
		return FALSE;
	}
}

/*初始条件:线性表L已存在*/
/*操作结果:返回L中数据元素个数*/
Status ListLength(List L)
{
	return L.length;	
}

/*初始条件:线性表L已存在,1≤i≤LIST_SIZE*/
/*操作结果:用e返回L中第i个数据元素的值*/
Status GetElem(List L,int i,ElemType &e)
{
    	e=L.elem[i-1];
    	return e;
}

/*初始条件:线性表L已存在,compaer()是数据元素判断函数*/
/*操作结果:返回L中第1个与e满足关系compaer()的数据元素的位序。若这样的数据元素不存在,则返回0*/
/*Status LocatElem(L,e,compare())
{ 
	//参考GetElem(List L,int i,ElemType &e)
}*/

/*初始条件:线性表L已存在*/
/*操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义*/
Status PriorElem(List L,int cur_e,int &pre_e)
{
   	for(int i=1;i<L.length;i++)
   	{
	   if(L.elem[i]==cur_e)
	   {
   		pre_e=L.elem[i-1];
		   return pre_e; 
		}   	
    }
}

/*初始条件:线性表L已存在*/
/*操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后续,否则操作失败,next_e无定义*/
Status NextElem(List L,int cur_e,int &next_e)
{
	for(int i=1;i<L.length;i++)
	{
		if(L.elem[i]==cur_e)
		{
			next_e=L.elem[i+1];
		}
		return next_e;
	}
}

/*初始条件:线性表L已存在*/
/*操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1*/
Status ListInsert(List &L,int i,ElemType e)
{
    ElemType *q,*p,*newbase;
	if (i<1||i>L.length+1) return ERROR;
	if (L.length>=L.listsize){
		 newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
		   if (!newbase) return(OVERFLOW);
		   L.elem=newbase;
		    L.listsize+=LISTINCREMENT;
	}
	 q=&(L.elem[i-1]);
	 for(p=&(L.elem[L.length-1]);p>=q;--p)   *(p+1)=*p;
	 *q=e;
     ++L.length;
     return OK;
		
}
/*初始条件:线性表L已存在*/
/*操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1*/
Status ListDelete(List &L,int i,ElemType &e)
{
	ElemType *p,*q;
  	if ((i<1)||(i>L.length)) return ERROR;
  	p=&(L.elem[i-1]);
  	e= *p;
  	q=(L.elem+L.length-1);
 	 for (++p;p<=q;++p) *(p-1)=*p;
  	--L.length;
  	return OK;
}
/*遍历顺序表并且输出元素*/
Status traverselist(List L)
{
	for(int i=0;i<L.length;i++)
	{
		if(i==0)
	 		printf("%d",L.elem[i]);
		else
			printf(" %d",L.elem[i]);
	}
	printf("\n");
	return OK;
}

/*小到大对顺序表进行排序*/
Status sortlist(List &L)
{
	for(int i=0;i<L.length-1;i++)
		for(int j=0;j<=L.length-i-1;j++)
		{
			if(L.elem[j]>L.elem[j+1])
			{
				int temp=L.elem[j];
				L.elem[j]=L.elem[j+1];
				L.elem[j+1]=temp;
			}
		} 
}

int main()
{
	List L;
	ElemType e1,e2;
	Status k;
	int i,a,b,c,d,e,n,j;
	printf("******************\n");
	printf("请选择您所要进行的操作\n");
	printf("1.排序\n2.判断顺序表是否为空\n3.顺序表中元素的个数\n");
	printf("4.寻找表中第i个元素\n5.寻找指定值及前驱后续\n6.插入\n7.删除\n");
	printf("8遍历输出\n9.清空\n10.销毁\n0.退出\n");
	printf("******************\n\n");
	//初始化线性表 
	InitList(L);
	printf("初始化表元素个数:");
 	scanf("%d",&n);//往线性表插入数据
 	 printf("输入所插入的数据:");
  	for(i=1;i<=n;i++)
	  	{
 	 	 	scanf("%d",&a);
  	     	ListInsert(L,i,a);
  	 	 }
 	printf("请进行下一步的操作:"); 
	while(scanf("%d",&c)&&c!=0)
	{
		if(c==1){
			sortlist(L);
			printf("线性表成功由小到大进行排序\n"); 
		}else if(c==2){
			if(ListEmpty(L))  printf("线性表是空表\n");
				else            printf("线性表不是空表\n"); 
		}else if(c==3){
	        printf("线性表的元素个数为%d\n",ListLength(L));
		}else if(c==4){
			printf("输入要查找表中第i个值:");
			scanf("%d",&i);  
			if(i<1||i>ListLength(L)){
    			printf("输入数值错误\n"); 
				break;
	 		}else{
			 		printf("表中第%d个元素对应的数值为%d\n",i,GetElem(L,i,e));
				}
		}else if(c==5){
			printf("输入要查找表中第i个值前驱和后续:");
			scanf("%d",&i); 
			if(i<=1||i>=ListLength(L)) {
				printf("输入数值错误\n"); 
				break;
			}else{
				printf("表中第%d个元素对应的前驱数值为%d\n",i,PriorElem(L,i,e));
				printf("表中第%d个元素对应的后续数值为%d\n",i,NextElem(L,i,e));
			}
		}else if(c==6){
			 printf("请输入您所想插入的位置以及值:");
			 scanf("%d%d",&e,&d); 
			 ListInsert(L,e,d);
			 if(ListInsert) printf("插入成功!\n"); 
			 	else		printf("插入失败!\n");	
		}else if(c==7){
				printf("输入删除第几个数:");
				scanf("%d",&c);
					if(c<1||c>L.length)
  				printf("输入错误!!!元素不存在\n");
  					else
    			k=ListDelete(L,c,e2); // 删除第c个数据
		       printf("删除第%d个元素成功,其值为%d\n",c,e2); 
		}else if(c==8){
			traverselist(L);
		}else if(c==9){
			ClearList(L);
			if(ClearList(L)==0) printf("清空成功!\n");
				else            printf("清空失败!\n");
		}else if(c==10){
			DestoryList(L);
			if(DestoryList(L)==OK)  printf("销毁成功!\n");
				else				printf("销毁失败!\n"); 
		}
		printf("请进行下一步的操作:"); 
	}
	printf("成功退出!\n"); 
	return 0;
}


评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值