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

2021-12-24  本文已影响0人  ShowMeCoding

链表(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
上一篇 下一篇

猜你喜欢

热点阅读