單向循環鏈表:
- 單鏈表的一個變形是單向循環鏈表,鏈表中最後一個節點的next域不再爲None,而是指向鏈表的頭節點。
# 單向循環鏈表基於Python語言的實現
'''
單向循環鏈表需要實現的方法:
is_empty() 鏈表是否爲空
len() 鏈表長度
travel() 遍歷整個鏈表
add(item) 鏈表頭部添加元素
append(item) 鏈表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 刪除節點
search(item) 查找節點是否存在
'''
class Node(object):
"""
節點類
"""
def __init__(self, value):
# 元素域
self.value = value
# 鏈接域
self.next = None
class ReturnOneWayLinkList(object):
"""
單向鏈表類
"""
def __init__(self, node=None):
# 初始化頭節點
self.__head = node
def __len__(self):
"""
返回鏈表長度
"""
if self.is_empty():
return 0
# 遊標,用來遍歷鏈表
cur = self.__head
# 記錄遍歷次數
count = 1
# 當前節點爲None則說明已經遍歷完畢
while cur.next != self.__head:
count += 1
cur = cur.next
return count
def is_empty(self):
"""
判斷鏈表是否爲空
"""
# 頭節點不爲None則不爲空
return self.__head == None
def add(self, value):
"""
頭部插入
要先遍歷得到尾部節點,將尾部節點的next指向這個新節點
再新節點的next指向頭節點
再將頭節點替換爲新節點
順序不可錯,要先保證原鏈表的鏈不斷,否則頭節點後面的鏈會丟失
"""
node = Node(value)
# 找到尾部節點,將它的next指向新節點
cur = self.__head
while cur.next != self.__head:
cur = cur.next
cur.next = node
# 將新節點的next指向原頭結點
node.next = self.__head
# 再將新節點變爲頭結點
self.__head = node
def append(self, value):
"""
尾部插入
"""
node = Node(value)
cur = self.__head
if self.is_empty():
self.__head = node
# 將這個節點的next指向head
node.next = self.__head
else:
# 如果不是空先找到尾部節點 遊標從頭節點開始,當遊標的下一個節點等於頭部節點表示找到了尾部節點
while cur.next != self.__head:
cur = cur.next
cur.next = node
node.next = self.__head
def insert(self, pos, value):
"""
指定位置插入元素
"""
# 應對特殊情況
if pos <= 0:
self.add(value)
elif pos > len(self) - 1:
self.append(value)
else:
node = Node(value)
prior = self.__head
count = 0
# 在插入位置的前一個節點停下
while count < (pos - 1):
prior = prior.next
count += 1
# 先將插入節點與節點後的節點連接,防止鏈表斷掉,先鏈接後面的,再鏈接前面的
node.next = prior.next
prior.next = node
def remove(self, value):
"""
移除元素
"""
if self.is_empty():
return
cur = self.__head
# 設置需要移除節點的上一個節點
prior = None
# 設置是否尋找到需要刪除的節點
is_have = False
# 尋找尾部節點
end = self.__head
while end.next != self.__head:
end = end.next
while cur.next != self.__head:
if value == cur.value:
is_have = True
# 判斷此節點是否是頭節點
if cur == self.__head:
self.__head = cur.next
# 將尾部節點的next更新爲最新的head
end.next = self.__head
else:
prior.next = cur.next
break
# 還沒找到節點,繼續遍歷
else:
prior = cur
cur = cur.next
# 適配尾部移除
if is_have == False and cur.value == value:
prior.next = self.__head
def search(self, value):
"""
搜索元素
"""
cur = self.__head
while cur.next != self.__head:
if value == cur.value:
return True
cur = cur.next
if cur.value == value:
return True
return False
def travel(self):
"""
遍歷鏈表
"""
if self.is_empty():
return
cur = self.__head
while cur.next != self.__head:
print(cur.value)
cur = cur.next
# 適配最後一個元素的遍歷
print(cur.value)
if __name__ == "__main__":
link_list = ReturnOneWayLinkList()
link_list.append('a')
link_list.append('b')
link_list.add('d')
# link_list.insert(2, 'c')
link_list.travel()
print(len(link_list))
print(link_list.search('a'))
print(link_list.search('b'))
print(link_list.search('c'))
# # 移除頭部測試
# link_list.remove('d')
# # 移除尾部測試
# link_list.remove('b')
# 移除中部測試
link_list.remove('a')
link_list.travel()