单链表之删除节点

1.删除节点的步骤
(1)找到要删除的这个节点:通过遍历来查找节点,从头指针+头节点开始,顺着链表依次将各个节点拿出来,按照一定的方法比对,找到我们要删除的那个节点。
(2)删除这个节点
(2.1)如果不是尾节点:首先把待删除节点的前一个节点的pNext指向待删除节点的后一个节点的首地址,然后再将摘出来这个节点free掉。
(2.2)如果这个节点是尾节点,首先把待删除这个节点的前一个节点的pNext指针指向NULL,然后再将摘出来这个节点free掉。

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

//构建链表节点
struct node
{
        int data;       //有效数据
        struct node *pNext;     //指向下一个节点的指针

};


//函数功能,创建链表节点
//返回值:指针,指向我们本函数新创建的一个节点的首地址
struct node *creat_node(int data)
{

        //创建一个链表节点
        struct node *p = (struct node *)malloc(sizeof(struct node));
        if(NULL == p)
        {
                printf("malloc error\n");
                return NULL;
        }


        //清理申请到的堆内存
        // void bzero(void *s, size_t n);
        bzero(p,sizeof(struct node));

        //填充节点
        p->data = data;
        p->pNext = NULL;       //将来要指向下一个节点的首地址

        return p;
}

//重头部加入新节点
void insert_head(struct node *pH,struct node *new)
{

/*      方法一:
         
        //第一步:新节点的pNext指向第一个节点
        new->pNext = pH->pNext;
        //第二部:头结点的pNext指向新节点
        pH->pNext = new;
        //第三部:头结点的计数加1
        pH->data += 1;
*/
        //方法二:

        //先保存第一个节点
        struct node *p1 = pH->pNext;
        //让头结点的pNext指向新节点
        pH->pNext = new;
        //新节点的pNext指向保存好的第一个节点
        new->pNext = p1;
        //头结点计数加1
        pH->data += 1;
}

/有头节点遍历
void bianli2(struct node *pH)
{
        struct node *p = pH;  //头指针后面是头节点这样初始化下面会打印头结点的数据

        printf("开始遍历==================\n");

        while(NULL != p->pNext)
        {
                p = p->pNext;
                printf("node data = %d\n",p->data);
        }

        printf("遍历完成==================\n");
}

//从链表pH中删除节点,待删除节点的数据区的值等于data
//返回值:当找到节点并成功删除返回0,未找到这个节点返回-1
int delete_node(struct node *pH,int data)
{
        struct node *p = pH;    //头指针后面的头节点(用来指向当前节点)
        struct node *pp = NULL;         //用来指向当前节点的前一个节点

        while(NULL != p->pNext) //判断是不是最后一个节点
        {
                pp = p;         //用来保留前一个节点的状态
                p = p->pNext;   //走向下一个节点,也就是循环增量

                if(p->data == data)     //判断这个节点是否是我们想要删除的那个节点
                {
                        if(NULL == p->pNext)    //1.如果找到的是尾节点
                        {
                                pp->pNext = NULL;       //原来尾节点的前一个为节点变成了新尾节点
                                free(p);        //释放原来尾节点的内存
                        }
                        else    //如果找到的是普通节点
                        {
                                pp->pNext = p->pNext;   //要删除的节点的前一个节点和后一个节点相连
                                free(p);
                        }


                        return 0;
                }
        }
        //到这里还没有找到,就说明链表中没有我们想要的那个节点
        printf("没找到这个节点\n");
        return -1;

}

int main(void)
{
        //定义头指针
        //struct node *pHeader = NULL;  这里如果把pHeader赋值为NULL在加入节点这个函数内就会出现段错误
        struct node *pHeader = creat_node(0);

        insert_head(pHeader,creat_node(1));

        insert_head(pHeader,creat_node(2));

        insert_head(pHeader,creat_node(3));


        printf("header node data = %d\n",pHeader->data);        //打印有多少个节点

        //bianli(pHeader);
        printf("删除前================\n");
        bianli2(pHeader);
        delete_node(pHeader,1);
        printf("删除后================\n");
        bianli2(pHeader);

        return 0;
}

输出结果

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值