程序员数据结构与算法IOS

数据结构基础--链表

2018-11-28  本文已影响15人  kirito_song

目录


基本性质

  1. 数组是物理地址上一段连续的存储空间。
    可以通过下标直接获取元素
    当内容超出容量时需要重新定义数组。
  2. 链表空间不一定保持联系,为临时分配的。
    只能从链表的头部开始一个一个查找
    增删的效率高于数组,因为不需要更改内存结构

链表的分类

  1. 单链表
    每个节点只能通过next指针,指向下一个节点。
  2. 双链表
    除了next指针之外,还有一个prev指针指向其上一个节点。
  1. 普通链表
    头无prev,尾无next。
  1. 循环链表
    首尾相接的链表。
    最后一个节点的next指针指向其第一个节点
    对于双链表,其第一个节点的prev指针指向最后一个节点。



链表问题代码实现的关键点

链表在调整过程中往往遇到改变头部的情况,如果头节点被改变则需要返回一个新头部。

注意那些指针变化了,同时注意对前后节点的影响。

头节点,尾节点,空节点的特殊处理。


链表插入和删除的注意事项

取得前后节点,将前节点的next指向新节点,新节点的next指向后节点。

取得前后节点,将前一个节点的next指针指向后一个节点。

在逻辑的设计上应该考虑空节点的情况


链表翻转

已翻转的头节点head,下一个节点now

  1. 将now节点的next指向head
  2. 将now节点设置为已翻转部分的新head

需要注意在执行1,2步骤之前需要一个变量来储存原now节点的next节点。
步骤2设置了新的head之后,将该节点作为新的now,继续翻转。


向一个有序的环境链表中插入一个节点,并保持依旧有序。

要求时间复杂度O(N),额外空间复杂度O(1)。

让新节点node自己成为环形链表,并返回node即可。

令变量prve设为头节点,current设为第二个节点,两个节点同步移动。


对于一个单链表,在不给定head的情况下删除指定node。要求时间复杂度O(1)

如果工程允许,可以将node.next的内容copy到node节点上,变相的删除了node节点的数据。

无法删除


给定一个链表,与一个数组num。要求实现荷兰国旗


给定两个有序链表的head,打印共同部分


给定一个单链表的head,实现一个调整链表的函数,使得每K个节点之间逆序,如果最后不足K个,则不调整。

  1. 链表为空,长度<k或者k<2
    直接返回
  1. 需要保留上次逆序的最后一位元素,修改其next。
  2. 最后段不足k个,直接不修改。值将上次逆序的最后一个元素next设置好。
  3. 第一组的第一个节点为头节点。

判断一个链表是否为回文结构

  1. 将链表节点依次入栈,在弹出时与原链表依次比对。

  2. 使用快行指针,通过二倍速的方式遍历。依次将慢指针的节点压入栈中,当快节点遍历到末尾时,慢指针正好处于中间位置。
    继续移动慢指针,并与栈中弹出的元素做对比。(需要注意总量的奇偶)


  3. 将后半部分链表进行逆序处理,从两端同时进行遍历比对



判断一个单链表是否有环,如有则返回入环节点。时间复杂度O(N),额外空间复杂度O(1)

如果不要求额外空间复杂度,可以直接用哈希表比对。

如果两指针相遇则表示有环,此时将快指针改为1,并从head重新同步移动,相遇处即为入环位置或者还有另一个证明


两个无环单链表是否相交,时间复杂度O(N+M),额外空间复杂度O(1)

先遍历两个链表确定长度,然后另长链表从短链表开始位置与短链表再次同步遍历,查看是否相同。



判断两个有环单链表是否相交,时间复杂度O(N+M),额外空间复杂度O(1)

首先都需要先去定单独的入环节点,然后

  1. 是否入环之前已经相交


  2. 是否入环时才相交,则入环位置节点相同


  3. 循环其中一个环,若遇到另一个的入环节点则返回。


  4. 否则,两链表并未相交


判断两个链表是否相交,并返回第一个相交的节点

  1. 尝试找到各自的入环节点

  2. 若一个有环一个无环,则不相交

  3. 若都为无环,则按照上文《两个无环单链表是否相交》的方式查找

  4. 若都为有环,则按照上文《判断两个有环单链表是否相交》的方式查找


参考资料

左神牛课网算法课

上一篇 下一篇

猜你喜欢

热点阅读