zoukankan      html  css  js  c++  java
  • 数据机构与算法学习(四)- 链表

    数组和链表是两个非常基础、非常常用的数据结构。

    两者的区别:从底层的存储结构来看,数组需要一块连续的内存空间来存储,对内存的要求比较高。而链表恰恰相反,它并不需要一块连续的内存空间,它通过“指针”将一组零散的内存块串联起来使用。

    三种常见的链表结构:单链表、双链表和循环链表。

    单链表

    概念定义:

    我们把内存块称为链表的节点。记录下一个节点的指针叫做后继指针next。把第一个节点叫做头节点。把最后一个节点叫做尾节点

    插入、删除数据操作,只需要考虑相邻节点的指针改变,对应的事件复杂度为 O(1).由于链表的特点随机访问就不是很高效了,需要进行遍历,时间复杂度为O(n).

    循环链表

    循环链表是一种特殊的单链表。与单链表唯一的区别就在尾节点。单链表指向空,循环链表指向头节点。优点是从链尾到链头比较方便。当腰处理的数据具有环型结构特点时,就特别适合采用循环链表,比如著名的约瑟夫问题。

    双向链表

    支持两个方向,每个节点的指针不止有一个后继指针next,还有一个前驱指针prev指向前面的节点。双向链表可以支持O(1)的时间复杂度的情况下找到前驱节点。

    删除操作:第一种, 删除节点中“值等于某个给定值”的结点; 这种情况的单链表与双链表都要做遍历O(n)的时间复杂度。第二种,删除给定指针指向的结点。这种情况对于单链表双链表就比较有优势了,单链表需要重新遍历 而双链表不需要。

    插入操作亦是如此。这是一种用空间换时间的设计思想。双链表需要两个指针,空间占用较大。

    链表代码的写作技巧

    技巧一:理解指针或引用的含义

    将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向了这个变量,通过指针就能找到这个变量。

    技巧二:警惕指针丢失和内存泄漏

    插入节点或者删除节点时,一定要注意操作的顺序。

    删除节点时,也一定要记得手动释放内存空间。

    技巧三:利用哨兵简化实现难度

    单链表的插入

    new_node->next = p->next;
    p->next = new_code;

    如果向一个空链表中插入第一个节点,上面的逻辑不能用了,需要特殊处理。

    if(head == null){
        head = new_code;
    }

    删除节点

    p->next = p->next->next;

    如果删除的是最后一个节点,需要特殊处理。

    if(head->next == null){
        head = null;
    }

    可以看出, 针对链表的插入、删除操作,需要对插入第一个节点和删除最后一个节点的情况进行特殊处理。这样的代码实现起来就会很繁琐不简洁,而且也容易因为考虑不全而出错。如何来解决这个问题呢?

    这里引入哨兵来解决问题。如果我们引入哨兵节点,在任何时候,不管链表是不是空,head指针都会一致指向这个哨兵节点。我们也把这种有哨兵节点的链表叫带头链表,相反,没有哨兵节点的链表就叫做不带头链表。哨兵节点一致存在,所以插入第一个节点和插入其他节点,删除最后一个节点和删除其他节点,都可以统一为相同的代码实现逻辑了。

    技巧四:重点留意边界条件处理

    • 如果链表为空时,代码能正常工作?
    • 如果链表只包含一个节点时,代码能否正常工作?
    • 如果链表只包含两个节点时,代码能够正常工作?
    • 代码逻辑在处理头节点和尾节点的时候,能否正常工作?

    技巧五:举例画图,辅助思考

    使用举例法和画图法。将它画在纸上,把各种情况都举一个例子,画出来。

    技巧六:多写多练,没有捷径

    把一下几个操作都能写熟练。

    • 单链表反转
    • 链表中环的检测
    • 两个有序的链表合并
    • 删除链表倒数第n个节点
    • 求链表的中间节点
  • 相关阅读:
    通过PMP了
    VBA之自动建立连接
    从头学SQL Server2005之一:数据库引擎体系结构
    SMP、NUMA、MPP体系结构介绍【转】
    将Windows2003的RDP客户端管理应用于XP
    VBA中简单修改原有公式的宏
    各种Excel VBA的命令
    领导和管理的区别在哪里?【转】
    COM(VB/VBA/Script)利用服务标记调用WCF服务之四:使用配置文件
    2009年第一篇日志
  • 原文地址:https://www.cnblogs.com/OneSky-Mi/p/14389378.html
Copyright © 2011-2022 走看看