• 数据结构(一):链表


    链表:由一系列不必再内存中相连的结构组成,每一个结构均含有表元素和指向后继结构的指针。

    与数组、列表的主要区别

    • 内存不连续;
    • 不能通过下标随机访问。

    优点

    • 插入、删除操作效率高,时间复杂度为o(1);
    • 内存利用率高,不会浪费内存;
    • 大小不固定,扩展灵活;

    缺点

    • 随机访问性差,查找效率低,时间复杂度为o(n);

    实现一个链表:

     1 class Node(object):
     2     """定义链表元素类"""
     3     def __init__(self, value=None, next=None):
     4         self.value = value
     5         self.next = next
     6 
     7 
     8 class SingleLinkList(object):
     9     def __init__(self):
    10         self.head = Node()  # 头节点没有数据,仅作为链表访问的起点
    11         self.tail = self.head
    12         self.length = 0
    13 
    14     def append(self, value):
    15         node = Node(value)
    16         self.tail.next = node
    17         self.tail = node
    18         self.length += 1
    19 
    20     def appendleft(self, value):
    21         """将节点插入到head后面"""
    22         node = Node(value)
    23         if self.head.next is not None:  # 判断链表是否插入过元素
    24             firstnode = self.head.next
    25             node.next = firstnode
    26             self.head.next = node
    27         else:
    28             self.head.next = node
    29             self.tail = node
    30         self.length += 1
    31 
    32     def iter_node(self):
    33         """构造生成器用于遍历链表节点"""
    34         curnode = self.head.next
    35         while curnode is not self.tail:
    36             yield curnode
    37             curnode = curnode.next
    38         yield curnode
    39 
    40     def __iter__(self):
    41         """通过生成器,使链表可被for循环遍历"""
    42         for node in self.iter_node():
    43             yield node.value
    44 
    45     def __len__(self):
    46         return self.length
    47 
    48     def remove(self, value):
    49         for curnode in self.iter_node():
    50             if curnode.next is not None and curnode.next.value == value:
    51                 node = curnode.next
    52                 curnode.next = node.next
    53                 del node
    54                 self.length -= 1
    55                 return 0  # 删除成功
    56         return -1  # 删除失败
    57 
    58     def popleft(self):
    59         """删除链表第一个节点"""
    60         if self.length > 0:
    61             node = self.head.next
    62             self.head.next = node.next
    63             self.length -= 1
    64             return node.value
    65         else:
    66             raise Exception('LinkList is empty')

    以上代码定义了一个单链表类,并实现了常用的添加、删除链表元素的方法。

    双端链表:单链表无法满足有些倒叙遍历链表的需求,因此需要双端链表。双端链表的实现只需要在单链表的基础上增加一个指向前一节点的指针即可,却极大的简化了某些针对节点的操作,如删除某节点的时间复杂度直接变为o(1)。

    循环双端链表:将双端链表的头节点与尾节点链接起来,就是循环双端链表。

    代码实现:

     1 class Node(object):
     2     def __init__(self, value=None, next=None, prev=None):
     3         self.value, self.next, self.prev = value, next, prev
     4 
     5 
     6 class CircularDoubleLinkList(object):
     7     def __init__(self):
     8         self.head = Node()  # 头节点没有数据,仅作为链表访问的起点
     9         self.tail = self.head
    10         self.length = 0
    11 
    12     def append(self, value):
    13         node = Node(value, self.head, self.tail)
    14         self.tail.next = node
    15         self.head.prev = node
    16         self.tail = node
    17         self.length += 1
    18 
    19     def appendleft(self, value):
    20         node = Node(value)
    21         if self.head.next is not None:
    22             nextnode = self.head.next
    23             node.next = nextnode
    24             node.prev = self.head
    25             nextnode.prev = node
    26             self.head.next = node
    27         else:
    28             node.prev = self.head
    29             node.next = self.head
    30             self.head.next = node
    31             self.head.prev = node
    32             self.tail = node
    33         self.length += 1
    34 
    35     def iter_node(self):
    36         """构造生成器用于遍历链表节点"""
    37         curnode = self.head.next
    38         while curnode is not self.tail:
    39             yield curnode
    40             curnode = curnode.next
    41         yield curnode
    42 
    43     def __iter__(self):
    44         """通过生成器,使链表可被for循环遍历"""
    45         for node in self.iter_node():
    46             yield node.value
    47 
    48     def __len__(self):
    49         return self.length
    50 
    51     def remove(self, node):
    52         """注意参数是node"""
    53         prevnode = node.prev
    54         nextnode = node.next
    55         if node is self.tail:
    56             self.tail = prevnode
    57         prevnode.next = nextnode
    58         nextnode.prev = prevnode
    59         self.length -= 1
    60 
    61     def iter_node_reverse(self):
    62         curnode = self.tail
    63         while curnode is not self.head:
    64             yield curnode
    65             curnode = curnode.prev
  • 相关阅读:
    分布式系统与机器学习相关笔记
    天坑:OpenGL制作游戏引擎备忘记录
    2016ACM-ICPC 大连站、青岛站、China-Final 赛后总结(无删版)by wanglangzhe || wmzksana
    CF 609E, 树链剖分
    CF 609F,线段树上二分 + set维护
    CF 540E, 树状数组
    hdu 5726, 2016多校1
    hdu5836, 2016CCPC网络赛
    SYSU-10,URAL 1675,容斥原理
    动态规划基础篇 from 51nod
  • 原文地址:https://www.cnblogs.com/sheshouxin/p/10659456.html
Copyright © 2020-2023  润新知