欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【链表】带头结点的双向循环链表

程序员文章站 2022-03-15 19:33:01
...

还需改进:

creat_node这个函数应有返回类型,来判断新建结点是否成功,不然主函数中不管成不成功都会访问该节点成员。

改了这个函数,在主函数中create_node后要判断是否成功,不成功就提示并退出函数,退出前别忘了还要释放链表!

同时create_link这个函数中也要判断head是否申请成功,不成功的话同样提示并退出函数。

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

struct dnode
{
    int num;

    struct dnode * prior;
    struct dnode * next;
};

typedef struct dnode Dnode;
typedef struct dnode * Dlink;

void create_dnode(Dlink *DblNode)
{
    int count = 10;

    do
    {
        *DblNode = (Dlink)malloc(sizeof(Dnode));
        count--;
    }while(!is_malloc_ok(*DblNode) && count);
}

int is_malloc_ok(Dlink DblNode)
{
    if(DblNode == NULL)
    {
        printf("malloc error!\n");
        return 0;
    }
    return 1;
}

void create_dlink(Dlink *DblHead)
{
    Dlink DblNode;
    create_dnode(&DblNode);

    *DblHead = DblNode;
    DblNode->next = DblNode;
    DblNode->prior= DblNode;
}

void insert_dnode_head(Dlink DblHead,Dlink DblNode)
{
    DblHead->next->prior = DblNode;
    DblNode->next = DblHead->next;
    DblHead->next = DblNode;
    DblNode->prior = DblHead;
}

void display(Dlink DblHead)
{
    if(DblHead == NULL)
    {
        printf("该链表已被释放\n");
        return;
    }

    Dlink p = DblHead;
    
    printf("该链表显示是:\n");
    if(p->next == DblHead)
    {
        printf("Link is empty!\n");
    }
    else
    {
        p = p->next;
        while(p != DblHead)
        {
            printf("num is %d\n",p->num);
            p = p->next;
        }
    }
}

int length(Dlink DblHead)
{
    Dlink p = DblHead->next;
    int count = 0;

    while(p != DblHead)
    {
        count++;
        p = p->next;
    }

    return count;
}

void insert_dnode_tail(Dlink DblHead,Dlink DblNode)
{
    DblNode->prior = DblHead->prior;
    DblHead->prior->next = DblNode;
    DblNode->next = DblHead;
    DblHead->prior = DblNode;
}

void insert_dnode_mid_before(Dlink DblHead,Dlink DblNode,int num)
{
    Dlink p = DblHead->next;

    while(p != DblHead && p->num != num)
    {
        p = p->next;
    }

    if(p == DblHead)
    {
        printf("No such node!\n");
    }
    else
    {
        DblNode->prior = p->prior;
        p->prior->next = DblNode;
        DblNode->next = p;
        p->prior = DblNode;
    }
}

void insert_dnode_mid_after(Dlink DblHead,Dlink DblNode,int num)
{
    Dlink p = DblHead->next;

    while(p != DblHead && p->num != num)
    {
        p = p->next;
    }

    if(p == DblHead)
    {
        printf("No such node!\n");
    }
    else
    {
        p->next->prior = DblNode;
        DblNode->next = p->next;
        p->next = DblNode;
        DblNode->prior = p;
    }
}

void delete_dnode(Dlink DblHead,int num)
{
    Dlink p = DblHead->next;

    while(p != DblHead && p->num != num)
    {
        p = p->next;
    }

    if(p == DblHead)
    {
        printf("No such node!\n");
    }
    else
    {
        p->next->prior = p->prior;
        p->prior->next = p->next;
        free(p);
    }
}

Dlink find(Dlink DblHead,int num)
{
    Dlink p = DblHead->next;

    while(p != DblHead && p->num != num)
    {
        p = p->next;
    }

    if(p == DblHead)
    {
        p = NULL;
        return p;
    }
    else
    {
        return p;
    }
}

void make_empty(Dlink DblHead)
{
    Dlink p = DblHead->next;
    Dlink q;

    while(p != DblHead)
    {
        q = p->next;
        p->next->prior = p->prior;
        p->prior->next = p->next;
        free(p);
        p = q;
    }
}

void release_dlink(Dlink *DblHead)
{
    make_empty(*DblHead);
    free(*DblHead);
    *DblHead = NULL;
}

int main()
{
    Dlink DblHead;
    Dlink DblNode;
    int i;
    int num;

    create_dlink(&DblHead);

    for(i = 0 ;i < 5; i++)
    {
        create_dnode(&DblNode);
        DblNode->num = i + 1;

        //insert_dnode_head(DblHead,DblNode);
        insert_dnode_tail(DblHead,DblNode);
    }

    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));


    create_dnode(&DblNode);
    printf("请输入你想插入的结点的数值:");
    scanf("%d",&DblNode->num);
    printf("请输入你想在值为哪个的结点前插入该结点:");
    scanf("%d",&num);

    insert_dnode_mid_before(DblHead,DblNode,num);

    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));


    create_dnode(&DblNode);
    printf("请输入你想插入的结点的数值:");
    scanf("%d",&DblNode->num);
    printf("请输入你想在值为哪个的结点后插入该结点:");
    scanf("%d",&num);

    insert_dnode_mid_after(DblHead,DblNode,num);

    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));

    
    printf("请输入你想删除的结点的数值:");
    scanf("%d",&num);

    delete_dnode(DblHead,num);
    
    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));

    
    printf("请输入你想查找的结点的数值:");
    scanf("%d",&num);

    DblNode = find(DblHead,num);
    if(DblNode == NULL)
    {
        printf("没有这个结点\n");
    }
    else
    {
        printf("这个结点的数值是%d\n\n",DblNode->num);
    }

    make_empty(DblHead);

    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));

    release_dlink(&DblHead);
    display(DblHead);
    
    

    return 0;
}