自学数据结构之链表(Python)

基础链表题目汇总:

1.什么是链表:

单链表

链表不同于数组,数组的存储需要一整块连续的内存空间

链表是通过“指针”(或是索引)将内存块串联起来,内存空间不连续


2.链表的个常规操作:

1. 单链表反转:

示例:
单链表的反转


方法一:三指针循环反转:
思路:三指针分别代表首节点为p,次结点为q,未遍历的结点值为r,遍历单链表,三指针相互反转

便于理解版:


def reverseLinkTree(head):
    if head == None:
        return None
    # 定义两个指针一前一后:
    p = head
    q = head.next
    # p指针反转指向空结点
    p.next = None
    while q:
        # r代表剩下的未反转的结点值
        r = q.next
        # q指针反转指向p
        q.next = p
        p = q
        # p、q位置后移
        q = r
    return p

代码简化版:

def Let_reverseLinkTree(head):
if not head:
    return None
p, q, p.next = head, head.next, None
while q:
    q.next, p, q = p, q, q.next
return p

方法二:双指针反转法:
思路:双指针分别代表首节点为cur,空结点为pre,遍历单链表,两指针前后反转
def leet_reverseLink(head):
    if not head:
        return None
    cur = head
    pre = None
     # cur, pre = head, None
    while cur:
        cur.next = pre
        pre = cur
        cur = cur.next
        # cur.next, pre, cur = pre, cur, cur.next
    return pre

方法三:尾指针插入法:
思路:保持头指针不动,遍历链表。从后向前插入到次指针位置,当指针遍历结束后,将首指针放到末尾处

便于理解版:

def reverseLinkTail(head):
    if head == None or head.next == None:
        return head
     # 从次指针开始
    cur = head.next
    while cur.next:
        pre = cur.next
        cur.next = pre.next
        pre.next = head.next
        head.next = pre
    # 将头结点移到尾部
    cur.next = head
    head = head.next
    cur.next.next = None
    return head

代码简化版:

def Let_reverseLinkTail(head):
    if not head or not head.next:
        return head
    cur = head.next
    while cur.next:
        pre = cur.next
        cur.next, pre.next, head.next = pre.next, head.next, pre
    p.next, head, p.next.next = head, head.next, None
    return head

方法四:递归法:
思路:将单链表的反转,看作head和head.next之间的反转,循环往复
def rec_reverseLink(head):
    if not head or not head.next:
        return head
    new_head = rec_reverseLink(head.next)
    head.next.next = head
    head.next = None
    return new_head

2. 链表中的环检测

示例:

在这里插入图片描述

方法一:字典查重法
思路:创建空字典,遍历单链表,加入字典,如果结点值已出现在字典中,就证明有环
def dist_checkLink(head):
    if not head:
        return False
    cur = head
    res = {}
    while cur.next:
        if cur in res:
            return True
        res[cur] = cur.val
        cur = cur.next
    return False


方法二:快慢双指针法
思路:
1.快慢指针同处于首节点上,让快指针走两步,慢指针走一步。
2.比较两个指针,当指针相等时,证明有环
def double_checkLink(head):
    if not head or head.next:
        return False
    fast = slow = head
    while fast.next and fast.next.next:
        fast = fast.next.next
        slow = slow.next
        if fast == slow:
            return True
    return False

3. 两个有序的链表合并

示例:
两个有序链表的合并


方法一:迭代法
思路:创建一个新链表,遍历两个链表,一一比较大小排序,放入新链表中
def mergeLink(l1: ListNode, l2: ListNode):
    head = ListNode(0)
    cur = head
    while l1 and l2:
        if l1.val <= l2.val:
            cur.next = l1
            l1 = l1.next
        else:
            cur.next = l2
            l2 = l2.next
        cur = cur.next
    # cur.next = l1 if l1 else l2
    if l1:
        cur.next = l1
    elif l2:
        cur.next = l2
    return head.next


方法二:递归法
思路:
1.比较两个链表中最小的头结点,让他和剩下的节点的递归结果,进行合并。
2.设置递归条件,也就是最小问题的返回结果。
def recursiveLink(l1: ListNode, l2: ListNode):
    if not l1:
        return l2
    if not l2:
        return l1
    if l1.val < l2.val:
        l1.next = recursiveLink(l1.next, l2)
        return l1
    else:
        l2.next = recursiveLink(l2.next, l1)
        return l2


4. 删除链表倒数第n个结点

示例:
删除指定结点


方法:快慢双指针法
思路:
1.快慢指针同处于首节点上,先让快指针走n步。
2.再让慢指针走,等到快指针走到末尾,慢指针正好走到第K个结点上,删去该结点
def delete_link(head, n):
    cur = ListNode(0)
    cur.next = head 
    # 快指针先走n步
    slow = fast = cur
    for _ in range(n):
        fast = fast.next 
    # 快慢指针同时走,fast指针到达尾部节点,slow到达倒数第N个节点的前一个节点
    while fast and fast.next:
        slow, fast = slow.next, fast.next 
    # 删除节点
    slow.next = slow.next.next 
    return cur.next 


5. 求链表的中间结点

示例:
在这里插入图片描述


方法:列表查找法
思路:
1.新建空列表,遍历链表,将结点值放入列表
2.最后使用列表的len()//2方法找到中间值
def midLink(head):
    if not head:
        return [head.val]
    cur = head
    new_list = []
    while cur:
        new_list.append(cur.val)
        cur = cur.next
    return new_list[len(new_list) // 2:]


搞懂这五个常规操作,链表就不会蒙圈了!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值