1 # 实现单向循环链表
2 class Node(object):
3 '''定义一个节点'''
4 def __init__(self,data):
5 # 因为每次都需要生成一个节点,写到类里面便于保存
6 self.data = data
7 # 保存节点的值
8 self.next = None
9 # 默认将节点的指向为空
10
11 class DanLianBiao_Cycle(object):
12 # 定义一个单向循环链表 将节点连接起来
13 def __init__(self,node = None):
14 # 指向节点 如果没传递则使用 None
15 self._head = node
16 # 定义头节点,指向实例化类对象时传递的节点指向
17 if node != None:
18 # 如果传递过来的不是 None
19 # 第一个节点时需要指向自身(不同之处)
20 node.next = node
21 # 指向自己
22
23 def is_empty(self):
24 '''链表是否为空'''
25 return self._head == None
26
27
28 def length(self):
29 '''查询链表长度'''
30 if self.is_empty():
31 return 0
32 count = 1
33 # 等于1 是因为如果为0 到最后不能够加到足够数目
34 while cur.next != self._head:
35 count += 1
36 cur = cur.next
37 return count
38
39 def travel(self):
40 '''遍历整个链表'''
41 if self.is_empty():
42 return
43 cur = self._head
44 while cur.next != self._head:
45 print(cur.data)
46 cur = cur.next
47 print(cur.data)
48 # 尾节点的下一个元素为头节点,跳出循环了,打印尾节点数据
49
50
51 def add(self,data):
52 '''链表头部添加元素'''
53 node = Node(data)
54 if self.is_empty():
55 self._head = node
56 # 头节点指向 node 节点
57 node.next = node
58 # node 节点的下一个节点还为 node
59 else:
60 cur = self._head
61 # 指定当前节点指向
62 while cur.next != self._head:
63 # 一直遍历
64 cur = cur.next
65 # 不断向下
66 # cur 当前指向最后一个节点
67 node.next = self._head
68 # 右手:node 的下一个节点为头节点
69 self._head = node
70 # 让头指针指向 node 节点
71 cur.next = self._head
72 # 尾指针的下一个节点为更新后的头节点
73
74 def append(self,data):
75 '''链表尾部添加元素'''
76 node = Node(data)
77 if self.is_empty():
78 self._head = node
79 node.next = node
80 else:
81 cur = self._head
82 while cur.next != self._head:
83 cur = cur.next
84 node.next = cur.next
85 # 右手:cur.next 为头节点
86 # 让 node 作为尾节点指向头节点
87 cur.next = node
88 # 左手:让当前节点的下一个节点指向 node 节点
89
90 def insert(self,pos,data):
91 '''指定位置添加元素'''
92 # 如果为零位置
93 if pos <= 0:
94 self.add(data)
95 # 添加节点
96 elif pos > (self.length()-1):
97 # 到最后一个元素
98 self.append(data)
99 # 添加节点
100 else:
101 node = Node(data)
102 index = 0
103 cur = self._head
104 while index < pos :
105 # 遍历到 pos 前一个位置
106 index += 1
107 cur = cur.next
108 # 不断向下移动
109 node.next = cur.next
110 # 先和右面元素建立联系 防止与左面元素失联
111 cur.next = node
112
113 def remove(self,data):
114 '''删除节点'''
115 if self.is_empty():
116 return
117 cur = self._head
118 pre = None
119 # 设置游标表示前一个游标
120 while cur.next != self._head:
121 if cur.data == data:
122 # 如果 cur 指向的节点为要删除的节点
123 if cur == self._head:
124 # 如果数据为头节点的数据
125 rear = self._head
126 # 定义一个可以找到尾节点的指针
127 while rear.next != self._head:
128 rear = rear.next
129 # 此时 rear 为尾节点
130 self._head = cur.next
131 # 跳过头节点
132 rear.next = self._head
133 # 尾节点的下一个元素为头节点的下一个元素
134 else:
135 # 如果不是头尾节点,是中间节点
136 pre.next = cur.next
137 # 跳过 cur 指向的节点
138 return
139 # 找到数据并返回
140 else:
141 # 如果还没有找到数据
142 pre = cur
143 cur = cur.next
144 # 向下移动
145 # cur 当前指向为尾节点
146 if cur.data == data:
147 if cur == self._head:
148 # 如果只有一个节点,cur 没有改变过
149 self._head = None
150 else:
151 # 尾部节点为要删除的节点
152 pre.next = cur.next
153
154
155 def search(self,data):
156 '''查找节点是否存在'''
157 if self.is_empty():
158 return False
159 cur = self._head
160 # 指向头节点
161 while cur.next != self._head:
162 # 如果下一个节点不为空
163 if cur.data == data:
164 # 如果找到了数据
165 return True
166 else:
167 cur = cur.next
168 # 继续向下寻找
169 # 处理尾部节点
170 if cur.data == data:
171 return True
172 # 如果找到了元素
173 return False
174 # 没有找到该数据
2020-04-14