创建N个单向链表对它进行摧毁和清空操作

本文详细介绍了链表摧毁和清空的区别。摧毁链表会释放包括头节点在内的所有节点,使链表不可用;而清空链表仅释放除头节点外的所有节点,链表仍可继续使用。通过实例和代码演示了两者的效果,并分享了vi编辑器的小技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摧毁和清空的含义及区别

摧毁

是先销毁了链表的头,然后接着一个一个的把后面的销毁了,这样这个链表就不能再使用了,即把包括头的所有节点全部释放。

清空

是先保留了链表的头,然后把头后面的所有的都销毁,最后把头里指向下一个的指针设为空,这样就相当与清空了,但这个链表还在,还可以继续使用;即保留了头,后面的全部释放

区别:

清空是链表的头还在,可以继续插入节点;销毁就是链表没了,整个链表(包括头)的空间都被释放了,不能进行任何操作了。

摧毁链表实例

int destroy(struct node *head)
{
    struct node *p; //定义结构体指针
    if(head==NULL)//如果链表不存在则返回0
    {   
        return 0;
    }   
    while(head != 0)//如果存在则进行摧毁,直到head为空,所有节点被销毁
    {   
        p = head->next;//把head指向的下一个节点被P保存
        free(head);//释放掉head指向的节点
        head = p;//把P保存的节点被head保存
    }   

};

清空链表实例

int clear(struct node *head)
{    
    struct node *p;//定义结构体指针
    struct node *q; 
    if(head == 0)
    {   
        return 0;
    }   
    p = head->next;//把头节点的下一个节点被p保存
    while(p != 0)//当p存在时,进行清空操作
    {   
        q = p->next;//使q保存p指向的下一个节点
        free(p);//释放掉P里的内容
        p = q;//让p保存q指向的节点
    }   
    head->next = NULL;//当上面循环完成时,已经只有一个头结点存在,使head-         >next=NULL,表示链表结束
 };

下面是完整代码示例

发现一个vi编辑器的小技巧,:set nonumber可以删除代码前的序号


/*********************************************************************************
 *      Copyright:  (C) 2017 fanmaolin<fanmaolinn@gmail.com>
 *                  All rights reserved.
 *
 *       Filename:  make4.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(08/05/2017)
 *         Author:  fanmaolin <fanmaolinn@gmail.com>
 *      ChangeLog:  1, Release initial version on "08/05/2017 07:24:41 AM"
 *                 
 ********************************************************************************/

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

#define LEN sizeof(struct node)
struct node
{
    int data;//存储数据
    struct node *next;//指向下一个节点
};

int n;//统计是第几个节点

struct node *creat()
{
    struct node *head;//头指针,指向第一个节点
    struct node *p1 = NULL;//p1保存创建的新节点的地址
    struct node *p2 = NULL;//p2保存原链表最后一个节点的地址

    n = 0;
    p1 = (struct node *)malloc(LEN);//新建一个节点
    p2 = p1;
    if(p1==NULL)//创建节点失败
    {
        printf("creat fail\n");
        return 0;
    }
    else
    {
        head = NULL;//头指针为空
        printf("please input %d node\n",n+1);
        scanf("%d",&(p1->data));//输入数据
    }
    while((p1->data)!=0)    //循环进行的条件
    {
        n = n + 1;//计算创建的节点数
        if(n==1)
        {
            head = p1;//head保存头结点的位置
            p2->next = NULL;//因为前面p1 = p2,而且现在只有一个节点,把next设置为空
        }

        else
        {

            p2->next = p1;//当不是第一个节点时,p2的next指向p1新创建的节点
        }

        p2 = p1;//p2保存p1的指向的节点,为p1创建新的节点做准备

        p1 = (struct node *)malloc(LEN);//p1创建新的节点
        printf("Please input %d node\n", n+1);
        scanf("%d", &(p1->data));//向新的节点输入数据
    }

    p2->next = NULL;//最后一个节点指向为空

