C语言单链表和顺序表的基本操作

笔者当初学的时候不熟悉结构,很容易出错

因为本人不是专学C,所以有些知识不是很懂

顺序表

typedef struct{
ElemType *elem; //存储空间的基地址
int length; //当前长度
}SqList;

  1. 顺序表结构比较简单,只需要在一个结构体中,加入一个数组,和一个表示数组长度的数
  2. *elem 的意思是指向一个地址==指针
  3. 所有的操作都基于结构体中的数组和长度

顺序表操作

#include
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;	   //Status 是函数返回值类型,其值是函数结果状态代码。
typedef int ElemType;  //ElemType 为可定义的数据类型,此设为int类型

#define MAXSIZE 100	  //顺序表可能达到的最大长度

typedef struct{
	ElemType *elem;	  //存储空间的基地址
	int length;		  //当前长度
}SqList;

Status InitList_Sq(SqList &L){ //功能1--算法2.1 顺序表的初始化
	//构造一个空的顺序表L
	L.elem=new ElemType[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间
	if(!L.elem)  exit(OVERFLOW);  //存储分配失败
	L.length=0;	    	//空表长度为0
	return OK;
}

Status ListInsert_Sq(SqList &L,int i,ElemType e){ //功能3--算法2.3 顺序表的插入
	//在顺序表L中第i个位置之前插入新的元素e
	//i值的合法范围是1<=i<=L.length+1
	if(i<1 || i>L.length+1)	return ERROR;		//i值不合法
	if(L.length==MAXSIZE)	return ERROR;		//当前存储空间已满
	for(int j=L.length-1;j>=i-1;j--)
		L.elem[j+1]=L.elem[j];					//插入位置及之后的元素后移
	L.elem[i-1]=e;								//将新元素e放入第i个位置
	++L.length;									//表长增1
	return OK;
}

void display(SqList L){ //功能4--依次显示顺序表L中的全部数据元素
    if(L.length==0) {cout<<"空表"<<endl; return ;}  //空白,直接返回
	cout<<"表中元素依次为:";
	for(int i=0;i<L.length;i++)
		cout<<L.elem[i]<<" ";
	cout<<",共有"<<L.length<<"个元素。"<<endl;
}
int LocateElem_Sq(SqList L,ElemType e) { //功能5. 顺序表的查找
	
	if(L.length==0) {cout<<"空表"<<endl; return ERROR;}
	for (int i = 0; i < L.length; i++)
		if (L.elem[i] == e)
			return i + 1;//查找成功,返回序号i+1
	return 0;//查找失败,返回0
}
Status ListDelete_Sq(SqList &L, int i) { //功能6. 顺序表的删除
	//在顺序表L中删除第i个元素,并用e返回其值
	//i值的合法范围是1<=i<=L.length
	if(L.length==0) {cout<<"空表"<<endl; return ERROR;}  //空白,直接返回
	if ((i < 1) || (i > L.length))
		return ERROR; //i值不合法
	for (int j = i; j <= L.length; j++)
		L.elem[j - 1] = L.elem[j]; //被删除元素之后的元素前移
	--L.length; //表长减1
	return OK;
}

Status GetmaxPlaceAndItem(SqList L,ElemType &a,ElemType &b) {//功能7. 顺序表的取值及位置
	if(L.length==0) {cout<<"空表"<<endl; return ERROR;}  //空白,直接返回
	int i;
    b=L.elem[0];
	a=1;

	for(i=1;i<=L.length;i++)
	{
		if(b<=L.elem[i-1])
		{
			b=L.elem[i-1];
			a=i;
		}
	}

	return OK;
}
Status ListDelete_Sq(SqList &L) {
	//功能8. 顺序表最小的删除

	//i值的合法范围是1<=i<=L.length
	if(L.length==0) {cout<<"空表"<<endl; return ERROR;}  //空白,直接返回
	int e=L.elem[0];
	int x=0;
	for (int i =1; i <=L.length; i++)
	{
		if(e>=L.elem[i-1])
		e=L.elem[i- 1];
		x=i-1;
		} 
	for (int j = x; j <= L.length; j++)
		L.elem[j - 1] = L.elem[j];//被删除元素之后的元素前移

	--L.length;//表长减1
	return OK;
}
Status reverse(SqList &L){//

	int temp;//
	if(L.length==0) {cout<<"空表"<<endl; return ERROR;}//空白,直接返回
	for(int i=0;i<L.length/2;i++){//在中间对半进行交换
	 temp=L.elem[i];
	 L.elem[i]=L.elem[L.length-i-1];
	 L.elem[L.length-i-1]=temp;
}
	return OK;
}
Status deleteItem(SqList &L,int item){
		if(L.length==0) {cout<<"空表"<<endl; return ERROR;}//空白,直接返回
		int count=0;
	for (int i =1; i <=L.length; i++)
	{
		cout<<"大";
		if(item==L.elem[i-1]){
			
			cout<<"相等";
			
			count++;//计算长度

			for(int j =i; j <=L.length+1; j++){

			L.elem[j-1]=L.elem[j];
			}
			i--;//i往后退一个
				L.length--;//减少长度

		}
	}


	
	return OK;
}
int main()
{
	SqList L;
	int i,count,temp=0,choose;
	ElemType x;
	choose=-1;  count=0; //count专门用于控制菜单显示,不要做其他用途
	while(choose!=0)
	{
		if(count%5==0)
		{	cout<<"**********************************************************************\n";
			cout<<"1. 建立空表                              2. 在表中输入指定个数元素\n";
			cout<<"3. 在第i个元素的前面插入一个元素         4. 逐个显示表中元素\n";
			cout<<"5. 依值查找                              6. 删除表中第i个元素\n";
			cout<<"7. 返回表中值最大元素及其在表中位置      8. 删除线性表中值最小的数据元素\n";
			cout<<"9. 逆置线性表                            10.删除表中所有值为item的元素\n";
			cout<<"11.重置为空表                            0. 退出\n";
			cout<<"**********************************************************************\n";
		}
		count++;
		cout<<"请选择:";
		cin>>choose;
		switch(choose)
		{
		case 1:
			if(InitList_Sq(L))						//创建顺序表
				cout<<"成功建立顺序表\n\n";
			else
				cout<<"顺序表建立失败\n\n";
			break;
		case 2:										
			cout<<"请输入一个数,代表元素的个数:";
			cin>>L.length;
			cout<<"请输入"<<L.length<<"个元素的数据(以空格隔开,按回车结束):";
			for(i=0;i<L.length;i++)
				cin>>L.elem[i];
			display(L); cout<<endl;
			break;
		case 3:	//顺序表的插入
			cout<<"请输入两个数,分别代表插入的位置和插入数值(用空格间隔,最后回车):";
			cin>>i>>x;				//输入i和x,i代表插入的位置,x代表插入的数值
			cout<<"插入之前--";   display(L);
			if(ListInsert_Sq(L,i,x))
			{
				cout<<"插入成功--";  display(L);  cout<<endl;
			}
			else
			{
				cout<<"插入失败--";  display(L);  cout<<endl;
			}
			break;
		case 4:	//顺序表的输出
			display(L);  cout<<endl;
			break;
		case 5:	//顺序表的依值查找
				cout<<"请输入一个数查找";
			cin>>x;				//输入x进行查找
			cout<<"执行之前--";   display(L);
			i=LocateElem_Sq(L,x);
			if(i){
			cout<<"查找成功--序位为:"<<i;   cout<<endl;
			}else{
				cout<<"查无";   cout<<endl;
			}
			cout<<"执行之后--"; display(L);
			break;
	   case 6:	//顺序表的删除
				cout<<"请输入一个序号进行删除";
			cin>>x;				//输入x位置进行删除
		cout<<"执行之前--";   display(L);
		i=ListDelete_Sq(L,x);
			if(i){
			cout<<"删除成功--序位为:"<<i;   cout<<endl;
			}else{
				cout<<"删除失败--";   cout<<endl;
			}
		cout<<"执行之后--";   display(L);
			break;
		case 7:	//顺序表的返回最大数及其位置
			cout<<"顺序表的返回最大数及其位置"<<endl;
		cout<<"执行之前--";   display(L);
			int a,b;
			if(GetmaxPlaceAndItem(L,b,a)){
			cout<<"成功返回最大数:"<<a<<"其位置:"<<b;	
			}else{
			cout<<"返回失败";
			}
		cout<<"执行之后--";   display(L);
			cout<<endl;
			break;
		case 8:	//顺序表删除最小数
			cout<<"顺序表删除最小数"<<endl;	
		cout<<"执行之前--";   display(L);
			if(ListDelete_Sq(L)){
			cout<<"顺序表的删除最小数成功";	
			}else{
			cout<<"返回失败";
			}
	cout<<"执行之后--";   display(L);
			cout<<endl;
			break;
		case 9:	//顺序表倒序
			cout<<"顺序表倒序"<<endl;	
			cout<<"执行之前--";   display(L);
			if(reverse(L)){
			cout<<"顺序表倒序成功";	
			}else{
			cout<<"返回失败";
			}
		cout<<"执行之后--";   display(L);
			cout<<endl;
			break;
	case 10:	//顺序表删除输入相同的数
			cout<<"顺序表删除输入的相同数:"<<endl;	
		cin>>x;
		cout<<"执行之前--";   display(L);

		if(deleteItem(L,x)){
			cout<<"删除成功"<<endl;	
		}else{
			cout<<"删除失败"<<endl;	
		}
		cout<<"执行之后--";   display(L);
			cout<<endl;
			break;

		case 11: //重置为空表。
			L.length=0;  display(L);  cout<<endl;
			break;
		}
	}
	return 0;
}

单链表操作

typedef struct LNode
{
ElemType data; //结点的数据域
struct LNode *next; //结点的指针域
}LNode,*LinkList;
Status InitList_L(LinkList &L){ /
L=new LNode; //生成新结点作为头结点,用头指针L指向头结点
L->next=NULL; //头结点的指针域置空
return OK;
}

  1. 单链表结构是一个带有嵌套的结构体,一个指向另一个
  2. 结构体定义LNode,*LinkList有些不同,LNode是直接给一个空间,LinkList是给一个指针还需要自行给它空间需要用到malloc函数
#include
using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;		//Status 是函数返回值类型,其值是函数结果状态代码。
typedef int ElemType;	 //ElemType 为可定义的数据类型,此设为int类型

typedef struct LNode
{
	ElemType data;	//结点的数据域
	struct LNode *next;		//结点的指针域
}LNode,*LinkList;  //LinkList为指向结构体LNode的指针类型

Status InitList_L(LinkList &L){	//功能1---算法2.5 单链表的初始化
	//构造一个空的单链表L
	L=new LNode;	//生成新结点作为头结点,用头指针L指向头结点
	L->next=NULL;    //头结点的指针域置空
	return OK;
}

Status ListInsert_L(LinkList &L,int i,ElemType &e){ //功能3---算法2.8 单链表的插入
	//在带头结点的单链表L中第i个位置之前插入元素e
	int j;
	LinkList p,s;
	p=L;j=0;
	while(p && j<i-1){p=p->next;++j;} //寻找第i-1个结点
	if(!p||j>i-1)	return ERROR;	//i大于表长+1或者小于1
	s=new LNode;	//生成新结点s
	s->data=e;		//将结点s的数据域置为e
	s->next=p->next; //将结点s插入L中
	p->next=s;
	return OK;
}//ListInsert_L

void display(LinkList L){ //功能4--依次显示单链表L中的全部数据元素
	LinkList p=L->next; 
	if(!p) {cout<<"空表"<<endl; return;}  //空白,直接返回
	cout<<"表中元素依次为:";
	int i=0;
	while(p)
	{
       i++;
	   cout<<p->data<<" ";
	   p=p->next;
	}
	cout<<",共有"<<i<<"个元素。"<<endl;
}

void CreateList_F(LinkList &L,int n){ //算法2.10 前插法创建单链表
	//逆位序输入n个元素的值,建立到头结点的单链表L
	LinkList p;
	L=new LNode;
	L->next=NULL; 	//先建立一个带头结点的空链表
	cout<<"请输入 "<<n<<" 个数(以空格隔开,按回车结束):";
	for(int i=n;i>0;--i){
		p=new LNode; 	//生成新结点
		cin>>p->data;   //输入元素值
		p->next=L->next;L->next=p;  //插入到表头
	}
}//CreateList_F

void CreateList_L(LinkList &L,int n){ //算法2.11 后插法创建单链表
	//正位序输入n个元素的值,建立到头结点的单链表L
	L=new LNode; //先建立一个带头结点的空链表
	LinkList r=L;          //尾指针r总是指向链表当前最末尾结点
	cout<<"请输入 "<<n<<" 个数(用空格间隔,最后回车):";
	for(int i=0;i<n;i++){
		r->next=new LNode; 	//生成新结点
		r=r->next;        	//r指向新的尾结点
		cin>>r->data;  	//输入元素值
	}
	r->next=NULL; 
}//CreateList_L

int GetElem(LinkList &L,int e,ElemType &a)//功能五:输入一个序位进行查找
{
	
	int j=0;
	LinkList p=L;
	p=p->next;//
	if(!p) {cout<<"空表"<<endl; return 0;}  //空白,直接返回
	while (p!=NULL)//循环遍历查找
	{
		j++;
		if(j==e)
		{
		 a=p->data;	
		return 1;
		}
		
		p=p->next;
	}
	return 0;//查无返回0

}
int GetElem(LinkList &L,ElemType &e)//功能六:输入一个数进行查找
{
	
	int j=0;
	LinkList p=L;//
	if(!p) {cout<<"空表"<<endl; return 0;}  //空白,直接返回
	while (p!=NULL)//循环遍历查找
	{
		j++;
		if(p->data==e)
		{
			
		return j;
		}
		
		p=p->next;
	}
	return 0;//查无返回0

}
int ListDelete(LinkList &L,int i,ElemType &e)//功能七:删除输入的序位节点
{
	int j=0;
	LinkList p=L,q;
	if(!p) {cout<<"空表"<<endl; return 0;}  //空白,直接返回
	while (j<i-1 && p!=NULL)
	{
		j++;
		p=p->next;
	}
	if (p==NULL)				/*未找到第i-1个结点*/
		return 0;
	else						/*找到第i-1个结点*p*/
	{
		q=p->next;              /*q指向要删除的结点*/
		if(q==NULL) return 0;   /*不存在第i个结点*/
        e=q->data;  
		p->next=q->next;		/*从单链表中删除*q结点*/
		free(q);				/*释放*q结点*/
		return 1;
	}
}
int GetMax(LinkList L,ElemType &e)//功能八:获得单链表中最大值
{
	LinkList p=L;
	if(!p) {cout<<"空表"<<endl; return 0;}  //空白,直接返回
	p=p->next;
	e=p->data;
	while(p!=NULL)
	{
		if(e<=p->data){
		e=p->data;
		}
		p=p->next;

	}
	return 1;
}
int Reverse(LinkList &L)//功能九:逆序单链表
{
	LinkList p,q,w; 
		w=q=p=L;
	int count=0;
	if(!p) {cout<<"空表"<<endl; return 0;}  //空白,直接返回
	p=p->next;
	int temp;
	while(p!=NULL)
	{
		count++;
		p=p->next;

	}

	
	for(int j=1;j<=count/2;j++){
		

	for(int t=0;t<j;t++)
	{
			
q=q->next;

	}
		for(int h=count;h>=j;h--)
	{
	
w=w->next;
	}
	temp=q->data;
	q->data=w->data;
	w->data=temp;
	q=w=L;
		
	}
	return 1;
	
}
int deleteitem(LinkList &L,int a){//功能十:删除输入相同的数

	LinkList q,p=L;
	
	if(!p) {cout<<"空表"<<endl; return 0;}  //空白,直接返回
	
	while(p!=NULL){
		
		    q=p;
			p=p->next;
			
			if(p->data==a){
			
                          /*q指向要删除的结点*/
               
		       q->next=p->next;		/*从单链表中删除*q结点*/
		      		
				
				return 1;
			}
			

	
	}return 0;
}
int main()
{
	int i,n,choose;
	ElemType x;
	LinkList L,p;
	choose=-1;  
	int count=0; //count专门用于控制菜单显示,不要做其他用途
	while(choose!=0)
	{
		if(count%5==0)
		{	cout<<"**********************************************************************\n";
			cout<<"  1. 建立空链表;                          2. 在表中输入指定个数的数据元素\n";
			cout<<"  3. 在第i个元素的前插入一个元素;         4. 逐个显示表中数据元素\n";
			cout<<"  5. 查找位序为i的元素,返回其值;         6. 依值查找,返回其位序\n";
			cout<<"  7. 删除表中第i个元素;                   8. 返回值最大的元素及其在表中位置\n";
			cout<<"  9. 就地逆置;                            10. 删除表中所有值为item的数据元素\n";
			cout<<"  0. 退出\n";
			cout<<"*******************************************************************************\n";
		}
		count++;
		cout<<"请选择:";
		cin>>choose;
		switch(choose)
		{
		case 1:	  //建立一个单链表
			if(InitList_L(L))
				cout<<"成功建立链表!\n\n";
			break;
		case 2:	 //功能2---使用后插法创建单链表
			cout<<"请输入一个数,代表元素的个数:";
			cin>>n;
			CreateList_L(L,n);
			cout<<"成功创建链表---"; display(L); cout<<endl;
			break;
		case 3:  //单链表的插入
			cout<<"请输入两个数,分别代表插入的位置和插入数值(用空格间隔,最后回车):";
			cin>>i>>x;				//输入i和x,i代表插入的位置,x代表插入的数值
			cout<<"插入之前--";   display(L);
			if(ListInsert_L(L,i,x))
			{
				cout<<"插入成功--";  display(L);  cout<<endl;
			}
			else
			{
				cout<<"插入失败--";  display(L);  cout<<endl;
			}
			break;
		case 4:	 //单链表的输出
			display(L);  cout<<endl;
			break;
		case 5:	 //依位序查找,返回查找的值
			cout<<"执行前"<<endl;
			display(L);
			cout<<"输入一个序位进行查找返回值"<<endl;

			cin>>x;
			int a;
			if(GetElem(L,x,a)){
			cout<<"查找成功!序位为"<<x<<"值为"<<a<<endl;
			}else{
				cout<<"查找失败"<<endl;

			}



			cout<<"执行后"<<endl;
			display(L);
			cout<<endl;

			break;

		case 6:	 //依值查找,返回查找值元素的序位
			cout<<"执行前"<<endl;
			display(L);
			cout<<"输入一个值进行查找返回序位"<<endl;

			cin>>x;
						
			if(GetElem(L,x)){
			cout<<"查找成功!序位为"<<GetElem(L,x)-1<<"值为"<<x<<endl;
			}else{
				cout<<"查找失败"<<endl;

			}



			cout<<"执行后"<<endl;
			display(L);
			cout<<endl;

			break;
		case 7:	 //删除指定位置节点
			cout<<"执行前"<<endl;
			display(L);
			cout<<"输入一个序位进行删除返回该值"<<endl;

			cin>>x;
			int b;
			if(ListDelete(L,x,b)){
			cout<<"删除成功!序位为"<<x<<"值为"<<b<<endl;
			}else{
				cout<<"删除失败"<<endl;

			}



			cout<<"执行后"<<endl;
			display(L);
			cout<<endl;

			break;
		case 8:	 //显示最大数
			cout<<"执行前"<<endl;
			display(L);
			int d;
			if(GetMax(L,d)){
			cout<<"显示成功,最大数:"<<d<<endl;
			}else{
				cout<<"显示失败"<<endl;


			}
			

			
			cout<<"执行后"<<endl;
			display(L);
			cout<<endl;

			break;
			break;



		case 9:	 //单链表逆序
			cout<<"执行前"<<endl;
			display(L);
		
			if(Reverse(L)){
			cout<<"逆序成功"<<endl;
			}else{
				cout<<"逆序失败"<<endl;


			}
			

			
			cout<<"执行后"<<endl;
			display(L);
			cout<<endl;

			break;
		case 10:	 //删除输入的数
			cout<<"执行前"<<endl;
			display(L);
				cout<<"输入一个数删除"<<endl;
				cin>>x;

		
			if(deleteitem(L,x)){
			cout<<"成功删除:"<<x<<endl;
			}else{
				cout<<"显示失败"<<endl;


			}
			

			
			cout<<"执行后"<<endl;
			display(L);
			cout<<endl;

			break;
		



		}
	}
	return 0;
}

你可能感兴趣的:(学校数据结构,C单链表顺序表)