数据结构 2. 链表

一、链表

借鉴[https://blog.csdn.net/dzysunshine/article/details/88041673]

1.实现单链表、循环链表、双向链表,支持增删操作

class LNode:   # 定义节点类
    def __init__(self, elem, next_=None):
        self.elem = elem
        self.next = next_
        
class LList:   # 定义单链表类
    def __init__(self):
        self._head = None

    # 增,包括链表头、尾和中间位置三种方法
    def prepend(self, elem):
        self._head = LNode(elem)

    def append(self, elem):
        if not self._head:
            self._head = LNode(elem)
            return
        p = self._head
        while p.next:
            p = p.next
        p.next = LNode(elem)

    def insert(self, elem, key):
        tmp = LNode(elem)
        p = self._head
        for i in range(key-1):
            p = p.next
        tmp.next = p.next
        p.next = tmp

    # 删,也是三种方法
    def delete(self, key):
        # todo: key边界限制待添加
        p = self._head
        for i in range(key - 1):
            p = p.next
        p.next = p.next.next

    def print_all(self):
        p = self._head
        while p :
            print(p.elem, end='')
            if p.next:
                print('->', end='')
            p = p.next
        print('')


class CList:   # 定义循环链表类
    def __init__(self):
        self._head = LNode(None)
        self._head.next = self._head
        self._rear = self._head

    def insert(self, key, value):
        tmp = LNode(elem)
        p = self._head
        for i in range(key-1):
            p = p.next
        tmp.next = p.next
        p.next = tmp
        if tmp.next == self._head:
            self._rear = tmp

    def delete(self, key):
        # todo:key边界
        p = self._head
        for i in range(key-1):
            p = p.next
            if not p:
                print('WRONG POSITION!')
                return 
        tmp = p.next
        p.next = p.next.next
        del tmp
        if p.next ==self._head:
            self._rear = p

class DLNode(LNode):   # 定义双链表节点
    def __init__(self, elem, next_=None, prev=None):
        super(DLNode, self).__init__()
        self.prev = prev

if __name__ == '__main__':
    l = LList()
    for i in range(10):
        l.append(i)
    l.print_all()
    l.insert(50, 3)
    l.print_all()
    l.delete(10)
    l.print_all()

2.实现单链表反转

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        prev = None
        cur = head
        while cur:
            nxt = cur.next
            cur.next = prev
            prev = cur
            cur = nxt
        return prev

3.实现两个有序的链表合并为一个有序链表

class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        l3 = ListNode(0)#空链表
        cur = l3
        while (l1 != None) & (l2!=None):
            if l1.val <= l2.val:
                cur.next = l1
                l1 = l1.next
            else:
                cur.next = l2
                l2 = l2.next
            cur = cur.next
        if l1 != None:
            cur.next = l1
        if l2 != None:
            cur.next = l2
        l3 = l3.next
        return l3

4.实现求链表的中间结点

def find_middle_node(head):
    slow, fast = head, head
    while fast and fast.next:
        fast = fast.next.next
        slow = slow.next
    return slow

练习

141. 环形链表

[https://leetcode-cn.com/problems/linked-list-cycle/submissions/]
题目描述

给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

示例 1:

输入:head = [3,2,0,4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

3
2
0
4

示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

1
2

示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

1

解题思路
设定快慢指针,快指针每次跨越两格,慢指针每次跨越一格,如果两个指针有重合的时候,该链表就存在环。

代码实现

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        fast = slow = head
        while slow and fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow is fast:
                return True
        return False
        

23. 合并K个排序链表

[https://leetcode-cn.com/problems/merge-k-sorted-lists/comments/]
题目描述

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6

代码实现

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        r, n, p = [], lists and lists.pop(), None
        while lists or n: r[len(r):], n = ([n], n.next or lists and lists.pop()) if n else ([], lists.pop())
        for n in sorted(r, key=lambda x: x.val, reverse=True): n.next, p = p, n
        return n if r else []
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值