数据结构-单链表基本操作的实现

  • CreateList_R(LinkList &L,int n):后插法创建单链表——时间复杂度O(n)
  • GetElem(LinkList L,int i,ElemType &e):单链表的取值——时间复杂度O(n)
  • LocateElem(LinkList L,ElemType e) :单链表的按值查找——时间复杂度O(n)
  • ListInsert(LinkList &L,int i,ElemType e):单链表的插入——时间复杂度O(n)
  • ListDelete(LinkList &L,int i):单链表的删除——时间复杂度O(n)
  • ListPrior(LinkList L,ElemType e,ElemType *pre):查找单链表中某个元素的前驱——时间复杂度O(n)
  • ListNext(LinkList L,ElemType e,ElemType *next):查找单链表中某个元素的后继——时间复杂度O(n)

完整的实现代码(包括算法步骤和代码注释):

//-------------数据结构-单链表基本操作的实现------------//
#include 
#include 
#define OK 1
#define ERROR 0
using namespace std;
typedef int Status;
//定义单链表的结构类型
typedef int ElemType;
//------单链表的存储结构-----// 
typedef struct LNode
{
	ElemType data;	     //结点的数据域
	struct LNode *next;	//结点的指针域,指向下一个指针 
 }LNode,*LinkList;      // LNode是结点,LinkList是链表,LinkList为指向结构体LNode的指针类型 

//------单链表的初始化-----//
  //【算法步骤】//
	//1.生成新结点作为头结点,用头指针L指向头结点。
	//2.头结点的指针域置空。
Status InitList(LinkList &L)
{
	//构造一个空的单链表L
	L=new LNode;      //生成新结点作为头结点,用头指针L指向头结点  或L=(LinkList)malloc(sizeof(LNode))
	L->next=NULL;     //头结点的指针域置空
	return OK; 
 } 
 
//------后插法创建单链表-----//
  //【算法步骤】//
	//1.创建一个只有头结点的空链表。
	//2.尾指针r初始化,指向头结点。 
	//3.根据创建链表包括的元素个数n,循环n次执行以下操作:
	   //生成一个新结点*P; 
	   //输入元素值赋给新结点*p的数据域;
	   //将新结点*p插入到尾结点*r之后;
	   //尾指针r指向新的尾结点*p。 
void CreateList_R(LinkList &L,int n)
{
	//正位序输入n个元素的值,建立带表头结点的单链表L
	L=new LNode;      //或L=(LinkList)malloc(sizeof(LNode))
	L->next=NULL;    //先建立一个带头结点的空链表 	
	LinkList r=L;             //尾指针r指向头结点 
	for(int i=0;i>p->data;  //输入元素值赋给新结点*p的数据域
		p->next=NULL;
		r->next=p;    //将新结点*p插入到尾结点*r之后 
		r=p;          //r指向新的尾结点*p 
	 }
 }

//-------------单链表的取值------------//
Status GetElem(LinkList L,int i,ElemType &e)
{
	//在带头结点的单链表L中根据序号i获取元素的值,用e返回L中第i个数据元素的值
	LinkList p=L->next;	   //初始化,p指向首元结点 
	int j=1; 			   //计数器初值赋为1
	while(p && jnext;		  //指向下一个结点
		++j;	          //计数器j相应加1 
	 } 
	if(!p||j>i) return ERROR;  //i值不合法i>n或i<=0
	e=p->data;				   //取第i个结点的数据域 
	return OK; 
 } 

//------单链表的按值查找-----//
  //【算法步骤】// 
	//1.用指针P指向首元结点。
	//2.从首元结点开始依次顺着链域next向下查找,只要指向当前结点的指针p不为空,并且p所指向结点的数据域不等于给定值e,则循环执行以下操作:p指向下一个结点。
	//3.返回p。若查找成功,p此时即为结点的地址值,若查找失败,p的值即为NULL。
bool LocateElem(LinkList L,ElemType e)
{
	//在带头结点的单链表L中查找值为e的元素
	LinkList p=L->next;       //初始化,p指向首元结点
	while(p && p->data!=e)   //顺着链域向后扫描,直到p为空或p所指结点的数据域等于e 
		p=p->next;   //p指向下一个结点 
	return p;		 //查找成功返回值为e的结点地址p,查找失败p为NULL 
 } 

//------单链表的插入-----//
  //【算法步骤】//
  //将值为e的新结点插入到表的第i个结点的位置上,即插入到结点ai-1与ai之间,具体插入过程如图所示,步骤如下: 
	//1.查找结点ai-1并由指针p指向该结点。
	//2.生成一个新结点*s。 
	//3.将新结点*s的数据域置为e。 
	//4.将新结点*s的指针域指向结点ai。
	//5.将结点*p的指针域指向新结点*s。
