数据结构(一):链表

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

与数组、列表的主要区别

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

优点

  • 插入、删除操作效率高,时间复杂度为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

 

posted @ 2019-04-08 23:25  漫漫芜  阅读(601)  评论(0编辑  收藏  举报