当我们不打算使用这个单链表时,我们需要把它销毁,其实也就是在内存中将它释放掉,以便于留出空间给其他程序或软件使用。
    单链表整表删除的算法思路如下:
    1.声明一指针p和q;
    2.将第一个结点赋值给p;
    3.循环:

    • 将下一结点赋值给q;
    • 释放p;
    • 将q赋值给p。

    实现代码算法如下:

    1. /* 初始条件:顺序线性表L已存在,操作结果:将L重置为空表 */
    2. //L是二级头指针,*L是一级头指针
    3. Status ClearList(LinkList *L)
    4. {
    5. LinkList p, q;
    6. /* p指向第一个结点 */
    7. p = (*L)->next;//*L->next是(头结点的后继,首结点,第一数据结点)的地址,所以一级指针p指向首结点
    8. /* 没到表尾 */
    9. while (p)
    10. {
    11. q = p->next;//当p为尾结点的时候,q = p->next = NULL
    12. free(p);
    13. p = q;//p = NULL
    14. }
    15. /* 头结点指针域置为空 */
    16. (*L)->next = NULL;
    17. return OK;
    18. }

    这段算法代码里,常见的错误就是有同学会觉得q变量没有存在的必要。
    在循环体内直接写free(p); p = p->next;即可。可这样会带来什么问题?
    要知道p指向一个结点,它除了有数据域,还有指针域。你在做free(p);时,其实是在对它整个结点进行删除和内存释放的工作。

    这就好比皇帝快要病死了,却还没有册封太子,他儿子五六个,你说要是你脚一蹬倒是解脱了,这国家咋办,你那几个儿子咋办?这要是为了皇位,什么亲兄弟血肉情都成了浮云,一定会打起来。所以不行,皇帝不能马上死,得先把遗嘱写好,说清楚,哪个儿子做太子才行。

    而这个遗嘱就是变量q的作用,它使得下一个结点是谁得到了记录,以便于等当前结点释放后,把下一结点拿回来补充。明白了吗?
    好了,说了这么多,我们可以来简单总结一下。