• 5. 双向链表


    (1)双向链表定义:

      一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。

    (2)操作:

        is_empty():           链表是否为空

        length():               链表长度

        travel():                 遍历链表

        add(item):             链表头部添加

        append(item):      链表尾部添加

        insert(pos, item): 指定位置添加

        remove(item):      删除节点

        search(item):       查找节点是否存在

    (3)实现:

     1 class Node(object):
     2     """节点"""
     3     def __init__(self, item):
     4         self.elem = item
     5         self.next = None    # 后继
     6         self.prev = None    # 前驱
     7 
     8 class DoubleLinkList(object):
     9     """双向链表"""
    10     def __init__(self, node=None):
    11         self.__head = node
    12 
    13     def is_empty(self):
    14         """判断链表是否为空"""
    15         return self.__head == None
    16 
    17     def length(self):
    18         """返回链表的长度"""
    19         cur = self.__head
    20         count = 0
    21         while cur != None:
    22             count += 1
    23             cur = cur.next
    24         return count
    25 
    26     def travel(self):
    27         """遍历链表"""
    28         cur = self.__head
    29         while cur != None:
    30             print(cur.elem, end=" ")
    31             cur = cur.next
    32         print("")
    33 
    34     def add(self, item):
    35         """链表头部添加元素,头插法"""
    36         node = Node(item)
    37         if self.is_empty():
    38             # 如果是空链表,将_head指向node
    39             self.__head = node
    40         else:
    41             # 将node的next指向_head的头节点
    42             node.next = self.__head
    43             # 将_head 指向node
    44             self.__head = node
    45             # 将_head的头节点的prev指向node
    46             node.next.prev = node
    47 
    48     def append(self, item):
    49         """链表尾部添加元素,尾插法"""
    50         node = Node(item)
    51         if self.is_empty():
    52             # 如果是空链表,将_head指向node
    53             self.__head = node
    54         else:
    55             # 移动到链表尾部
    56             cur = self.__head
    57             while cur.next != None:
    58                 cur = cur.next
    59             # 将尾节点cur的next指向node
    60             cur.next = node
    61             # 将node的prev指向cur
    62             node.prev = cur
    63 
    64     def search(self, item):
    65         """查找元素是否存在"""
    66         cur = self.__head
    67         while cur != None:
    68             if cur.item == item:
    69                 return True
    70             cur = cur.next
    71         return False

    (4)指定位置插入节点:

        

        def insert(self, pos, item):
            """在指定位置添加节点"""
            if pos <= 0:
                self.add(item)
            elif pos > (self.length()-1):
                self.append(item)
            else:
                cur = self.__head
                count = 0
                # 移动到指定位置的前一个位置
                while count < pos:
                    count += 1
                    cur = cur.next
                # 当循环退出后,cur指向pos位置
                node = Node(item)
                # 将node的next指向cur
                node.next = cur
                # 将node的prev指向cur的prev
                node.prev = cur.prev
                # 将cur的前一个节点的next指向node
                cur.prev.next = node
                # 将cur的prev指向node
                cur.prev = node

    (5)删除元素:

        

        def remove(self, item):
            """"删除节点"""
            cur = self.__head
            while cur != None:
                if cur.elem == item:
                    # 先判断此节点是否是头结点
                    # 头结点
                    if cur == self.__head:
                        self.__head = cur.next
                        if cur.next:
                            # 判断链表是否只有一个节点
                            cur.next.prev = None
                    else:
                        cur.prev.next = cur.next
                        if cur.next:
                            cur.next.prev = cur.prev
                    break
                else:
                    cur = cur.next

    (6)测试代码:

    if __name__ == "__main__":
        dll = DoubleLinkList()
        print(dll.is_empty())  # True
        print(dll.length())    # 0
        
        dll.append(1)
        print(dll.is_empty())  # False
        print(dll.length())    # 1
        
        dll.append(2)
        dll.add(8)
        dll.append(3)
        dll.append(4)
        dll.append(5)
        dll.append(6)
        dll.travel()  # 8 1 2 3 4 5 6
        
        dll.insert(-1, 9)
        dll.travel()  # 9 8 1 2 3 4 5 6
        dll.insert(3, 100)
        dll.travel()  # 9 8 1 100 2 3 4 5 6
        dll.insert(10, 200)
        dll.travel()  # 9 8 1 100 2 3 4 5 6 200
        dll.remove(100)
        dll.travel()  # 9 8 1 2 3 4 5 6 200
        dll.remove(9)
        dll.travel()  # 8 1 2 3 4 5 6 200
        dll.remove(200)
        dll.travel()  # 8 1 2 3 4 5 6

    (7)运行结果(只需将以上代码组合在一起运行即可):

        

    文章写来不易,转载请标注。。。欢迎关注!
  • 相关阅读:
    django 省 市 区 联动
    ACM/ICPC 之 Dinic算法(POJ2112)
    ACM/ICPC 之 网络流入门-EK算法(参考模板)(POJ1273)
    ACM/ICPC 之 网络流入门-Ford Fulkerson与SAP算法(POJ1149-POJ1273)
    ACM/ICPC 之 DFS求解欧拉通路路径(POJ2337)
    ACM/ICPC 之 DFS求解欧拉回路+打表(POJ1392)
    ACM/ICPC 之 暴力打表(求解欧拉回路)-编码(POJ1780)
    ACM/ICPC 之 昂贵的聘礼-最短路解法(POJ1062)
    ACM/ICPC 之 SPFA-兑换货币(POJ1860)
    ACM/ICPC 之 欧拉回路两道(POJ1300-POJ1386)
  • 原文地址:https://www.cnblogs.com/si-lei/p/9263544.html
Copyright © 2020-2023  润新知