python-链表-Linked_list_construciton-构建链表

本文介绍了一个双向链表的实现方法,包括如何设置头尾节点、插入和删除节点等核心功能。此外,还提供了查找特定值节点的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

构建链表,并完成一下功能:

  • 设置链表的头(head)和尾部(tail),也就是将其中的某个元素直接变成头和尾
  • 在一个节点的特定位置(前/后)插入一个node,或者在一个特定的位置插入节点,假设head节点的位置为1
  • 移除具有特定值的node
  • 搜索具有特定值的node

Solution

# 节点包括本身的值和前后关系
class Node:
    def __init__(self, value):
        self.value = value
        self.prev = None
        self.next = None
# 对于一个双向链表对象,只负责记录头尾信息。
# 要查看前后的邻居必须深入进去
class DoublyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None
#更改头部
#Time: O(1)|Space:O(1)
    def setHead(self, node):
        # 边界条件,头部是空的
        if self.head is None:
            self.head = node
            self.tail = node
            return
        #否则执行在当前节点的头部前方进行插入,使用self.insertBefore
        self.insertBefore(self.head, node)
#Time: O(1)|Space:O(1)
    #设定尾部
    def setTail(self, node):
        # 边界条件,尾部是空的,此时同步和尾部都是新来的这个节点
        if self.tail is None:
            self.setHead(node)
            return
        #如果不是空的,在当前的tail后方插入节点
        self.insertAfter(self.tail,node)
#Time: O(1)|Space:O(1)
    # 实现前方插入
    def insertBefore(self, node, nodeToInsert):
        #这里 nodeToInsert是我们将要用来进行插入的node
        if nodeToInsert == self.head and nodeToInsert == self.tail:
            return
        #否则先尝试移除这个已经存在的 nodeToInsert。如果存在
        self.remove(nodeToInsert)

        nodeToInsert.prev = node.prev
        nodeToInsert.next = node
        if node.prev is None:
            self.head = nodeToInsert
        else:
            node.prev.next = nodeToInsert
        node.prev = nodeToInsert

#Time: O(1)|Space:O(1)
    def insertAfter(self, node, nodeToInsert):
        if nodeToInsert == self.head and nodeToInsert == self.tail:
            return
        self.remove(nodeToInsert)
        nodeToInsert.prev = node
        nodeToInsert.next = node.next
        if node.next is None:
            self.tail = nodeToInsert
        else:
            node.next.prev = nodeToInsert
        node.next = nodeToInsert
#Time: O(position)|Space:O(1)
    def insertAtPosition(self, position, nodeToInsert):
        if position == 1:
            self.setHead(nodeToInsert)
            return
        node = self.head
        current_position = 1
        while node is not None and current_position != position:
            node = node.next
            current_position += 1
        if node is not None:
            self.insertBefore(node,nodeToInsert)
        else:
            self.setTail(nodeToInsert)
#Time: O(n)|Space:O(1)
    def removeNodesWithValue(self, value):
        node = self.head
        while node is not None:
            node_to_remove = node
            node = node.next
            if node_to_remove.value == value:
                self.remove(node_to_remove)
#Time: O(1)|Space:O(1)
    def remove(self, node):
        if node == self.head:
            self.head = self.head.next
        if node == self.tail:
            self.tail = self.tail.prev
        self.removeNodeBindings(node)
#Time: O(n)|Space:O(1)
    def containsNodeWithValue(self, value):
        node = self.head
        while  node is not None and node.value != value:
            node = node.next
        return node is not None
#Time: O(1)|Space:O(1)
    def removeNodeBindings(self,node):
        if node.prev is not None:
            node.prev.next = node.next
        if node.next is not None:
            node.next.prev = node.prev
        node.prev = None
        node.next = None

### show a linked list
    def draw_linked_list(self):
        delimeter = "<->"
        node = self.head
        while node is not None:
            if node.next is not None:
                print(node.value,end = delimeter)
                node = node.next
            else:
                print(node.value,end = '\n')
                return

linkList = DoublyLinkedList()
linkList.setHead(Node(1))
linkList.setTail(Node(6))
for i in reversed(range(2,6)):
    linkList.insertAfter(linkList.head,Node(i))
# linkList.insertAfter(linkList.head,Node(2))
# linkList.insertAfter(Node(1),Node(2))
# 1<->5[Finished in 0.6s]

linkList.draw_linked_list()
linkList.insertBefore(linkList.tail,Node(3))
linkList.draw_linked_list()
linkList.insertBefore(linkList.head,Node(666))
linkList.draw_linked_list()
linkList.removeNodesWithValue(5)
linkList.draw_linked_list()


linkList_2 = DoublyLinkedList()
linkList_2.setHead(Node(111))
linkList_2.insertAfter(linkList_2.head,Node(222))
# linkList_2.setTail(Node(111))
linkList_2.draw_linked_list()
linkList_2.insertBefore(linkList_2.head,Node(111))
linkList_2.draw_linked_list()

Output

/Users/lianda_duan/Documents/pycharm_project/temp_can_delete/venv/bin/python /Users/lianda_duan/Documents/pycharm_project/temp_can_delete/main.py
1<->2<->3<->4<->5<->6
1<->2<->3<->4<->5<->3<->6
666<->1<->2<->3<->4<->5<->3<->6
666<->1<->2<->3<->4<->3<->6
111<->222
111<->111<->222

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值