链表

Posted by lily on April 7, 2023

一、链表知识总结 二、链表做题心得

链表定义

class LinkNode(self, val=None):
#   self表示创建的对象自身,定义了对象自带的属性和方法
    self.val = val
    self.next = None
# 实例化链表并用头插法添加元素
# 已存在头节点
head = LinkNode(val1)
def createLink_head(val):
    node = LinkNode(val)
    head.next = node
    # 把头节点往下移动继续添加
    head = node

链表的增删改操作

# 为了方便对头节点进行删除或增加操作,增加一个虚拟头节点
dummy_head = LinkNode(next=head)
# 虚拟头节点也是链表节点类的一个,下一个引用指向头节点
new_node = LinkNode(val=3)
# 索引值是从0开始的,添加到索引值为3的位置上
posi = 3
for i in range(posi):
    dummy = dummy.next
new_node.next = dummy.next
dummy.next = new_node

链表的反转

  1. 不必再新开空间存放新链表
  2. 只需要每个链表里的两两节点进行反转,遍历到最后,所有节点都反转完毕
  3. IMG_0122.PNG
  4. 递归解决链表反转

IMG_0036.jpeg IMG_0038.jpeg

def reverseLinkList(head):
    if not head or not head.next:
        return head
    tail = reverseLinkList(head.next)
    head.next.next = head
    head.next = None
    return tail
  1. 链表的赋值问题:

IMG_0041.jpeg


链表题知识总结

  1. 循环关系

逻辑关系: while + if: 循环直到if条件不成立 while : if: else: 进入循环若if不成立则进行else操作,循环直到while条件不成立

  1. 数学方法解决链表寻找链表环入口问题
  2. 递归算法的应用
    1. 大问题可以被拆分为有限个小问题
    2. 每一层的解决方法相同
    3. 存在最小的子问题
    4. 1⃣️在递进的过程中解决小问题(代码写在调用自我函数之前,动作在“递”之前发生)
    5. 2⃣️在返归的过程中解决问题(代码写在调用函数之后,边归边解决问题)
  3. 解决链表反转时tail值不变问题
    1. 输出发现tail值一直不变
      # 递归解法, 头节点为head,传入一个head参数为ListNode类
      def reverseLinkList(head):
       if not head or not head.next:
        return head
      # print('before')
       tail = reverseLinkList(head.next)
       #
       print("tail:", tail.val,end=',')
       #
       head.next.next = head
       head.next = None
       print("head:", head.val,end=',')
       return tail
      # 输出结果
      tail: 7,head: 6,tail: 7,head: 5,tail: 7,head: 4,tail: 7,head: 3,tail: 7,head: 2,tail: 7,head: 1,
      
    2. 为什么每一轮tail的值都相同 ①当递归到最后一层时返回值为尾tail=尾节点值, ②最后一层递归的最后一行又有一个返回值tail,相当于把tail赋给之后的每一层递归值,所以tail的值不变
    3. Ⅱ为什么head的值会改变 因为head在每一层递归调用中都被赋了一个不同的值, 所以返回之时head的每一层的值也都不同, 所以每次进行两两之间的反转操作都在不同的节点之间

寻找链表中点

快慢指针法