C语言链表删除功能,删除的节点再次插入链表的问题


//设计双链表的数据节点类型 
#include
#include
#include



typedef struct node
{
    int data;
    struct node *next;
    struct node *prev;
}DN,*PDN;
//struct node -----DN
//struct node *----PDN

//新建空的带头节点的双向头节点链表 
PDN doublelist_init() 
{
    //申请头节点内存 
    PDN phead=(PDN*)malloc(sizeof(DN));
    if(phead==NULL)
    {
        printf("malloc fail\n");
        return false;
    }
    phead->next=phead;
    phead->prev=phead;
    return phead;
}

bool is_empty(PDN phead)
{
    if(phead->prev==NULL && phead->next==NULL)
       return true;
    else
       return false;
}

//向后遍历 
show_head(PDN phead)
{
    if(phead==NULL)
    {
        printf("malloc fail\n");
        return false;
    }
    if(is_empty(phead))
       return;
       
    PDN p=phead->next;
    while(p!=phead)
    {
        printf("%d\t",p->data);
        p=p->next;
    }
    printf("\n");
    
    return;
}

//向前遍历 
show_tail(PDN phead)
{
    if(phead==NULL)
    {
        printf("malloc fail\n");
        return false;
    }
    PDN p=phead->prev;
    while(p!=phead)
    {
        printf("%d\t",p->data);
        p=p->prev; 
    }
    printf("\n");
    
    return;
}

//把d作为数据域,构造新节点,然后把新节点插入到phead指向的头节点
//插入成功返回true,失败返回false 
bool insert_node_head(PDN phead,int d)
{
    //把d作为数据域,构造新节点 
    //申请新节点内存空间 
    PDN pnew=(PDN*)malloc(sizeof(DN));
    if(pnew==NULL)
    {
        printf("malloc fail\n");
        return false;
    }
    pnew->data=d;
    pnew->prev=NULL;
    pnew->next=NULL;
    
    if(phead==NULL||pnew==NULL)
    {
        printf("malloc fail\n");
        return;
    }
    
    pnew->next=phead->next;
    pnew->prev=phead;
    phead->next->prev=pnew;
    phead->next=pnew;
    
    return true;
}
//把d作为数据域,构造新节点,然后把新节点插入到phead指向的头节点前面(整条链表的末尾) 
//插入成功返回true,失败返回false 
bool insert_node_tail(PDN phead,int d)
{
    PDN pnew=(PDN*)malloc(sizeof(DN));
    /*PDN p = phead->prev; //聪和佳的写法*/
    if(pnew==NULL)
    {
        printf("malloc fail\n");
        return false;
    }
    pnew->data=d;
    pnew->prev=NULL;
    pnew->next=NULL;
    
    //聪和佳的写法
    //pnew->prev = p;
    //pnew->next = phead;
    //phead->prev = pnew;
    //p->next = pnew;
    pnew->prev=phead->prev;
    pnew->next=phead;
    phead->prev->next=pnew;
    phead->prev=pnew;
    
    return true;
}

int delete(PDN phead,int d,PDN pdata)
{
    /*int flag = 0;*/
    if(is_empty(phead))
       return false ;
       
    PDN pdel = phead->next;
    PDN pdata_del = NULL;
    while(pdel!=phead)
    {
       if(pdel->data==d)
       {
           PDN pdata_del = pdel;
           pdel->prev->next=pdel->next;
           pdel->next->prev=pdel->prev;
           
           /*flag=1*/;
           break;
       }
       pdel=pdel->next;
    }
    //if (flag == 0)
    //    return false;
    //else
    //    return pdata_del;
    return pdata_del;
}

int main()
{
    //创建空的带头节点的双向循环链表 
    PDN phead=doublelist_init();
    PDN pdata = NULL;
    
    //向链表头部中插入节点
    printf("this is doublelist after insert node from head\n");
    printf("show head and tail:\n");
    insert_node_head(phead,1);
    insert_node_head(phead,2);
    insert_node_head(phead,3);
    insert_node_head(phead,4);
    show_head(phead);
    show_tail(phead);
    
    //向链表尾部中插入节点 
    printf("this is doublelist after insert node from tail");
    printf("show head and tail:\n");
    insert_node_tail(phead,1);
    insert_node_tail(phead,2);
    insert_node_tail(phead,3);
    insert_node_tail(phead,5);
    show_head(phead);
    show_tail(phead);
    
    //删除链表的数据
    printf("this is doulelist after delete tail\n");
    printf("show head and tail:\n");
    if(pdata=delete(phead,5,&pdata))
          printf("delete success\n");
    else
        printf("delete fail\n"); 
    show_head(phead);
    show_tail(phead);
}

如何将删除功能中,以删除的链表节点(没有清除数据),重新插入想插入的链表节点位置,该节点也返回给主函数

你是想删除节点后,还可以添加被删除的节点嘛?你可以再创建一个链表,作为回收站一样的功能。

  • 当删除节点时,就是把被删除的节点放到新链表中,同时当前链表删除此节点
  • 当恢复节点时,就是从新链表中取出元素并删除然后放到当前链表