Status ListInsert(LinkList &L,int i,ElemType e)
{
	//在带头结点的单链表L中第i个位置插入值为e的新结点 
	LinkList p=L;
	int j=0;
	while(p && (jnext;   //查找第i-1个结点,p指向该结点 
		++j;
	}
	if(!p||j>i-1) return ERROR;  //i>n+1或者i<1
	LinkList s=new LNode;    //生成新结点*s 
	s->data=e;		//将结点*s的数据域置为e 
	s->next=p->next;//将结点*s的指针域指向结点ai 
	p->next=s;		//将结点*p的指针域指向结点*s 
	return OK; 	 
 } 

//------单链表的删除-----//
  //【算法步骤】//
  //将删除单链表的第i个结点ai,具体插入过程如图所示,步骤如下: 
	//1.查找结点ai-1并由指针p指向该结点。
	//2.临时保存待删除结点ai的地址在q中,以备释放。 
	//3.结点*p的指针域指向ai的直接后继结点。 
	//4.释放结点ai的空间。 
Status ListDelete(LinkList &L,int i)
{
	//在待头结点的单链表L中,删除第i个元素
	LinkList p=L;
	int j=0;
	while((p->next)&&(jnext;
		++j;
	 }
	 if(!(p->next)||(j>i-1)) return ERROR;  //当i>n或i<1时,删除位置不合理
	 LinkList q=p->next;       //临时保存被删结点的地址以备释放 
	 p->next=q->next;		   //改变删除结点前驱结点的指针域 
	 delete q;                 //释放删除结点的空间 
	 return OK; 
 } 

//-------------查找单链表中某个元素的前驱------------//
Status ListPrior(LinkList L,ElemType e,ElemType *pre)
{
	LinkList q=L->next;      //初始化,q指向首元结点
	if(!q) return ERROR;	//若链表为空
	LinkList p=q->next;	    //p指向第二个结点 
	while(p)
	{
		if(p->data==e)
		{
			*pre=q->data;
			return OK;
		}
		else
		{
			q=p;
			p=p->next;
		}
	 } 
	return ERROR;
}

//-------------查找单链表中某个元素的后继------------//
Status ListNext(LinkList L,ElemType e,ElemType *next)
{
	LinkList q=L->next;      //初始化,q指向首元结点
	if(!q) return ERROR;	//若链表为空
	LinkList p=q->next;	    //p指向第二个结点 
	while(p)
	{
		if(q->data==e)
		{
			*next=p->data;
			return OK;
		}
		else
		{
			q=p;
			p=p->next;
		}
	 } 
	return ERROR;
}

//------打印单链表函数-----//  
void PrintList(LinkList L)
{	
	printf("当前单链表中所有元素为:"); 
	LinkList p=L->next;
	if(p==NULL) return;
	else
	{
		while(p!=NULL)
		{	
			if(p->next==NULL)
			{
				printf("%d",p->data);
			}
			else
			{
				printf("%d->",p->data);
			}
			p=p->next;
		}	
	}
	printf("\n");
} 

//------创建单链表函数------//
void CreateList(LinkList &L) 
{
	int n;
	printf("请输入要创建的单链表的长度:");
	scanf("%d",&n);
	printf("请输入依次输入%d个数(空格隔开):",n);
	CreateList_R(L,n);
	printf("单链表创建成功!\n");
	PrintList(L);
}

//------单链表取值函数------//
void GetList(LinkList &L)
{
	int i,e;
	printf("请输入要取的数据元素的序号为:");
	scanf("%d",&i);
	bool flag=GetElem(L,i,e);
	if(flag)
	{
		printf("单链表中序号%d对应的数据元素%d取值成功!\n",i,e);
		PrintList(L);	
	}
	else
	{
		printf("单链表中序号%d对应的数据元素%d取值失败!\n",i,e);
	}	
 } 

//------单链表查找函数------//
void SearchList(LinkList &L)
{
	int e;
	printf("请输入要查找的数据元素为:");
	scanf("%d",&e);
	bool flag=LocateElem(L,e);
	if(flag)
	{
		printf("单链表中元素%d查找成功!\n",e);
		PrintList(L);	
	}
	else
	{
		printf("单链表中元素%d查找失败!\n",e);
	}	
 } 

//------单链表插入函数------//
void InsertList(LinkList &L)
{
	int i,e;
	printf("请输入要插入的位置:");
	scanf("%d",&i);
	printf("请输入要在第%d个位置插入的数据元素:",i);
	scanf("%d",&e); 
	bool flag=ListInsert(L,i,e);
	if(flag)
	{
		printf("元素%d插入单链表成功!\n", e);
		PrintList(L);	
	}
	else
	{
		printf("元素%d插入单链表失败!\n",e);
	}	
 } 

//------单链表删除函数------//
void DeleteList(LinkList &L)
{
	int i;
	printf("请输入要删除的位置:");
	scanf("%d",&i);
	bool flag=ListDelete(L,i);
	if(flag)
	{
		printf("单链表中第%d个位置的元素删除成功!\n",i);
		PrintList(L);	
	}
	else
	{
		printf("单链表中第%d位置的元素删除失败!\n",i);
	}	
 } 

//------单链表查找前驱函数------//
void PriorList(LinkList &L)
{
	int e,pre; 
	printf("请输入要查找前驱的数据元素为:");
	scanf("%d",&e);
	int flag=ListPrior(L,e,&pre);
	if(flag)
	{
		printf("单链表中数据元素%d的前驱为: %d\n",e,pre);
		printf("查找成功!\n"); 
		PrintList(L);	
	}
	else
	{
		printf("查找失败!\n"); 
	}	
 }  

//------单链表查找后继函数------//
void NextList(LinkList &L)
{
	int e,next; 
	printf("请输入要查找前驱的数据后继为:");
	scanf("%d",&e);
	int flag=ListNext(L,e,&next);
	if(flag)
	{
		printf("单链表中数据元素%d的后继为: %d\n",e,next);
		printf("查找成功!\n"); 
		PrintList(L);	
	}
	else
	{
		printf("查找失败!\n"); 
	}	
 } 

//菜单
void Menu()
{
	printf("\n|*|--------  1.创建单链表L中的数据元素  ----------|*|\n");
	printf("|*|----------  2.在单链表L中插入数据元素  ----------|*|\n");
	printf("|*|----------  3.在单链表L中删除数据元素  ----------|*|\n");
	printf("|*|----------  4.查找单链表L中的数据元素  ----------|*|\n");
	printf("|*|----------  5.取值单链表L中的数据元素  ----------|*|\n");
	printf("|*|----------  6.打印单链表L中的数据元素  ----------|*|\n");
	printf("|*|----------  7.查找单链表中某个元素的前驱  ----------|*|\n");
	printf("|*|----------  8.查找单链表L中某个元素的后继  ----------|*|\n");
	printf("|*|----------  9.退出程序  ----------|*|\n");	
 }  
//------主函数-----//
int main()
{	
	int choice;
	LinkList L; 
	InitList(L);
	while(true)
	{
		Menu();
		printf("请输入菜单序号:");
		scanf("%d",&choice);
		switch(choice)
		{
			case 1:CreateList(L); break;
			case 2:InsertList(L); break;
			case 3:DeleteList(L); break;
			case 4:SearchList(L); break;
			case 5:GetList(L); break;
			case 6:PrintList(L); break;
			case 7:PriorList(L); break;
			case 8:NextList(L); break;
		}
		if(choice==9) break; 	
	} 
 } 

运行结果:

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:1
请输入要创建的单链表的长度:3
请输入依次输入3个数(空格隔开):1 2 3
单链表创建成功!
当前单链表中所有元素为:1->2->3

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:2
请输入要插入的位置:2
请输入要在第2个位置插入的数据元素:4
元素4插入单链表成功!
当前单链表中所有元素为:1->4->2->3

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:3
请输入要删除的位置:4
单链表中第4个位置的元素删除成功!
当前单链表中所有元素为:1->4->2

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:4
请输入要查找的数据元素为:1
单链表中元素1查找成功!
当前单链表中所有元素为:1->4->2

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:5
请输入要取的数据元素的序号为:2
单链表中序号2对应的数据元素4取值成功!
当前单链表中所有元素为:1->4->2

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:6
当前单链表中所有元素为:1->4->2

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:7
请输入要查找前驱的数据元素为:4
单链表中数据元素4的前驱为: 1
查找成功!
当前单链表中所有元素为:1->4->2

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:8
请输入要查找前驱的数据后继为:4
单链表中数据元素4的后继为: 2
查找成功!
当前单链表中所有元素为:1->4->2

|*|--------  1.创建单链表L中的数据元素  ----------|*|
|*|----------  2.在单链表L中插入数据元素  ----------|*|
|*|----------  3.在单链表L中删除数据元素  ----------|*|
|*|----------  4.查找单链表L中的数据元素  ----------|*|
|*|----------  5.取值单链表L中的数据元素  ----------|*|
|*|----------  6.打印单链表L中的数据元素  ----------|*|
|*|----------  7.查找单链表中某个元素的前驱  ----------|*|
|*|----------  8.查找单链表L中某个元素的后继  ----------|*|
|*|----------  9.退出程序  ----------|*|
请输入菜单序号:9

--------------------------------
Process exited after 72.32 seconds with return value 0
请按任意键继续. . .

你可能感兴趣的:(数据结构,考研,c语言,数据结构,算法,链表)