轉載:https://blog.csdn.net/weixin_43187669/article/details/96426362
算法是為了解決實際問題而設計的,數據結構是算法需要處理的問題載體。
Python提供現成的數據結構類型叫做Python的內置數據結構,比如列表、元組、集合、字典。
Python系統里面沒有直接定義需要自定義的成為Python的擴展數據結構,比如棧、隊列等。
順序表的基本形式
1.定義:所謂順序表,就是將元素順序地存放在一塊連續的存儲區里,元素間的順序關系由他們的存儲順序自然表示。
圖a,每個元素所占存儲單元大小固定相同。
圖b,每個元素所占的存儲單元大小不相同。存儲一個鏈接地址。
順序表的結構與實現
順序表的兩種基本實現方式
圖a為一體式結構,存儲表信息的單元與元素存儲區以連續的方式安排在一快存儲區里。
圖b為分離式結構,存儲表信息的單元與元素存儲區以連續的方式安排在兩塊存儲區里。
元素存儲區替換
一體式結構:若想更換數據區,則只能整體搬遷,即整個順序表對象改變了。
分離式結構:若想更換數據區,只需要將信息區中的數據區鏈接地址更新即可,而該順序表對象不變。
元素存儲區擴充
1.只有分離式結構的元素存儲區可以擴充。
2.擴充的兩種策略:
1)每次擴充增加固定數目的存儲位置,如每次擴充增加10個元素位置。
特點:節省空間,但是擴充操作頻繁,操作次數多。
2)每次擴充容量加倍,如每次擴充增加一倍存儲空間。
特點:減少了擴充操作的執行此書,但可能會浪費空間資源。以空間換時間,推薦此方式。
順序表的操作
1.增加元素的三種方式。
Python中的順序表
Python中的list和turple兩種類型采用了順序表的實現技術。
list是可變類型,即采用分離式技術實現的動態順序表。
turple是不可變型,即不變的順序表。
list的基本絲線技術
1.Python標准類型list就是一種元素個數可變的線性表,可以加入和刪除元素,具有以下特征:(1)順序表:基於下標的高效元素訪問和更新,時間復雜度是O(1);
(2)分離式技術:允許任意加入元素,而且在不斷加入元素的過程中,表對象的id不變。
list元素存儲區擴充規則
1.在建立空表(或者很小的表)時,系統分配一塊能容納8個元素的存儲區;
2. 在執行插入操作(insert或append)時,如果元素存儲區滿就換一塊4倍大的存儲區。
3. 如果此時的表已經很大(目前的閥值為50000),則改變策略,采用加一倍的方法。
原因: 為了避免出現過多空閑的存儲位置。
鏈表
順序表的構建需要預先知道數據大小來申請連續的存儲空間,而在進行空充時又需要進行數據的搬遷,所以使用起來並不是很靈活,但是鏈表結構可以充分利用計算機的內存空間,實現靈活的內存動態管理。
1.鏈表的定義:鏈表是一種常見的基礎書籍結構,是一只種類線性表,但是不想順序表一樣連續存儲數據,而是在每一個節點(數據存儲單元)里存放下一個節點的位置信息。(即地址)
單鏈表
1.單鏈表的定義:單向鏈表也叫單鏈表,每個節點包含兩個域,一個信息域(元素域)和一個鏈接域。這個鏈接指向鏈表中的下一個節點,而最后一個節點的鏈接域則指向一個空值。
2.節點實現:
class SingleNode(object): """單鏈表的節點“”“ def ——init——(self,item): #item存放數據元素 self。item = item #next是下一個結點的標示 self.
3.單鏈表的操作
length() 鏈表長度
travel() 遍歷整個鏈表
add(item) 鏈表頭部添加元素
append(item) 鏈表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 刪除節點
search(item)查找節點是否存在
is_empty() 鏈表是否為空
4.單鏈表的頭部添加元素與尾部添加元素
5.單鏈表在指定位置添加元素
6.刪除節點
鏈表與順序表的對比:
單向循環鏈表
1.單鏈表的一個變形是單向循環鏈表,鏈表中最后一個節點的next域不再為None,而是指向鏈表的頭節點。
2.單向鏈表的操作及其實現:
函數名 功能
length() 鏈表長度
travel() 遍歷整個鏈表
add(item) 鏈表頭部添加元素
append(item) 鏈表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 刪除節點
search(item) 查找節點是否存在
is_empty() 鏈表是否為空
雙向鏈表
特點:每個節點有兩個鏈接:一個指向前一個節點,當此節點為第一個節點時,指向空值;而另一個指向下一個節點,當此節點為最后一個節點時,指向空值。
指定位置添加節點算法示意圖:
2.刪除元素算法示意圖:
class Node(object): def __init__(self, element): self.element = element # 數據域 self.next = None self.prev = None def __str__(self): return self.elelemnt class DuLinkList(object): def __init__(self): self.head = None def is_empty(self): return self.head == None #判空 def __len__(self): if self.is_empty(): return 0 cur = self.head linkLen = 0 while cur: cur = cur.next linkLen += 1 return linkLen #計算長度 def travel(self): if not self.is_empty(): cur = self.head while cur.next != None: print(cur.element, end=',') cur = cur.next print(cur.element) else: print('空鏈表') #遍歷每個元素 def add(self, item): node = Node(item) if self.is_empty(): self.head = node else: node.next = self.head self.head.prev = node self.head = 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, index, item): if index <= 0: self.add(item) elif index >= len(self): self.append(item) else: node = Node(item) count = 0 cur = self.head while count <= index - 1: count += 1 cur = cur.next node.next = cur.next cur.next = node node.prev = cur #插入節點 def remove(self,item): pre = None cur = self.head if cur.element == item: self.head = self.head.next else: while cur: if cur.element != item: pre = cur cur = cur.next else: pre.next = cur.next cur.prev = pre.next break #刪除節點 if __name__ == '__main__': link = DuLinkList() print("鏈表長度:", len(link)) link.travel() print('鏈表是否為空?', link.is_empty()) print('添加頭結點:') for item in range(5): link.append(item) print('鏈表長度:', len(link)) link.insert(1, 'python')