美文网首页
Python数据结构-链表(Linked List)

Python数据结构-链表(Linked List)

作者: ShowMeCoding | 来源:发表于2021-12-24 22:40 被阅读0次

    链表(Linked List):一种线性表数据结构。它使用一组任意的存储单元(可以是连续的,也可以是不连续的),来存储一组具有相同类型的数据。

    我们先来简单介绍一下链表结构的优缺点:

    • 优点:存储空间不必事先分配,在需要存储空间的时候可以临时申请,不会造成空间的浪费;一些操作的时间效率远比数组高(插入、移动、删除元素等)
    • 缺点:不仅数据元素本身的数据信息要占用存储空间,指针也需要占用存储空间,链表结构比数组结构的空间开销大

    双向链表(Doubly Linked List):链表的一种,也叫做双链表。它的每个链节点中有两个指针,分别指向直接后继和直接前驱。

    循环链表(Circular linked list):链表的一种。它的最后一个链节点指向头节点,形成一个环。

    链表的实现与基本操作

    # 链节点以及链表的结构定义
    class ListNode:
        def __init__(self, val=0, next=None):
            self.val = val
            self.next = next
    
    class LinKList:
        def __init__(self):
            self.head = None
    
    # 建立一个线性链表
    def create(self, data):
        self.head = ListNode(0)        # 头节点
        cur = self.head                # 当前节点
        for i in range(len(data)):
            node = ListNode(data[i])
            cur.next = node
            cur = cur.next
    
    # 求线性链表的长度
    def length(self):
        count = 0
        cur = self.head
        while cur:
            count += 1
            cur = cur.next
        return count
    
    # 查找元素
    def find(self, val):
        cur = self.head
        while cur:
            if cur.val == val:
                return cur
            cur = cur.next
        # 查找无结果
        return None
    
    # 链表头部插入元素
    def insertFront(self, val):
        # 创建一个值为val的链节点
        node = ListNode(val)    
        # 将node节点指向头节点
        node.next = self.head
        # 将链表的头节点head指向node
        self.head = node
    
    # 链表尾部插入元素
    def insertRear(self, val):
        node = ListNode(val)
        cur = self.head
        while cur:
            cur = cur.next
        # 将链表的尾节点指向node
        cur.next = node
    
    # 链表中间插入元素
    def insertMiddle(self, index, val):
        count = 0
        cur = self.head
        # 找到待插入位置的前一个链表节点
        while cur and count < index - 1:
            count += 1
            cur = cur.next
        if not cur:
            return 'Error'
        # 先将待插入节点与后节点相连,然后前节点与插入节点相连
        node = ListNode(val)
        node.next = cur.next
        cur.next = node
    
    # 改变元素
    def change(self, index, val):
        count = 0
        cur = self.head
        while cur and count < index:
            count += 1
            cur = cur.next
        if not cur:
            return 'Error'
        # 直接赋值
        cur.val = val
    
    # 删除链表头部的元素
    def removeFront(self):
        if self.head:
            self.head = self.head.next
    
    # 删除链表尾部的元素
    def removeRear(self):
        # 对于一个节点的链表
        if not self.head.next:
            return 'Error'
    
        cur = self.head
        while cur.next.next:
            cur = cur.next
        cur.next = None
    
    # 删除链表中间位置的元素
    def removeMiddle(self, index):
        count = 0
        cur = self.head
    
        while cur.next and count < index - 1:
            count += 1
            cur = cur.next
        if not cur:
            return 'Error'
        
        del_node = cur.next
        cur.next = del_node.next
    
    707. 设计链表

    MyLinkedList linkedList = new MyLinkedList();
    linkedList.addAtHead(1);
    linkedList.addAtTail(3);
    linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3
    linkedList.get(1); //返回2
    linkedList.deleteAtIndex(1); //现在链表是1-> 3
    linkedList.get(1); //返回3

    class ListNode:
        def __init__(self, x):
            self.val = x
            self.next = None
    
    class MyLinkedList:
    
        def __init__(self):
            self.size = 0
            self.head = ListNode(0)
    
        # 获取链表元素
        def get(self, index: int) -> int:
            if index < 0 or index >= self.size:
                return -1
            cur = self.head
            for _ in range(index+1):
                cur = cur.next
            return cur.val
    
        # 头节点插入
        def addAtHead(self, val: int) -> None:
            self.addAtIndex(0, val)
    
        # 尾节点插入
        def addAtTail(self, val: int) -> None:
            self.addAtIndex(self.size, val)
    
        # 指定位置插入元素
        def addAtIndex(self, index: int, val: int) -> None:
            if index > self.size:
                return
            if index < 0:
                index = 0
            # 链表长度加1
            self.size += 1
            pre = self.head
            for _ in range(index):
                pre = pre.next
            # 插入的节点
            addNode = ListNode(val)
            addNode.next = pre.next
            pre.next = addNode
    
        def deleteAtIndex(self, index: int) -> None:
            if index < 0 or index >= self.size:
                return
            self.size -= 1
            pre = self.head
            for _ in range(index):
                pre = pre.next
            # 需要删除index位置的元素
            pre.next = pre.next.next
    
    206. 反转链表

    输入:head = [1,2,3,4,5]
    输出:[5,4,3,2,1]

    • 使用迭代
    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    
    class Solution:
        def reverseList(self, head: ListNode) -> ListNode:
            prev = None
            cur = head
            while cur:
                next = cur.next     # 第三个节点
                cur.next = prev     # 第二个节点指向第一个节点
                prev = cur          # 前一个节点 prev 移动到当前节点
                cur = next          # 当前节点继续向后遍历到 next 位置(遍历当前节点)
            return prev             # 最后返回新的头节点
    
    • 使用递归
    class Solution:
        def reverseList(self, head: ListNode) -> ListNode:
            if not head or not head.next:   #递归终止条件
                return head
            p = self.reverseList(head.next)
            # A --> B --> C(none)   ==> B --> A --> C(none)
            head.next.next = head
            head.next = None
            return p
    
    203. 移除链表元素

    输入:head = [1,2,6,3,4,5,6], val = 6
    输出:[1,2,3,4,5]

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    
    class Solution:
        def removeElements(self, head: ListNode, val: int) -> ListNode:
            # 链表初始化头节点
            newNode = ListNode(0, head)
            newNode.next = head
    
            prev = newNode       # 头节点
            cur = head
            while cur:
                if cur.val == val:
                    prev.next = cur.next
                    cur = cur.next
                else:
                    prev = prev.next
                    cur = cur.next
            return newNode.next
    

    相关文章

      网友评论

          本文标题:Python数据结构-链表(Linked List)

          本文链接:https://www.haomeiwen.com/subject/kgmevltx.html