用 python 實現雙向連結串列
阿新 • • 發佈:2018-12-15
用 python 寫單鏈表之後,雙向連結串列那就沒什麼難度了。
#coding=utf-8
__date__ = ' 17:07'
__author__ = 'sixkery'
# 雙鏈表的節點由資料域和指標域兩部分組成,指標域儲存兩個地址,一個是前驅結點,一個是後繼結點。
class Node(object):
'''節點'''
def __init__(self,item):
# 儲存節點的資料
self.element = item
# 下一個節點的地址,因為現在還沒有建立表,下一個節點指向還不確定,所以下一個節點的地址暫為空
self.next = None
# 下一個節點的地址,因為現在還沒有建立表,下一個節點指向還不確定,所以下一個節點的地址暫為空
self.prev = None
class DoubleLinkList(object):
'''實現雙鏈表,把節點串聯起來'''
# 這裡實現一個物件的屬性,目的是把節點掛到連結串列的開始位置,後續節點就不會迷路啦
# 一開始節點預設為空
def __init__(self,node=None):
self.__head = node
def is_empty (self):
'''判斷連結串列是否為空'''
# 如果連結串列的頭部沒有節點,就為空
return self.__head is None
def length(self):
'''返回連結串列的長度'''
# 要想知道連結串列的長度,需要遍歷一遍連結串列,然後計數
# 定義一個遊標,指向第一個節點,通過遊標的移動,計算連結串列中元素的個數
cur = self.__head # 代表遊標跟第一個節點指向的是同一個位置
count = 0
while cur != None:
count += 1
cur = cur.next # 遊標移動
return count
def travel(self):
'''遍歷整個連結串列'''
cur = self.__head
while cur != None:
print(cur.element,end=' ')
cur = cur.next
print('')
def add(self,item):
'''在頭部新增元素'''
# 在頭部新增,把原來的頭部節點斷開
# 新的節點的地址指向原來節點的第一個位置,然後新的節點的元素設為頭部
node = Node(item)
node.next = self.__head
self.__head = node
node.next.prev = node
def append(self,item):
'''連結串列尾部新增元素,尾插法'''
# 先構造這個節點
node = Node(item)
if self.is_empty():
self.__head = node
else:
cur = self.__head
# 這裡判斷條件發生變化,請注意
while cur.next != None:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self,pos,item):
'''指定位置插入元素'''
# 如果輸入的位置元素小於零,在頭部插入
if pos <= 0:
self.add(item)
# 如果輸入的位置元素大於列表的長度,在尾部插入
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
cur = self.__head
count = 0
# 要對插入位置的前一個元素進行操作
while count < pos:
cur = cur.next
count += 1
# 當迴圈退出後,cur 指向 pos 的位置。
node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = node
def remove(self,item):
'''刪除節點'''
cur = self.__head
while cur != None:
if cur.element == item:
# 先判斷此節點是否是頭結點
if cur == self.__head:
self.__head = cur.next
if cur.next:
# 判斷連結串列是否只有一個結點
cur.next.prev = None
else:
cur.prev.next = cur.next
if cur.next:
# 判斷連結串列是否只有一個結點
cur.next.prev = cur.prev
break
else:
cur = cur.next
def search(self,item):
'''查詢節點是否存在'''
cur = self.__head
while cur != Node:
if cur.element == item:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
li = DoubleLinkList()
print(li.is_empty())
print(li.length())
li.append(1)
print(li.is_empty())
print(li.length())
li.append(4)
li.add(10)
li.append(5)
li.append(6)
li.append(7)
li.insert(-1,15)
li.travel()
li.insert(3,50)
li.travel()
li.insert(10,100)
li.travel()
li.remove(100)
li.travel()
單向迴圈連結串列
#coding=utf-8
__date__ = ' 17:58'
__author__ = 'sixkery'
# 單向迴圈連結串列的節點由資料域和指標域兩部分組成,通俗講就是一個存資料一個存下一個資料的地址,尾結點指向頭結點。
class Node(object):
'''節點'''
def __init__(self,element):
# 儲存節點的資料
self.element = element
# 下一個節點的地址,因為現在還沒有建立表,下一個節點指向還不確定,所以下一個節點的地址暫為空
self.next = None
class SingleCycleList(object):
'''實現單向迴圈連結串列,把節點串聯起來'''
# 這裡實現一個物件的屬性,目的是把節點掛到連結串列的開始位置,後續節點就不會迷路啦
# 一開始節點預設為空
def __init__(self,node=None):
self.__head = node
if node:
node.next = node
def is_empty(self):
'''判斷連結串列是否為空'''
# 如果連結串列的頭部沒有節點,就為空
return self.__head == None
def length(self):
'''返回連結串列的長度'''
# 要想知道連結串列的長度,需要遍歷一遍連結串列,然後計數
# 定義一個遊標,指向第一個節點,通過遊標的移動,計算連結串列中元素的個數
if self.is_empty():
return 0
cur = self.__head # 代表遊標跟第一個節點指向的是同一個位置
count = 1
while cur.next != self.__head:
count += 1
cur = cur.next # 遊標移動
return count
def travel(self):
'''遍歷整個連結串列'''
if self.is_empty():
return
cur = self.__head
while cur.next != self.__head:
print(cur.element,end=' ')
cur = cur.next
# 退出迴圈,cur 指向尾結點,但尾結點的元素未輸出
print(cur.element)
def add(self,item):
'''在頭部新增元素'''
# 在頭部新增,把原來的頭部節點斷開
# 新的節點的地址指向原來節點的第一個位置,然後新的節點的元素設為頭部
node = Node(item)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
# 退出迴圈,cur 指向尾結點
node.next = self.__head
self.__head = node
cur.next = node
def append(self,item):
'''連結串列尾部新增元素,尾插法'''
# 先構造這個節點
node = Node(item)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
# 這裡判斷條件發生變化,請注意
while cur.next != self.__head:
cur = cur.next
node.next = self.__head
cur.next = node
def insert(self,pos,item):
'''指定位置插入元素'''
# 如果輸入的位置元素小於零,在頭部插入
if pos <= 0:
self.add(item)
# 如果輸入的位置元素大於列表的長度,在尾部插入
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
pre = self.__head
count = 0
# 要對插入位置的前一個元素進行操作
while count < (pos - 1):
pre = pre.next
count += 1
# 當迴圈退出後,pre 指向 pos-1 的位置。
node.next = pre.next
pre.next = node
def remove(self,item):
'''刪除節點'''
if self.is_empty():
return
cur = self.__head
pre = None
while cur.next != self.__head:
if cur.element == item:
# 先判斷此節點是否是頭結點
if cur == self.__head:
# 頭結點情況
# 找尾結點
rear = self.__head
while rear.next != self.__head:
rear = rear.next
self.__head = cur.next
rear.next = self.__head
else:
# 中間結點
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
# 退出迴圈,cur 指向尾結點
if cur.element == item:
if cur == self.__head:
# 連結串列只有一個結點
self__head = None
else:
pre.next = cur.next
def search(self,item):
'''查詢節點是否存在'''
if self.is_empty():
return False
cur = self.__head
while cur.next != self.__head:
if cur.element == item:
return True
else:
cur = cur.next
# 退出迴圈,cur 指向尾結點
if cur.element == item:
return True
return False
if __name__ == '__main__':
li = SingleCycleList()
print(li.is_empty())
print(li.length())
li.append(1)
print(li.is_empty())
print(li.length())
li.append(4)
li.add(10)
li.append(5)
li.append(6)
li.append(7)
li.insert(-1,15)
li.travel()
li.insert(3,50)
li.travel()
li.insert(10,100)
li.travel()
li.remove(100)
li.travel()
li.remove(15)
li.travel()