双向链表及其基本操作

  双向链表是对单向链表的一种升级改造,具备prev和next两个指针,本文从双向链表的实现开始,逐步实现对双向链表的判空、求长度、遍历、添加、删除等操作。由于双向链表的操作与单链表相似,部分注释可参考【单链表及其基本操作:https://www.cnblogs.com/kongzimengzixiaozhuzi/p/12951670.html】。

1.定义链表节点

  双向链表相比于单向链表,多了prev指针,用于指向当前节点的前一个节点。

1 class Node(object):
2     """节点"""
3     def __init__(self, element):
4         self.elem = element
5         self.next = None
6         self.prev = None

2.初始化双向链表

  初始化链表时,需要一个对象属性指向头结点。

1 class DoubleLinkList(object):
2     """双链表"""
3     def __init__(self, node = None): 
4         self. __head = node

3.双向链表基本操作

3.1.链表判空

  空链表的头一定是指向None的。

1     def is_empty(self):
2         """链表是否为空"""
3         return self.__head is None

3.2.求链表长度

  求链表长度就是统计链表节点的个数,可以使用一个游标cur遍历节点,使用一个计数器count记录节点个数。

1     def length(self):
2         """链表长度"""
3         """cur作为游标,移动遍历元素"""
4         cur = self.__head
5         count = 0
6         while cur is not None:
7             count += 1
8             cur = cur.next
9         return count

3.3.遍历链表

1     def travel(self):
2         """遍历链表"""
3         cur = self.__head
4         while cur is not None:
5             print(cur.elem, end=" ")  # end=" "关闭换行功能,print() 的原型,print默认是以end="\n"结尾.
6             cur = cur.next
7         print(end="\n")

3.4.往链表头部添加元素

  往链表中添加元素就相当远添加数据节点,需要传入节点的数据。

1     def add(self, item):
2         """在链表头部添加元素"""
3         node = Node(item)
4         node.next = self.__head
5         self.__head = node
6         node.next.prev = node

3.5.往链表尾部添加元素

 1     def append(self, item):
 2         """链表尾部添加元素"""
 3         node = Node(item)
 4         if self.is_empty():
 5             self.__head = node
 6         else:
 7             cur = self.__head
 8             while cur.next is not None:
 9                 cur = cur.next
10             cur.next = node
11             node.prev = cur

3.6.往链表指定位置添加元素

  往双向链表中添加元素涉及到打开prev和next两个指针。需要考虑添加位置的边界条件:如果添加的位置是链表头部,可以直接调用add()函数。如果添加的位置是链表尾部,可以直接调用append()函数。

 1     def insert(self, pos, item):
 2         """在指定位置添加元素"""
 3         if pos <= 0:
 4             self.add(item)
 5         elif pos > self.length()-1:
 6             self.append(item)
 7         else:
 8             node = Node(item)
 9             cur = self.__head
10             count = 0
11             while count < pos:
12                 count += 1
13                 cur = cur.next
14             node.next = cur
15             node.prev = cur.prev
16             cur.prev.next = node
17             cur.prev = node

3.7.删除节点

 1     def remove(self, item):  # 删除具体的数据
 2         """删除节点"""
 3         cur = self.__head
 4         while cur is not None:
 5             if cur.elem == item:
 6                 if cur == self.__head:  # 头节点特殊处理
 7                     self.__head = cur.next
 8                     if cur.next:  # 判断链表是否只有一个节点
 9                         cur.next.prev = None
10                 else:
11                     cur.prev.next = cur.next
12                     if cur.next:
13                         cur.next.prev = cur.prev
14                 break
15             else:
16                 cur = cur.next 

3.8.查找节点

1     def search(self, item):
2         """查找节点是否存在"""
3         cur = self.__head
4         while cur is not None:
5             if cur.elem == item:
6                 return True
7             else:
8                 cur = cur.next
9         return False

3.9.测试与结果

 1 # 测试
 2 if __name__ == "__main__":
 3     li = DoubleLinkList()
 4     print(li.is_empty())       # True
 5     print(li.length())         # 0
 6 
 7     li.append(1)
 8     print(li.is_empty())       # False
 9     print(li.length())         # 1
10 
11     li.append(2)
12     li.add(8)
13     li.append(3)
14     li.append(4)
15     li.append(5)
16     li.append(6)
17     li.insert(-1, 9)  
18     li.insert(2, 100)  
19     li.insert(10, 200)  
20     li.travel()                # 9 8 100 1 2 3 4 5 6 200 
21     li.remove(100)                
22     li.travel()                # 9 8 1 2 3 4 5 6 200 
23     li.remove(9) 
24     li.travel()                # 8 1 2 3 4 5 6 200 
25     li.remove(200)  
26     li.travel()                # 8 1 2 3 4 5 6 

 

posted @ 2020-05-24 22:22  孔子?孟子?小柱子!  阅读(212)  评论(0编辑  收藏  举报