• 数据结构(王卓)(4)附:链表的销毁与清空


    目录

    销毁

    运行逻辑:

    另外,如果我们在输入的时候,输入一个链表Lnode类型进去:

    清空(只销毁内容)

    project 1:(其实只是对销毁链表的生搬硬套的照抄,并且里面还缺少了while语句的循环)

    project 2:

    project 3:

    project 4: 

    project 5: 

    project 6: 

    project 7: 最终成品版本

    问题:

    原因:


    位置:PPT第二章:118


    销毁

    1. Status 销毁单链表(LinkList L)
    2. {
    3. LinkList p;
    4. while (L)
    5. {
    6. p =L;
    7. L->next;
    8. delete p;
    9. }
    10. return OK;
    11. }

    运行逻辑:

    (1):设定一个指针,让指针指向链表的头指针L

    (2):让头指针等于头指针里面指向下一结点的结点内部指针next

    (保存了头指针.next(L.next),即下一个结点的地址)

    此时L的值为下一个结点的地址

    (3):删除这个我们设定的指针

    这个我们设定的指针此时就是链表中的第一个结点的地址(头指针)

    这一操作在我们的记录里删除了头结点的地址

    与此同时里面存储的变量自然也没有内存空间存储了(该内容的内存空间区域都没了你还存啥)自然也就一同(一起)被释放,于是这个整一节点都被清除

    然后再进入下一轮(头指针记为当前之后的第一个节点的地址,然后再释放这一结点,逐个清除)

    ......

    最终:

    L指向下一指针a(n);

    删除结点a(n-1);

    指针p指向a(n);

    p指向a(n).next=^(空);

    删除

    结点a(n);

    注:头指针,头结点,首元结点:

    位置:PPT第二章:94


    另外,如果我们在输入的时候,输入一个链表Lnode类型进去:

    1. Status 销毁单链表(LinkList& L)
    2. {
    3. //判断链表是否为空
    4. if (链表是否为空(L))
    5. {
    6. cerr << "empty List!" << endl;
    7. return false;
    8. }
    9. while (L)//链表还未到达尾端
    10. {
    11. Lnode* temp;
    12. temp = *&L;
    13. L = L->next;
    14. delete temp;
    15. }
    16. return true;
    17. }

    或者:

    1. Status 销毁单链表(LinkList& L)
    2. {
    3. //判断链表是否为空
    4. if (链表是否为空(L))
    5. {
    6. cerr << "empty List!" << endl;
    7. return false;
    8. }
    9. while (L)//链表还未到达尾端
    10. {
    11. auto temp = L->next;//将头指针指向下一个结点
    12. delete L;
    13. L = temp;
    14. }
    15. return true;
    16. }

    清空(只销毁内容)

    project 1:(其实只是对销毁链表的生搬硬套的照抄,并且里面还缺少了while语句的循环)

    1. Status 清空链表(Lnode *&L)
    2. {
    3. if (链表是否为空(L))
    4. cerr << "链表为空" << endl;
    5. auto temp = *&L;
    6. L = L->next;
    7. delete (*temp);
    8. }

    project 2:

    1. Status 清空链表(LinkList L)
    2. {
    3. if (链表是否为空(L))
    4. cerr << "链表为空" << endl;
    5. while (L)
    6. {
    7. auto temp = L;
    8. delete L->data;
    9. L = L->next;
    10. }
    11. }

    结果他说清空链表是指清空中间的所有结点,但是保留头结点(也包括头指针)(为空)

    而不是清空链表中每一结点存储的数据内容,remake:


    project 3:

    1. Status 清空链表(LinkList L)
    2. {
    3. if (链表是否为空(L))
    4. cerr << "链表为空" << endl;
    5. while (L)
    6. {
    7. auto temp = L->next;
    8. delete L;
    9. L = temp;
    10. }
    11. }

    整个程序运行的流程逻辑链路还是没有完成闭环


    project 4: 

    1. Status 清空链表(LinkList L)
    2. {
    3. if (链表是否为空(L))
    4. cerr << "链表为空" << endl;
    5. while (L)
    6. {
    7. auto temp = L->next;
    8. L = temp;
    9. L = L->next;
    10. delete temp;
    11. }
    12. }

    注意:在这里,我们不能再用L来指向第二个节点的地址,因为如果这样(使)用:

    第一轮:

    (1):temp指向第一个结点

    (2):L指向第一个结点

    (3):L指向第二个节点

    (4):删除第一个节点

    第二轮:
    (1):temp指向第三个节点

    (2):L指向第三个节点

    (3):L指向第四个结点

    (4):删除第3个节点

    ......

    这样一来,第二个节点就没删掉;

    而且,因为一次跳两个,倒数第二个就未必给你跳(没机会了,后面没有了))


    project 5: 

    1. Status 清空链表(LinkList L)
    2. {
    3. if (链表是否为空(L))
    4. cerr << "链表为空" << endl;
    5. while (L)
    6. {
    7. auto temp1 = L->next;
    8. auto temp2 = temp1->next;
    9. delete temp1;
    10. temp1=temp2;
    11. }
    12. }

    但是我们编到这里我们肯定也知道,如果这样的话这个程序他就是一直在用L赋值

    这样到后面肯定是不行的,所以继续改进:


    project 6: 

    1. Status 清空链表(LinkList L)
    2. {
    3. if (链表是否为空(L))
    4. cerr << "链表为空" << endl;
    5. auto temp1 = L->next;
    6. while (temp1)
    7. {
    8. auto temp2 = temp1->next;
    9. delete temp1;
    10. temp1=temp2;
    11. }
    12. }

    最后别忘了,我们要的是一个空的头结点,并且在完成操作后,我们还需要返回一个操作成功执行的信号: 


    project 7: 最终成品版本

    1. Status 清空链表(LinkList L)
    2. {
    3. if (链表是否为空(L))
    4. cerr << "链表为空" << endl;
    5. auto temp1 = L->next;
    6. while (temp1)
    7. {
    8. auto temp2 = temp1->next;
    9. delete temp1;
    10. temp1=temp2;
    11. }
    12. L->next = NULL;
    13. return true;
    14. }

    最后:

    temp1指向a(n-1),temp2指向a(n);

    删除 a(n-1);

    temp1指向a(n);

    while(1)(通过)

    temp2指向a(n).next=^(空);

    删除 a(n);

    temp1也指向a(n).next=^(空);

    清空L->next;

    结束;


    问题:

    为什么(我们何必)还要再去设立一个新的变量temp2,我们直接去使用头结点L记录后面的地址不就完了吗?何必这么多此一举?

    1. Status 清空链表(LinkList L)
    2. {
    3. if (链表是否为空(L))
    4. cerr << "链表为空" << endl;
    5. auto temp1 = L->next;
    6. while (temp1)
    7. {
    8. L = temp1->next;
    9. delete temp1;
    10. temp1=L;
    11. }
    12. L->next = NULL;
    13. return true;
    14. }

    temp1指向a(n-1),L指向a(n);

    删除 a(n-1);

    temp1指向a(n);

    while(1)(通过)

    L指向a(n).next=^(空);

    删除 a(n);

    temp1也指向a(n).next=^(空);

    清空L->next;

    结束;

    最后头指针不是也被保留了并且清空了吗???为什么弹幕里说不可以,说这样就把第一个节点也销毁了???头指针L和头结点依然存在啊,只不过是内容和指向被清空而已啊?? 


    原因:

    头指针其实还需要指向头结点,如果用头指针L代替temp2的话,最后L也置为空

    也就是说这样的话, 最后我们的头指针L就没办法指向我们的头结点了,不符合题目给出的规定要求

  • 相关阅读:
    java设计模式(七)适配器模式(Adapter Pattern)
    Linux开发讲课18--- “>file 2>&1“ 和 “2>&1 >file“ 的区别
    STM32和ESP32哪个更适合初学者
    优炫软件董事长梁继良当选新一届北京市商会副会长
    深度学习 | Pytorch深度学习实践 (Chapter 10、11 CNN)
    如何在PPT中去除编辑密码?
    Jetpack Compose - Button按钮使用
    CGLIB源码易懂解析
    Spring Cloud灰度部署
    跟着野火从零开始手搓emWin(2)emWin 在 Windows 上仿真
  • 原文地址:https://blog.csdn.net/Zz_zzzzzzz__/article/details/128164072