平平

双向循环链表

双向循环链表(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;
}