双向循环链表的增删改插(第一次写博客),欢迎指正

双向循环链表增删改查菜单

在这里插入图片描述

func.h

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct menu
{
	int num;
	int results;
	struct menu *pbef;
	struct menu *pnext;
}Menu_t,*pMenu_t;
void list_sort_insert(pMenu_t *,pMenu_t *,int,int);
void list_print(pMenu_t);
void list_head_insert(pMenu_t *,pMenu_t *,int,int);
void list_tail_insert(pMenu_t *,pMenu_t *,int,int);
void list_increase(pMenu_t *,pMenu_t *,int,int,int);
void list_find(pMenu_t *,int);
void list_delete(pMenu_t *,pMenu_t *,int);
void list_change(pMenu_t *,pMenu_t *,int);

func.c

#include"func.h"
//顺序构建链表
void list_sort_insert(pMenu_t *pphead,pMenu_t *pptail,int i,int score)
{
	pMenu_t pnew=(pMenu_t)malloc(sizeof(Menu_t));
	pMenu_t pcur=*pphead;
	pMenu_t ppre=*pphead;
	//链表为空
	memset(pnew,0,sizeof(Menu_t));
	pnew->num=i;
	pnew->results=score;
	if(NULL==pcur)
	{
		pnew->pnext=pnew;
		pnew->pbef=pnew;
		*pphead=pnew;
		*pptail=pnew;
	}
	//头插入
	else if(i<pcur->num)
	{
		(*pptail)->pnext=pnew;
		pnew->pnext=*pphead;
		(*pphead)->pbef=pnew;
		pnew->pbef=*pptail;
		*pphead=pnew;
	}
	else
	{
		//在链表有三个及以上节点时,中间插入
		while(pcur->pnext!=*pphead)
		{
			if(i<pcur->num)
			{
				ppre->pnext=pnew;
				pnew->pnext=pcur;
				pcur->pbef=pnew;
				pnew->pbef=ppre;
				break;
			}
			ppre=pcur;
			pcur=pcur->pnext;
		}
		//当链表只有两个节点时,中间插入
		if(i<pcur->num)
		{
				ppre->pnext=pnew;
				pnew->pnext=pcur;
				pcur->pbef=pnew;
				pnew->pbef=ppre;
		}
		//尾部插入
		if(i>pcur->num)
		{
			(*pptail)->pnext=pnew;
			pnew->pnext=*pphead;
			(*pphead)->pbef=pnew;
			pnew->pbef=*pptail;
			*pptail=pnew;
		}
	}
}
//头插法
void list_head_insert(pMenu_t *pphead,pMenu_t *pptail,int i,int score)
{
	pMenu_t pnew=(pMenu_t)malloc(sizeof(Menu_t));
	pMenu_t pcur=*pphead;
	pMenu_t ppre=*pphead;
	memset(pnew,0,sizeof(Menu_t));
	pnew->num=i;
	pnew->results=score;
	if(NULL==pcur)
	{
		pnew->pnext=pnew;
		pnew->pbef=pnew;
		*pphead=pnew;
		*pptail=pnew;
	}
	else
	{
		(*pptail)->pnext=pnew;
		pnew->pnext=*pphead;
		(*pphead)->pbef=pnew;
		pnew->pbef=*pptail;
		*pphead=pnew;
	}
}
//尾插法
void list_tail_insert(pMenu_t *pphead,pMenu_t *pptail,int i,int score)
{
	pMenu_t pnew=(pMenu_t)malloc(sizeof(Menu_t));
	pMenu_t pcur=*pphead;
	pMenu_t ppre=*pphead;
	memset(pnew,0,sizeof(Menu_t));
	pnew->num=i;
	pnew->results=score;
	if(NULL==pcur)
	{
		pnew->pnext=pnew;
		pnew->pbef=pnew;
		*pphead=pnew;
		*pptail=pnew;
	}
	else
	{
		(*pptail)->pnext=pnew;
		pnew->pnext=*pphead;
		(*pphead)->pbef=pnew;
		pnew->pbef=*pptail;
		*pptail=pnew;
	}
}
//打印输出
void list_print(pMenu_t phead)
{
	pMenu_t pt=phead;
	while(phead!=NULL)
	{
		printf(" %d %d\n",phead->num,phead->results);
		phead=phead->pnext;
		if(phead==pt)
			break;
	}
	printf("\n");
}
//查询内容
void list_find(pMenu_t *pphead,int b)
{
	pMenu_t pcur=*pphead;
	if(NULL==*pphead)
	{
		printf("链表为空\n");
	}
	else
	{
		while(pcur!=NULL)
		{
			if(pcur->num==b)
			{
				printf("%d处内容为%d\n",b,pcur->results);
				break;
			}
			pcur=pcur->pnext;
			if(pcur==*pphead)
				break;
		}
		if(b!=pcur->num)
		{
			printf("该节点不存在");
		}
	}
}
//增加节点
void list_increase(pMenu_t *pphead,pMenu_t *pptail,int i,int score,int b)
{
	int a;
	pMenu_t pnew=(pMenu_t)malloc(sizeof(Menu_t));
	pMenu_t pcur=*pphead;
	pMenu_t ppre=*pptail;
	memset(pnew,0,sizeof(Menu_t));
	pnew->num=i;
	pnew->results=score;
	if(NULL==pcur)
	{
		pnew->pnext=pnew;
		pnew->pbef=pnew;
		*pphead=pnew;
		*pptail=pnew;
	}
	else
	{
		while(pcur!=NULL)
		{
			if(b==pcur->num)
			{
				A:printf("请输入a的值:");
				printf("前插:a=1;     后插:a=0\n");
				scanf("%d",&a);
				if(a==1)
					if(pcur==*pphead)
					{
						ppre->pnext=pnew;
						pnew->pnext=pcur;
						pcur->pbef=pnew;
						pnew->pbef=ppre;
						*pphead=pnew;
						break;
					}
					else
				{
					ppre->pnext=pnew;
					pnew->pnext=pcur;
					pcur->pbef=pnew;
					pnew->pbef=ppre;
					break;
				}
				if(a==0)
				{
					pnew->pnext=pcur->pnext;
					pcur->pbef=pnew;
					pcur->pnext=pnew;
					pnew->pbef=pcur;
					break;
				}
				else
				{
					printf("请重新输入:");
					goto A;
				}
				break;
			}
			ppre=pcur;
			pcur=pcur->pnext;
			if(pcur==*pphead)
				break;
		}
		if(b!=pcur->num)
		{
			printf("没有目的节点,插入失败\n");
		}
	}
}
//删除节点
void list_delete(pMenu_t *pphead,pMenu_t *pptail,int b)
{
	pMenu_t pcur=*pphead;
	pMenu_t ppre=*pphead;
	if(b==pcur->num)
	{
		(*pptail)->pnext=pcur->pnext;
		pcur->pnext->pbef=*pptail;
		*pphead=pcur->pnext;
		if(NULL==*pphead)
		{
			*pptail=NULL;
		}
			free(pcur);
			pcur=NULL;
	}
	else
	{
		while(pcur!=NULL)
		{
			if(b==pcur->num)
			{
				ppre->pnext=pcur->pnext;
				pcur->pnext->pbef=ppre;
				break;
			}
			ppre=pcur;
			pcur=pcur->pnext;
			if(pcur==*pphead)
			{
				ppre->pnext=*pphead;
				(*pphead)->pbef=ppre;
				*pptail=ppre;
				break;
			}
		}
			/*free(pcur);
			pcur=NULL;*/
		if(b!=pcur->num)
		{
			printf("链表中无该节点,删除失败\n");
		}
	}
}
void list_change(pMenu_t *pphead,pMenu_t *pptail,int b)
{
	pMenu_t pcur=*pphead;
	int a;
	if(NULL==*pphead)
	{
		printf("链表为空\n");
	}
	else
	{
		while(pcur!=NULL)
		{
			if(pcur->num==b)
			{
				printf("找到目标节点,请修改内容\n");
				printf("请输入要修改内容:");
				scanf("%d",&a);
				pcur->results=a;
				printf("修改成功,新值为%d\n",pcur->results);
				break;
			}
			pcur=pcur->pnext;
			if(pcur==*pphead)
				break;
		}
		if(b!=pcur->num)
		{
			printf("该节点不存在,修改失败");
		}
	}
}

