数据结构循环链表基本操作实例演示

本文详细介绍了循环链表的基本操作,包括初始化、插入、删除、查找及遍历等,并通过具体示例代码进行了演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
#include<stdlib.h>   					//系统函数头文件 

/*链表存储结构的定义*/
typedef struct CLinkList		 
{
	int data;							
	struct CLinkList *next;
 } node;
 
 /*****************************************/
 /*操作                                   */ 
 /*****************************************/
 
 /*初始化循环链表*/
void ds_init(node **pNode)
{
	int item;
	node *temp;
	node *target;
	
	printf("输入节点的值,输入0完成初始化\n");
	
	while(1)
	{
		scanf("%d",&item);
		fflush(stdin);					//清除缓冲区 ,保证输入正常 
		
		if(item==0)
		 return;
		 
		 if((*pNode)==NULL)
		 {/*循环链表中只有一个节点*/ 
		 	*pNode=(node*)malloc(sizeof(struct CLinkList));
		 	if(!(*pNode))
		 		exit(0);							//无条件退出函数 
		 	(*pNode)->data=item;
		 	(*pNode)->next=*pNode;
		 }
		 else
		 {
		 	/*找到next指向第一个结点的结点*/ 
		 	for(target=(*pNode);target->next!=(*pNode);target=target->next)
		 	;                                   //将指针指向下一个对象,直到指向头结点 
		 	/*生成一个新的结点 */
			temp=(node *)malloc(sizeof(struct CLinkList));		//分配内存空间 
			 
			if(!temp)				//分配失败退出 
				exit(0);
				
			temp->data=item;					//将输入的值赋给temp 
			temp->next=*pNode;					//将新的数据元素的指针指向头结点 
			target->next=temp;					//原来的最后一个元素的指针指向新的元素 
		 }
	}
 } 
 /*插入结点*/
/*参数:链表的第一个结点,插入的位置*/
void ds_insert(node **pNode, int i)			//i为插入的元素的插入位置 
{
	node *temp;								//定义变量 
	node *target;
	node *p;
	int item;
	int j=1;
	
	printf("输入要插入结点的值:");			//给插入结点赋值 
	scanf("%d",&item);
	
	if(i==1)								 
	{
		//新插入的结点作为第一个结点
		temp=(node*)malloc(sizeof(struct CLinkList));//分配内存 
		
		if(!temp)					//失败退出 
			exit(0);
			
		temp->data=item;			//把插入的值赋给temp 
		
		/*寻找到最后一个节点*/
		for(target=(*pNode);target->next!=(*pNode);target=target->next)
		;
		
		temp->next=(*pNode);		//把temp的指针指向头结点 
		target->next=temp;			//把最后一个结点的指针指向temp,因为temp要变成第一个结点 
		*pNode=temp;				//完全替换,把头结点的位置让给temp 
	}
	else
	{
		target=*pNode;				//把target赋给头结点 
		
		for(;j<(i-1);++j)			//进行遍历,知道target为要插入元素的位置的前一个元素的位置 
		{
			target=target->next;
		}
		
		temp=(node *)malloc(sizeof(struct CLinkList));
		
		if(!temp)
			exit(0);
			
		temp->data=item;				//把插入的值赋给temp 
		p=target->next;					//利用中介p来装载要插入的位置的上个位置的指针 
		target->next=temp;				//把这个指针指向temp 
		temp->next=p;					//然后再调出p,完成衔接  temp 就有了前驱和后继 
	}
 } 
 
 /*删除节点*/ 
void ds_delete(node **pNode,int i)		//i为要删除的结点的位置 
{
	node *target;
	node *temp;
	int j=1;
	
	if(i==1)
	{
		//删除的是第一个结点
		/*找到最后的一个结点*/
		for(target=*pNode;target->next!=*pNode;target=target->next) 	
		;
		
		temp=*pNode;						//当删除的是第一个结点的时候,把temp代表头结点 
		*pNode=(*pNode)->next;				//头结点变为原来头结点指向的那个元素的指针,变为新的头结点 
		target->next=*pNode;				//最后一个结点的指针指向新的头结点 
		free(temp);							//释放原来的头结点,也相当于删除 
	}
	else
	{
		target=*pNode;						//target代表头结点 
		for(;j<i-1;++j)						//进行遍历,要target指向要删除位置的元素 
			target=target->next;		
		temp=target->next;					//temp承载要删除的元素 
		target->next=temp->next;			//把target的指针指向要删除的元素的指针,直接跳过被删除元素 
		free(temp);							//释放temp,相当于删除 
	}
}

/*返回结点所在位置*/
int ds_search(node *pNode,int elem)			//elem相当于要寻找的元素 
{
	node *target;			
	int i=1;
	
	for(target=pNode;target->data!=elem&&target->next!=pNode;++i) 
		target=target->next;			//让target当头结点,进行指向,当碰到元素elem时,停止,i记载位置 
	
	if(target->next==pNode)				//如果是头结点,返回0,否则,返回 i的值 
		return 0;
	else
		return i;
 } 
 
 /*遍历*/
 void ds_traverse(node *pNode)
 {
 	node *temp;
 	temp=pNode;							//temp作为头结点 
 	printf("**********链表中的元素********");
	
	do
	{
		printf("%4d",temp->data);		//进行输出 
	 } while((temp=temp->next)!=pNode);	//直到temp的指针指向头结点 
	 printf("\n");
  } 
  
  int main()
  {
  	node *pHead=NULL;
  	char opp;
  	int find;
  	
  	printf("1.初始化列表\n\n2.插入结点\n\n3.删除节点\n\n4.返回结点位置\n\n5.遍历链表\n\n0.退出\n\n请输入你的操作"); 
  	
  	while(opp!='0')
  	{
  		scanf("%c",&opp);
  		switch(opp)
  		{
  			case'1':
  				ds_init(&pHead);
  				printf("\n");
  				ds_traverse(pHead);
  				break;
  			
  			case'2':
  				printf("输入需要插入结点的位置:"); 
				 scanf("%d",&find);
				 ds_insert(&pHead,find);
				 printf("在位置%d插入值后:\n",find);
				 ds_traverse(pHead);
				 printf("\n");
				 break;
				 
			case'3':
				printf("输入需要删除的结点位置:");
				scanf("%d",&find);
				ds_delete(&pHead,find);
				printf("删除第%d个结点后:",find);
				ds_traverse(pHead);
				printf("\n");
				break;
				
			case'4':
				printf("你要查找倒数第几个结点的值:");
				scanf("%d",&find);
				printf("元素%d所在位置:%d\n",find,ds_search(pHead,find));
				printf("\n");
				break;
				
			case'5':
				 ds_traverse(pHead);
				 printf("\n");
				 break;
				
			case'0':
				exit(0);
		  }
	  }
	  return 0;
  }
  

   新手刚刚入门数据结构,用了一个上午了解,认识,理解了循环链表,虽然懂了,可无奈小编智力有限,费了不少时间,不过功夫不负有心人,总算在数据结构大门挤出了一点门缝,看到一个特别好的实例,有链表的初始化,插入,删除,查看,遍历,感觉受益匪浅,想与大家分享,所有理解都加在注释里面了,大家可以边看代码,边理解。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值