双向循环链表
双向循环链表(Doubly Circular Linked List)是一种数据结构,它由多个节点(Node)组成,每个节点包含两个指针(Pointer),分别指向它的前一个节点和后一个节点,最后一个节点的后继指向头结点,头结点的前驱指向最后一个节点,形成一个环状结构。
下面是一个简单的双向循环链表的实现,包含节点的结构体和常见操作函数的实现:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define SHOW_MODE 0
#define FIND_MODE 1
#define DELL_MODE 2
typedef struct list_link_node
{
int data;
struct list_link_node * pre;
struct list_link_node * next;
}listnode,*listlink;
listlink Creat_list_node();//创建节点
int Mode_Select(listlink head );//模式选择
int Tail_Add_Node(listlink head);//尾部插入
listlink Display(listlink head,int mode);//遍历节点
int Head_Add_Node(listlink head);//头部插入
int ADD_Anywhere(listlink head);//任意节点插入(调用了Display遍历至输入数据相等处)
int Dele_Anywhere(listlink head);//删除任意节点
int ADD_Anywhere(listlink head)
{
if(head==NULL)
{
printf("failed!\n");
return 0;
}
if(head->next==head)
{
printf("empty!\n");
return 0;
}
listlink add_node = Display(head,FIND_MODE);//遍历
if(add_node ==(listlink) 0)
{
printf("add falied!\n");
return -1;
}
listlink new_node=Creat_list_node();//新建节点
if(new_node==(listlink) -1)
{
printf("new falied!\n");
return -1;
}
printf("请输入要添加的数据:\n");
scanf("%d",&new_node->data);
new_node->next=add_node->next;
new_node->next->pre=new_node;
new_node->pre=add_node;
add_node->next=new_node;
return 0;
}
int Dele_Anywhere(listlink head)
{
if(head==NULL)
{
printf("failed!\n");
return 0;
}
if(head->next==NULL)
{
printf("empty!\n");
return 0;
}
listlink del_node = Display(head,DELL_MODE);//删除模式(遍历)
if(del_node ==(listlink) 0)
{
printf("del falied!\n");
return -1;
}
del_node->pre->next=del_node->next;
del_node->next->pre=del_node->pre;
del_node->next=NULL;
del_node->pre=NULL;
free(del_node);
return 0;
}
int Head_Add_Node(listlink head)
{
if(head==NULL)
{
printf("failed!\n");
return -1;
}
listlink new_node=Creat_list_node();//初始化新节点
if(new_node==(listlink)-1)
{
printf("tail node failed!\n");
return -1;
}
printf("请输入新数据:\n");
scanf("%d",&new_node->data);
new_node->next=head->next; //新节点next 赋值为 传入节点next
new_node->next->pre=new_node; //此时新节点next同等 传入节点,该节点pre 赋值为 新节点
new_node->pre=head; //新节点pre 赋值为 传入节点
head->next=new_node; //传入节点next 赋值为 新节点
return 0;
}
listlink Creat_list_node()
{
listlink node=(listlink)malloc(sizeof(listnode)); //指向堆,用完不会自动释放
if(node==(listlink)NULL)
{
printf("listlink malloc failed!\n");
return (listlink)-1;
}
memset(node,0,sizeof(listnode));
node->pre=node;
node->next=node;
return node;
}
int Tail_Add_Node(listlink head)
{
if(head==NULL)
{
printf("failed!\n");
return -1;
}
listlink new_node=Creat_list_node();//创建新节点
if(new_node==(listlink)-1)
{
printf("tail node failed!\n");
return -1;
}
printf("请输入新数据:\n");
scanf("%d",&new_node->data);//数据域
new_node->pre=head->pre; //新节点pre 赋值为 传入节点pre
new_node->pre->next=new_node; //此时用 新节点pre 等于传入节点,成员next赋值为新节点
new_node->next=head; //传入节点next 赋值为 新节点
head->pre=new_node; //传入节点pre 赋值为 新节点
//"蛇头咬蛇尾"
return 0;
}
listlink Display(listlink head,int mode)
{
if(head==NULL)
{
printf("adnormal!\n");
return (listlink)0;
}
if(head->next==head)
{
printf("empty!\n");
return (listlink)0;
}
int data=0;
if(mode==FIND_MODE||mode==DELL_MODE)
{
printf("请输入要检索的数据!\n");
scanf("%d",&data);//要检索的值
}
//初始化节点 赋值为 传入节点next;当前节点 不等于 传入节点;当前节点 赋值为 当前节点next
for(listlink temp_node=head->next;temp_node!=head;temp_node=temp_node->next)
{
if(mode==SHOW_MODE)
{
printf("%d\n",temp_node->data);
}
if((mode==FIND_MODE||mode==DELL_MODE)&&temp_node->data==data)//判断当前节点成员数据值与输入的数据值
{
printf("hit the number!\n");
return temp_node;//返回当前节点地址
}
}
if(mode==FIND_MODE||mode==DELL_MODE)
{
printf("找不到数据!\n");
return 0;
}
return (listlink)0;
}
int Mode_Select(listlink head)
{
if(head==NULL)
{
printf("failed!\n");
return 0;
}
int select_num=0;
while (1)
{
system("clear");
printf("-------1.尾插链表-----------\n");
printf("-------2.头插链表-----------\n");
printf("-------3.指定位置添加数据----\n"); //bian
printf("-------4.指定位置删除数据----\n"); //bian
printf("-------5.检索数据-----------\n"); //bian
printf("-------6.移动数据-----------\n"); //bian
printf("-------7.显示链表------------\n");
printf("-------8.退出链表!-----\n");
scanf("%d",&select_num);
switch (select_num)
{
case 1:Tail_Add_Node(head);
break;
case 2:Head_Add_Node(head);
break;
case 3:ADD_Anywhere(head);
break;
case 4:Dele_Anywhere(head);
break;
case 5:Display(head,FIND_MODE);
break;
case 6:printf("-------1.尾插链表------\n");
break;
case 7:Display(head,SHOW_MODE);
break;
case 8:printf("-------8.退出链表!------\n");
return 0;
default:printf("错误的命令!请重新输入:\n");
break;
}
sleep(2);
}
return 0;
}
int main(int argc, char const *argv[])
{
listlink head=Creat_list_node();
if(head==(listlink)-1)
{
printf("creat head failed!\n");
return -1;
}
Mode_Select(head);
return 0;
}