main.c

#include"func.h"

int main()
{
	int i;
	int b;
	int a;//代表输入命令
	int score;
	pMenu_t phead=NULL,ptail=NULL;
	printf("*******************************************\n");
	printf("|                菜单                      |\n");
	printf("|-----------------------------------------|\n");
	printf("|  请输入命令:                             |\n");
	printf("|          1、创建一个双向循环链表          |\n");
	printf("|          2、增加节点                     |\n");
	printf("|          3、删除节点                    |\n");
	printf("|          4、修改节点内容                |\n");
	printf("|          5、查询节点内容                |\n");
	printf("|          6、显示所有节点内容             |\n");
	printf("|          7、退出菜单                    |\n");
	printf("*******************************************\n");
	while(printf("请输入命令:\n"),scanf("  %d",&a)!=EOF)
	{
		if(a==1)
		{
			printf("创建一个双向循环链表\n");
			printf("请依次输入链表标号及内容:");
			while(scanf("%d %d",&i,&score)!=EOF)
			{
				list_sort_insert(&phead,&ptail,i,score);
				/*list_head_insert(&phead,&ptail,i,score);
				list_tail_insert(&phead,&ptail,i,score);*/
			}
		}
	//在任意位置增加节点
		if(a==2)
		{
			printf("请输入要增加的节点信息:");
			scanf("%d %d",&i,&score);
			printf("请输入增加节点位置信息:");
			scanf("%d",&b);
			list_increase(&phead,&ptail,i,score,b);
		}
		//删除节点
		if(a==3)
		{
			printf("请输入要删除节点:");
			scanf("%d",&b);
			list_delete(&phead,&ptail,b);
		}
		//修改内容
		if(a==4)
		{
			printf("请输入要修改的节点:");
			scanf("%d",&b);
			list_find(&phead,b);
			list_change(&phead,&ptail,b);
		}
		//查询内容
		if(a==5)
		{
			printf("请输入要查询的节点:");
			scanf("%d",&b);
			list_find(&phead,b);
		}
		//显示所有节点内容
		if(a==6)
		{
			list_print(phead);
		}
		//退出程序
		if(a==7)
		{
			printf("---感谢使用,再见---\n");
			break;
		}
	}
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值