#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
typedef struct node
{
struct node *prior;///前驱
int data;///数据
struct node *next;///后继
}linklist;
void clear();///清屏
linklist *init_DoubleLinkList();///初始化双向循环链表
void creat_DoubleLinkList(linklist *);///创建双向循环链表
int del_val(linklist *);///删除双向循环链表的值
int insert_val(linklist *);///插入双向循环链表的值
void display_DoubleLinkList(linklist *);///输出双向循环链表
int main()
{
linklist *L;///L为头结点
int choice,ok;
do
{
printf("\t\t\t*************************\n");
printf("\t\t\t*1.初始化双向循环链表\t*\n");
printf("\t\t\t*2.创建双向循环链表\t*\n");
printf("\t\t\t*3.删除双向循环链表的值\t*\n");
printf("\t\t\t*4.插入双向循环链表的值\t*\n");
printf("\t\t\t*5.显示双向循环链表的值\t*\n");
printf("\t\t\t*0.退出\t\t\t*\n");
printf("\t\t\t*************************\n");
printf("请选择你需要操作的数字:");
scanf("%d",&choice);
if(choice==0)
break;
switch(choice)
{
case 1:L=init_DoubleLinkList();break;
case 2:creat_DoubleLinkList(L);break;
case 3:ok=del_val(L);
if(ok)
printf("删除成功\n");
else
printf("删除失败\n");
break;
case 4:ok=insert_val(L);
if(ok)
printf("插入成功\n");
else
printf("插入失败\n");
break;
case 5:display_DoubleLinkList(L);break;
default:printf("输入错误,请重新输入\n");break;
}
clear();
}while(1);
return 0;
}
///初始化循环链表
linklist *init_DoubleLinkList()
{
linklist *L;
L=(linklist *)malloc(sizeof(linklist));
if(!L)
printf("初始化失败\n");
else
printf("初始化成功\n");
L->next=L->prior=L;
L->data=0;
return L;
}
///创建循环链表
void creat_DoubleLinkList(linklist *L)
{
int num,data;
linklist *p,*q,*temp;
temp=L->next;
while(temp->next!=L)
temp=temp->next;///多次进入,头结点都是上一次的双向循环链表的尾结点
p=q=temp;
printf("请输入你需要的添加的数量:");
scanf("%d",&num);
printf("\n");
printf("请输入%d个数据:",num);
while(num--)
{
scanf("%d",&data);
p->next=(linklist *)malloc(sizeof(linklist));///申请的是p的next,因为p已经是指向L了,不能再操作了
p->next->data=data;
p=p->next;///p向新的节点
p->prior=q;///新的节点指向上一个节点q
q=q->next;///上一个节点也指向新的节点,这样就达到双向了
}
p->next=L;///输入结束之后p->next不再是之前为空了,而是指向L这个头结点,也就达到循环的效果了
L->prior=p;///L的头节点也要指向尾节点那么也就是达到双向了
}
///输出链表
void display_DoubleLinkList(linklist *L)
{
linklist *p=L->next;///一定是头节点的next,如果不是,那么就不会进行循环输出了
if(L->next==L)
{
printf("NULL\n");
return ;///空链表直接返回
}
printf("双向链表数据如下:");
while(p!=L)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
///删除数据
int del_val(linklist *L)
{
int value,ok=0;
linklist *p;
p=L->next;
if(L->next==L)
{
printf("NULL\n");
return 0;///删除失败返回0
}
printf("请输入你要删除的值:");
scanf("%d",&value);
while(p!=L)
{
p=p->next;///q->next才是真正的有数据
if(p->data==value)
{
p->prior->next=p->next;///p的prior的next也就是p的前一个节点的next指向了p的next,也就相当于跳过了p
p->next->prior=p->prior;///p的next->prior也就是p的下一个节点的prior指向了p的prior,也就是相当于p的下一个节点指向了p上一个节点
///完美衔接过去
free(p);///释放p
ok=1;
break;
}
}
if(ok)
return 1;///删除成功返回1
else
return 0;///删除失败返回0
}
///插入数据
int insert_val(linklist *L)
{
int loc,value,position=0,ok=0;
linklist *p,*temp;
temp=(linklist *)malloc(sizeof(linklist));
p=L->next;
if(L->next==L)
{
printf("NULL\n");
return 0;///插入失败返回0
}
printf("请输入你要在什么位置插入:");
scanf("%d",&loc);
printf("请输入要插入的值:");
scanf("%d",&value);
temp->data=value;
while(p!=L)
{
++position;
if(position==loc)///找到loc的位置,并跳出
{
ok=1;
break;
}
p=p->next;
}
temp->prior=p->prior;///temp的prior指向p的prior,相当于temp的前驱指向了loc-1,也就达到temp变loc的位置的开始
p->prior->next=temp;///p->prior->next就是loc-1的next指向temp,temp的前一个节点的prior和next都衔接好了,接下来弄p
temp->next=p;///temp的next指向p,p也就变成了loc+1的位置了
p->prior=temp;///p的prior指向temp也就是上一个节点
///以上四个步骤之后就完美把temp插入进去,让temp完美变成loc的位置
if(ok)
return 1;///插入成功返回1
else
return 0;///插入失败返回0
}
///清屏
void clear()
{
printf("按任意键继续......\n");
getch();
system("cls");
}
双向循环链表基本操作
最新推荐文章于 2024-08-07 11:30:08 发布