順序表
順序表兩種存儲模式*(順序和元素外置):
- 順序存儲模式:適用於列表中存儲的都是同一種元素。
- 元素外置存儲模式:適用於列表中存儲不同的元素,先開闢空間存儲每一個數據,用順序表存儲列表中每一個元素的地址。
順序表兩種存儲結構:(一體式和分離式)
- 區別在於,當存儲的元素超過了順序表的存儲容量時,分離式存儲結構的標頭不需要再次申請地址,只需要改變標頭中第三次元素(存儲元素的第一個地址,即200所在的地址0x23)
順序表和鏈表的區別
- 時間複雜度不同
2.鏈表是將零散的內存空間利用起來,但也增加了地址的存儲。
3.如在中間刪除操作,同樣是o(n),鏈表主要工作是在查找元素,但是順序表是爲了騰空間。
單鏈表代碼實現
class Node(object):
def __init__(self,elem):
self.elem = elem
self.next = None
class Single_link(object):
def __init__(self,node = None):
self.__head = node
def is_empty(self):
return self.__head == None #布爾類型
def length(self):
cur = self.__head # cur.next 表示的是一個存在的節點, 如果不存在就會報錯
count = 0
while cur!= None:
cur = cur.next
count += 1
return count
def travel(self):
"""遍歷"""
cur = self.__head
while cur !=None:
print(cur.elem,end=' ')
cur = cur.next
print(' ')
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
def add(self, item):
"""鏈表頭部添加元素"""
node = Node(item)
node.next =self.__head
self.__head = node
def insert(self, pos, item):
"""鏈表指定位置添加元素"""
if pos <= 0:
self.add(item)
elif pos > self.length():
self.append(item)
else:
count = 0
pro_cur = self.__head
while count < pos-1:
pro_cur = pro_cur.next
count += 1
node = Node(item)
node.next = pro_cur.next
pro_cur.next = node
def remove(self, item):
'''刪除某個數字'''
cur = self.__head
pre = None
while cur != None:
if cur.elem == item:
if cur == self.__head:
self.__head = cur.next
else:
pre.next = cur.next
break
else: # 不是這個數字,繼續往下走
pre = cur
cur = cur.next
def rearch(self, item):
cur = self.__head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return None
if __name__ == '__main__':
ll = Single_link()
雙鏈表代碼實現
class Node(object):
def __init__(self,elem):
self.elem = elem
self.next = None
self.prev = None
class Double_link(object):
def __init__(self,node = None):
self.__head = node
def is_empty(self):
return self.__head == None #布爾類型
def length(self):
cur = self.__head
count = 1
while cur != None:
count += 1
cur = cur.next
return count
def travel(self):
cur = self.__head
while cur != None:
print(cur.elem, end=" ")
cur = cur.next
print('')
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 add(self, item):
"""鏈表頭部添加元素"""
node = Node(item)
node.next = self.__head
self.__head = node
def insert(self, pos, item):
"""鏈表指定位置添加元素"""
if pos <= 0:
self.add(item)
elif pos > self.length():
self.append(item)
else:
cur = self.__head
count = 0
node = Node(item)
while cur != None:
if count == pos:
node.prev = cur.prev
cur.prev.next = node
node.next = cur
cur.prev = node
break
else:
count += 1
cur = cur.next
def remove(self, item):
'''刪除某個數字'''
cur = self.__head
while cur != None:
if cur.elem == item:
# 當刪除的爲頭結點
if cur == self.__head:
self.__head = cur.next
# 當頭結點不唯一時
if cur.next:
cur.next.prve = None
else:
# 當該結點不是尾部結點
cur.prev.next = cur.next
if cur.next:
cur.next.prve = cur.prev
break
else:
cur = cur.next
def rearch(self, item):
cur = self.__head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return None
if __name__ == '__main__':
ll = Double_link()
棧代碼實現
class stack(object):
def __init__(self):
self.__list = []
def push(self, item):
"""添加一個新的元素到棧頂"""
self.__list.append(item)
def pop(self):
"""彈出棧頂元素"""
return self.__list.pop()
def peek(self):
if self.__list:
return self.__list[-1]
"""返回棧頂元素"""
def is_empty(self):
"""判空"""
return self.__list == []
def size(self):
"""返回棧的元素個數"""
return len(self.__list)
if __name__ == '__main__':
s = stack()
s.push(1)
s.push(2)
s.push(3)
print(s.size())
print(s.peek())
print(s.pop())
print(s.pop())
print(s.pop())
print(s.peek())
print(s.size())
隊列代碼實現
class Quene(object):
"""隊列 尾部添加 頭部刪除"""
def __init__(self):
self.__list = []
def insert_queue(self, item):
"""向隊列中添加一個元素"""
self.__list.append(item)
def del_queue(self):
"""從隊列頭部刪除一個函數"""
return self.__list.pop(0)
def is_empty(self):
"""判空"""
return self.__list == []
def size(self):
"""返回隊列大小"""
return len(self.__list)
if __name__ == '__main__':
s = Quene()
print(s.is_empty())
s.insert_queue(1)
print(s.is_empty())
s.insert_queue(2)
s.insert_queue(3)
print(s.size())
print(s.del_queue())
print(s.del_queue())
print(s.del_queue())
print(s.size())
print(s.is_empty())
二分查找代碼實現
def binary_search_1(alist, item):
"""遞歸法實現二分查找"""
n = len(alist)
# 設置退出條件
if n > 0:
mid = n//2
if alist[mid] == item:
return True
elif alist[mid] > item:
return binary_search_1(alist[:mid], item)
else:
return binary_search_1(alist[mid+1:], item)
return False
def binary_search_2(alist, item):
"""二分查找 非遞歸實現"""
n = len(alist)
start = 0
end = n-1
while start <= end:
mid = (start + end) // 2
if alist[mid] == item:
return True
elif alist[mid] > item:
end = mid-1
else:
start = mid+1
return False
if __name__ == '__main__':
list = [1,2,3,4,5,6]
print(binary_search_1(list, 6))
print(binary_search_1(list, 1))
print(binary_search_2(list, 6))
print(binary_search_2(list, 1))
樹的概念與二叉樹代碼實現
-
常見樹結構:滿二叉樹:滿子樹
完全二叉樹:最後一層可以不滿,但是要靠左,子樹爲0,1都行
平衡二叉樹:最後一層只要有子樹,就必須是兩個
二叉排序樹:結點值爲 左<中<右
哈夫曼樹、B樹。 -
二叉樹特徵:
性質1:第i層最多有2^(i-1)個結點
性質2:深度爲K的二叉樹最多有2^(k-1)個結點
性質3:葉結點數爲X,度爲2的結點總是爲Y,X = Y+1。
性質4:n個結點的完全二叉樹,深度爲log2(n+1)
性質5:完全二叉樹,從上到下,從左到右的編碼,編號爲i的結點,其左孩子必爲2i,右孩子爲2i+1;雙親爲i/2(i=1時爲根,除外) -
廣度優先遍歷:層次遍歷 (使用隊列來添加)
-
深度優先遍歷:
前序遍歷:根 左 右 (先根遍歷)
中序遍歷:左 根 右 (中根遍歷)
後序遍歷:左 右 根 (後根遍歷)
代碼實現
class Node(object):
def __init__(self, item):
self.item = item
self.lchild = None
self.rchild = None
class Tree(object):
'''二叉樹'''
def __init__(self):
self.root = None
def add(self, item):
node = Node(item)
queue = [self.root]
if self.root == None:
self.root = node
return
# 通過隊列來實現 [A B C D E ] 從左邊取判斷是否爲空 ,空就直接添加,不空的話添加到隊列右側
while queue:# [None]的值爲True
cur_node = queue.pop(0)
if cur_node.lchild is None:
cur_node.lchild = node
return
else:
queue.append(cur_node.lchild)
if cur_node.rchild is None:
cur_node.rchild = node
return
else:
queue.append(cur_node.rchild)
def breadth_travel(self):
'''廣度遍歷'''
queue = [self.root]
if self.root == None:
return
while queue:
cur_node = queue.pop(0)
print(cur_node.item, end=' ')
if cur_node.lchild:
queue.append(cur_node.lchild)
if cur_node.rchild:
queue.append(cur_node.rchild)
print(' ')
def preorder(self, node):
"""前序遍歷"""
if node is None:
return
print(node.item, end=' ')
self.preorder(node.lchild)
self.preorder(node.rchild)
def midorder(self, node):
"""中序遍歷"""
if node is None:
return
self.midorder(node.lchild)
print(node.item, end=' ')
self.midorder(node.rchild)
def postorder(self, node):
"""後序遍歷"""
if node is None:
return
self.postorder(node.lchild)
self.postorder(node.rchild)
print(node.item, end=' ')
if __name__ == '__main__':
tree = Tree()
for i in range(10):
tree.add(i)
tree.breadth_travel()
tree.preorder(tree.root)
print(' ')
tree.midorder(tree.root)
print(' ')
tree.postorder(tree.root)