修改处见注释,供参考:

//设计双链表的数据节点类型 
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

typedef struct node
{
    int data;
    struct node* next;
    struct node* prev;
}DN, * PDN;
//struct node -----DN
//struct node *----PDN

//新建空的带头节点的双向头节点链表 
PDN doublelist_init()
{
    //申请头节点内存 
    PDN phead = (PDN)malloc(sizeof(DN));
    //PDN phead = (PDN*)malloc(sizeof(DN));  修改
    if (phead == NULL)
    {
        printf("malloc fail\n");
        return false;
    }
    phead->next = phead;
    phead->prev = phead;
    return phead;
}

bool is_empty(PDN phead)
{
    if (phead->prev == NULL && phead->next == NULL)
        return true;
    else
        return false;
}

//向后遍历 
void show_head(PDN phead)  //show_head(PDN phead) 修改
{
    if (phead == NULL)
    {
        printf("malloc fail\n");
        return;  //false;        修改
    }
    if (is_empty(phead))
        return;

    PDN p = phead->next;
    while (p != phead)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");

    return;
}

//向前遍历 
void show_tail(PDN phead)   //show_tail(PDN phead) 修改
{
    if (phead == NULL)
    {
        printf("malloc fail\n");
        return;  //false;      修改
    }
    PDN p = phead->prev;
    while (p != phead)
    {
        printf("%d ", p->data);
        p = p->prev;
    }
    printf("\n");

    return;
}

//把d作为数据域,构造新节点,然后把新节点插入到phead指向的头节点
//插入成功返回true,失败返回false 
bool insert_node_head(PDN phead, int d)
{
    //把d作为数据域,构造新节点 
    //申请新节点内存空间 
    PDN pnew = (PDN)malloc(sizeof(DN));
    //PDN pnew = (PDN*)malloc(sizeof(DN)); 修改
    if (pnew == NULL)
    {
        printf("malloc fail\n");
        return false;
    }
    pnew->data = d;
    pnew->prev = NULL;
    pnew->next = NULL;

    if (phead == NULL || pnew == NULL)
    {
        printf("malloc fail\n");
        return false;             //修改
    }

    pnew->next = phead->next;
    pnew->prev = phead;
    phead->next->prev = pnew;
    phead->next = pnew;

    return true;
}
//把d作为数据域,构造新节点,然后把新节点插入到phead指向的头节点前面(整条链表的末尾) 
//插入成功返回true,失败返回false 
bool insert_node_tail(PDN phead, int d)
{
    PDN pnew = (PDN)malloc(sizeof(DN));
    //PDN pnew = (PDN*)malloc(sizeof(DN));  修改
    /*PDN p = phead->prev; //聪和佳的写法*/
    if (pnew == NULL)
    {
        printf("malloc fail\n");
        return false;
    }
    pnew->data = d;
    pnew->prev = NULL;
    pnew->next = NULL;

    pnew->prev = phead->prev;
    pnew->next = phead;
    phead->prev->next = pnew;
    phead->prev = pnew;

    return true;
}

PDN  Delete(PDN phead, int d, PDN pdata) //int delete  修改
{
    if (is_empty(phead))
        return false;
    PDN pdel = phead->next;
    PDN pdata_del = NULL;
    while (pdel != phead)
    {
        if (pdel->data == d)
        {
            pdata_del = pdel;  //PDN pdata_del = pdel;修改
            pdel->prev->next = pdel->next;
            pdel->next->prev = pdel->prev;
            break;
        }
        pdel = pdel->next;
    }
    return pdata_del;
}

int main()
{
    //创建空的带头节点的双向循环链表 
    PDN phead = doublelist_init();
    PDN pdata = NULL;

    //向链表头部中插入节点
    printf("this is doublelist after insert node from head\n");
    printf("show head and tail:\n");
    insert_node_head(phead, 1);
    insert_node_head(phead, 2);
    insert_node_head(phead, 3);
    insert_node_head(phead, 4);
    show_head(phead);
    show_tail(phead);

    //向链表尾部中插入节点 
    printf("this is doublelist after insert node from tail");
    printf("show head and tail:\n");
    insert_node_tail(phead, 1);
    insert_node_tail(phead, 2);
    insert_node_tail(phead, 3);
    insert_node_tail(phead, 5);
    show_head(phead);
    show_tail(phead);

    //删除链表的数据
    printf("this is doulelist after delete tail\n");
    printf("show head and tail:\n");
    if (pdata = Delete(phead, 5, pdata)) //delete(phead, 5, &pdata) 修改
        printf("delete success\n");
    else
        printf("delete fail\n");
    show_head(phead);
    show_tail(phead);

    printf("deletd node_add:%p, pdata=%d", pdata, pdata->data); //修改,从链表脱离的结点信息保留在 pdata,
    return 0;                                                    //后续运行插入函数,将 pdata指向的结点 插入操作即可
}