    free(p1);//释放结束时p1申请的内存空间
    p1 = NULL;//避免p1成为野指针
    return head;//返回头指针
};


void print(struct node *head)
{
    struct node *p;
    p = head;

    printf("head is %o\n", head);
    do
    {
        printf("p is %o ,data is  %d, pnext is %o\n", p, p->data, p->next);//打印节点的地址,数据,下一个节点的地址
        p = p->next;//p指向下一个节点

    }while(p != NULL);
};

int destroy(struct node *head)
{
    struct node *p;//定义结构体指针
    if(head==NULL)//如果链表不存在则返回0
    {
        return 0;
    }
    while(head != 0)//如果存在则进行摧毁,直到head为空,所有节点被销毁
    {
        p = head->next;//把head指向的下一个节点被P保存
        free(head);//释放掉head指向的节点
        head = p;//把P保存的节点被head保存
    }

 make4.c                                                                                                                            
};
int clear(struct node *head)
{
    struct node *p;//定义结构体指针
    struct node *q;
    if(head == 0)
    {
        return 0;
    }
    p = head->next;//把头节点的下一个节点被p保存
    while(p != 0)//当p存在时,进行清空操作
    {
        q = p->next;//使q保存p指向的下一个节点
        free(p);//释放掉P里的内容
        p = q;//让p保存q指向的节点
    }
    head->next = NULL;//当上面循环完成时,已经只有一个头结点存在,使head->next=NULL,表示链表结束
 };

int main(void)
{
    struct node *head;
    head = creat();//创建链表
    print(head);//打印链表信息
    destroy(head);摧毁链表
    //clear(head);//清空链表
    print(head);检查摧毁或清空的效果

}

摧毁结果


[fanmaolin@Centeros lianbiao]$ gcc make4.c     
[fanmaolin@Centeros lianbiao]$ ./a.out         
please input 1 node
1
Please input 2 node
2
Please input 3 node
3
Please input 4 node
4
Please input 5 node
5
Please input 6 node
0
head is 155540020
p is 155540020 ,data is  1, pnext is 155540060
p is 155540060 ,data is  2, pnext is 155540120
p is 155540120 ,data is  3, pnext is 155540160
p is 155540160 ,data is  4, pnext is 155540220
p is 155540220 ,data is  5, pnext is 0
head is 155540020
p is 155540020 ,data is  28754080, pnext is 155540060
p is 155540060 ,data is  28753920, pnext is 155540120
p is 155540120 ,data is  28753952, pnext is 155540160
p is 155540160 ,data is  28753984, pnext is 155540220
p is 155540220 ,data is  28754016, pnext is 0

可以清楚的看到,摧毁链表后数据已经变为垃圾数据,链表不能使用

清空效果


[fanmaolin@Centeros lianbiao]$ gcc make4.c     
[fanmaolin@Centeros lianbiao]$ ./a.out     
please input 1 node
1
Please input 2 node
2
Please input 3 node
3
Please input 4 node
4
Please input 5 node
5
Please input 6 node
0
head is 33470020
p is 33470020 ,data is  1, pnext is 33470060
p is 33470060 ,data is  2, pnext is 33470120
p is 33470120 ,data is  3, pnext is 33470160
p is 33470160 ,data is  4, pnext is 33470220
p is 33470220 ,data is  5, pnext is 0
head is 33470020
p is 33470020 ,data is  1, pnext is 0

可以看到清空链表后,仅仅只有表头存在,依然可以进行插入等操作。

总结:

关于摧毁链表后依然可以根据头指针找到后面链表的地址

首先,我们虽然free()掉了,但是在没有其他人使用那块地址时,指针依然指向那块地址。假设你是新生时学校给你分配了宿舍,你一直记得,等你毕业离开时宿舍依旧存在,你也记得宿舍,但是你现在不能住了。

发现一个vi编辑器的小技巧,:set nonumber可以删除代码前的序号,U撤回之前的操作

参考链接:http://blog.youkuaiyun.com/bzhxuexi/article/details/41721429

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值