鏈表
鏈表由包含數值域和指針域的數據節點構成。
單向鏈表
每個數據節點包含一個指向下一個節點的指針。
代碼示例:
#!/usr/bin/env python
# encoding: utf-8
# TODO: 定義單向鏈表節點
class Node(object):
def __init__(self, item=None):
'''
:param item: 記錄當前節點值
:param next: 記錄下一個節點
:return: None
'''
self.item = item
self.next = None
def __repr__(self):
return repr(self.item)
# TODO: 定義單向鏈表
class SLinkList(object):
def __init__(self):
'''
:param head: 頭節點
:param last: 尾節點
:param length: 鏈表長度
:return:
'''
self.head = None
self.last = None
self.curNode = None
self.length = 0
self.index = 0
# 顯示內容
def __repr__(self):
return repr(self.view())
# 獲取鏈表長度,適用len方法
def __len__(self):
'''
count = 0
curNode = self.head
while curNode:
count += 1
curNode = curNode.next
return count
'''
return self.length
# 使鏈表可索引和切片
def __getitem__(self, index):
print(type(index))
try:
return self.view()[index]
except IndexError as e:
raise e
# 標示可迭代
def __iter__(self):
return self
# 適用next方法,實現可迭代
def __next__(self):
if not self.head or self.index >= self.length:
raise StopIteration
else:
if not self.curNode:
self.curNode = self.head
curItem = self.curNode.item
self.curNode = self.curNode.next
self.index += 1
return curItem
# 判斷鏈表是否爲空
def isEmpty(self):
return self.head is None
# 頭部添加節點
def add(self, item):
newNode = Node(item)
if self.isEmpty():
self.head = newNode
self.last = newNode
else:
newNode.next = self.head
self.head = newNode
self.length += 1
return self
# 尾部添加節點
def append(self, item):
newNode = Node(item)
if self.isEmpty():
self.head = newNode
else:
self.last.next = newNode
self.last = newNode
self.length += 1
return self
# 指定位置插入節點
def insert(self, pos, item):
if pos <= 0:
self.add(item)
elif pos >= self.length:
self.append(item)
else:
newNode = Node(item)
curNode = self.head
count = 0
while count != pos:
count += 1
preNode = curNode
curNode = curNode.next
preNode.next = newNode
newNode.next = curNode
self.length += 1
return self
# 刪除元素
def remove(self, item):
if self.isEmpty() or not self.find(item):
return self
else:
curNode = self.head
curItem = curNode.item
if curItem == item and self.length == 1:
self.head = None
self.last = None
elif curItem == item and self.length > 1:
self.head = curNode.next
else:
while item != curItem:
preNode = curNode or None
curNode = curNode.next or None
nextNode = None if not curNode else curNode.next
curItem = None if not curNode else curNode.item
preNode.next = nextNode
self.length -= 1
# 查找元素,返回元素節點
def find(self, item):
curNode = self.head
curItem = curNode.item
pos = 0
if curItem == item:
return curNode
else:
pos += 1
while curItem != item:
pos += 1
curNode = curNode.next
if not curNode:
break
curItem = curNode.item
return curNode
# 清空鏈表
def clear(self):
self.length = 0
self.head = None
self.last = None
# 查看鏈表值
def view(self):
items = []
curNode = self.head
while curNode:
items.append(curNode.item)
curNode = curNode.next
return items
if __name__ == '__main__':
link = SLinkList()
print(link.isEmpty())
link.add(1)
link.add(2)
print(link.isEmpty())
print(link)
link.append(5)
link.append(9)
print(link)
link.insert(0, 6)
link.insert(3, 7)
print(link)
link.insert(11, 7)
print(link)
link.insert(1, 8)
print(link)
print(link[1:3])
print(link[1])
print(len(link))
link.remove(6)
print(link)
from collections import Iterable, Iterator
print(isinstance(link, Iterable))
print(link.find(2).next)
link.remove(5)
link.remove(5)
link.remove(2)
link.remove(7)
print(link)
print('last=', link.last)
# for i, x in enumerate(link):
# print(i, x)
輸出結果爲:
True
False
[2, 1]
[2, 1, 5, 9]
[6, 2, 1, 7, 5, 9]
[6, 2, 1, 7, 5, 9, 7]
[6, 8, 2, 1, 7, 5, 9, 7]
<class 'slice'>
[8, 2]
<class 'int'>
8
8
[8, 2, 1, 7, 5, 9, 7]
True
1
[8, 1, 9, 7]
last= 7
雙向鏈表
每個數據節點包含一個指向下一節點的指針和一個指向上一節點的指針。
代碼示例:
#!/usr/bin/env python
# encoding: utf-8
# TODO: 定義雙向鏈表節點
class Node(object):
def __init__(self, item=None):
'''
:param item: 記錄當前節點值
:param prev: 記錄前一個節點
:param next: 記錄下一個節點
:return: None
'''
self.item = item
self.prev = None
self.next = None
def __repr__(self):
return repr(self.item)
# TODO: 定義雙向鏈表
class DLinkList(object):
def __init__(self):
'''
:param head: 頭節點
:param last: 尾節點
:param length: 鏈表長度
:return:
'''
self.head = None
self.last = None
self.curNode = None
self.length = 0
self.index = 0
# 顯示內容
def __repr__(self):
'''
repr類似給原有對象加引號;
str則是將原對象轉換成字符串格式。
'''
return repr(self.view())
# 獲取鏈表長度,適用len方法
def __len__(self):
'''
count = 0
curNode = self.head
while curNode:
count += 1
curNode = curNode.next
return count
'''
return self.length
# 使鏈表可索引和切片
def __getitem__(self, index):
# index爲<class 'slice'>或者<class 'int'>類型
# print(type(index))
try:
return self.view()[index]
except IndexError as e:
raise e
# 標示可迭代
def __iter__(self):
return self
# 適用next方法,實現可迭代
def __next__(self):
# StopIteration拋出越界異常,否則死循環
if not self.head or self.index >= self.length:
raise StopIteration
else:
if not self.curNode:
self.curNode = self.head
curItem = self.curNode.item
self.curNode = self.curNode.next
self.index += 1
return curItem
# 判斷鏈表是否爲空
def isEmpty(self):
return self.head is None
# 頭部添加節點
def add(self, item):
newNode = Node(item)
newNode.prev = None
if self.isEmpty():
self.head = newNode
self.last = newNode
else:
newNode.next = self.head
self.head = newNode
self.length += 1
return self
# 尾部添加節點
def append(self, item):
newNode = Node(item)
if self.isEmpty():
self.head = newNode
else:
self.last.next = newNode
newNode.prev = self.last
self.last = newNode
self.length += 1
return self
# 指定位置插入節點
def insert(self, pos, item):
if pos <= 0:
self.add(item)
elif pos >= self.length:
self.append(item)
else:
newNode = Node(item)
curNode = self.head
count = 0
while count < pos:
count += 1
preNode = curNode
curNode = curNode.next
preNode.next = newNode
newNode.prev = preNode
newNode.next = curNode
curNode.prev = newNode
self.length += 1
return self
# 刪除元素
def remove(self, item):
if self.isEmpty() or not self.find(item):
return self
else:
curNode = self.head
curItem = curNode.item
if curItem == item and self.length == 1:
self.head = None
self.last = None
elif curItem == item and self.length > 1:
self.head = curNode.next
if self.head:
self.head.prev = None
else:
while item != curItem:
preNode = curNode or None
curNode = curNode.next or None
nextNode = None if not curNode else curNode.next
curItem = None if not curNode else curNode.item
preNode.next = nextNode
if nextNode:
nextNode.prev = preNode
self.length -= 1
# 查找元素,返回元素節點
def find(self, item):
curNode = self.head
curItem = curNode.item
pos = 0
if curItem == item:
return curNode
else:
pos += 1
while curItem != item:
pos += 1
curNode = curNode.next
if not curNode:
break
curItem = curNode.item
return curNode
# 清空鏈表
def clear(self):
self.length = 0
self.head = None
self.last = None
# 查看鏈表值
def view(self):
items = []
curNode = self.head
while curNode:
items.append(curNode.item)
curNode = curNode.next
return items
if __name__ == '__main__':
from collections import Iterable
link = DLinkList()
print(link.isEmpty())
link.append(1)
link.add(2)
link.add(3)
print(link)
link.append(4)
print(link)
link.insert(0, 'a')
link.insert(2, 'b')
print(link)
link.insert(9, 'c')
print(link.isEmpty())
link.remove(3)
link.remove(4)
link.remove('2')
print(link)
print(link[2])
print(link[1:3])
print('last=', link.last)
輸出結果爲:
True
[3, 2, 1]
[3, 2, 1, 4]
['a', 3, 'b', 2, 1, 4]
False
['a', 'b', 2, 1, 'c']
2
['b', 2]
last= 'c'
循環鏈表
雙向鏈表中,head節點的prev指針指向last節點,last節點的next指針指向head節點。
代碼示例:
略!