1.說明
1.1 概念
簡單來說,數據結構是用來設計數據以何種方式組織並存儲在計算機中,像我們常見的列表,字典,元祖等都屬於數據結構
1.2 分類
按照其邏輯可以分爲線性結構,樹結構,圖結構
線性結構:數據結構中的元素存在一對一的相互關係,如列表
樹結構:數據結構中的元素存在一對多的相互關係
圖結構:數據結構中的元素存在多對多的相互關係
2.關於列表(數組)
在其他語言中列表被稱爲數組(像c),在Python中被稱爲列表,這兩者之間還是存在區別的:
列表可以可以混合存儲元素類型,像字符串,整數等,而數組不行,要求元素類型一致
數組長度是固定的,而Python中長度不夠會開闢新的內存地址,再把原來的內容拷過來
3.關於隊列(queue)
它屬於一種數據集合,僅允許在列表的一端進行插入,另外一端進行刪除
特點:聯想我們排隊打飯,都是先進先出,對頭出隊,隊尾進隊
雙向隊列:隊列的兩端都支持進隊和出隊操作
3.1 python隊列內置模塊
基本操作:
創建隊列:queue = deque(li)
進隊:append
出隊:popleft
雙向隊列隊首進隊:appendleft
雙向隊列隊尾進隊:pop
from collections import deque lis = [9,5,2,7] q = deque(lis,8) # 最大長度是8 q.append(4) # 從隊尾追加 q.popleft() # 隊首出隊 # 對於雙向對列 q.appendleft(99) # 隊首進隊 q.pop() # 隊尾出隊
4.關於棧(stack)
棧也是一個數據集合,只能在一端進行插入或刪除操作的列表
特點:後進先出。聯想一摞書,我們取書只能從上取,存入也只能從上面存
利用python代碼實現一個棧
class Stack(object): # 初始化棧 def __init__(self): self.items = [] # 判斷棧是否爲空 def is_empty(self): return self.items == [] # 返回棧頂 def peek(self): return self.items[len(self.items) - 1] # 返回棧大小 def size(self): return len(self.items) # 壓棧 def push(self, item): self.items.append(item) # 出棧 def pop(self): return self.items.pop()
4.1 python棧內置模塊
棧的基本操作:
進棧(壓棧):push
出棧:pop
取棧頂:gettop(查看棧頂元素,但不取走) li[-1]
博客參考鏈接
5.關於鏈表
屬於一種動態數據結構,鏈表中每一個元素都是一個對象,每個對象稱爲一個節點,包含有數據域key和指向下一個節點的指針next。通過各個節點之間的相互連接,最終串聯成一個鏈表
鏈表的基本元素:
節點:每個節點有兩個部分,左邊部分稱爲值域,用來存放用戶數據;右邊部分稱爲指針域,用來存放指向下一個元素的指針。
head:head節點永遠指向第一個節點
tail: tail永遠指向最後一個節點
None:鏈表中最後一個節點的指針域爲None值
鏈表和數組的區別:
1.數組需要提前定義大小,數據小於定義長度會浪費空間,大於定義長度則無法插入。而鏈表是動態增刪數據,可以隨意增加
2.數組適用於獲取元素的操作,直接get索引即可。鏈表對於獲取元素需要從頭一直尋找,但是適用與增刪,直接修改節點的指向即可
3.數組從棧中分配空間,操作方便,但是自由度小,鏈表從堆中分配空間, 自由度大但申請管理比較麻煩
節點定義:
class Node: def __init__(self,data=None,next=None): self.data = data self.next = next # 保存下一個節點對象 def __repr__(self): return str(self.data)
定義鏈表:
# 定義節點 node1 = Node(1) node2 = Node(2) node3 = Node(3) # 將每個節點的關係表示出來 node1.next = node2 node2.next = node3
鏈表出數:
# 順序出數 def printList(node): while node: print(node) node = node.next printList(node1) # 逆序出數 def printBackward(lists): if lists == None: return printBackward(lists.next) print(lists) printBackward(node1)
5.1 鏈表基本操作
鏈表翻轉(面試常見問題)
class Node: def __init__(self, data=None, next=None): self.data = data self.next = next # 保存下一個節點對象 def __repr__(self): return str(self.data) # 時間消耗O(n),空間消耗O(1) def rever(head): if head == None or head.next == None: # 邊界條件 return head cur = head # 鏈表頭 tmp = None # 臨時變量 newhead = None # 翻轉鏈表表頭 while cur: # 存在鏈表頭 tmp = cur.next # tmp爲鏈表頭下一節點 cur.next = newhead # 此時cur.next爲None newhead = cur # 把鏈表頭賦值給翻轉鏈表頭 cur = tmp # 把下一節點賦值給鏈表頭 return newhead if __name__ == '__main__': head = Node(1) a1 = Node(2) a2 = Node(3) a3 = Node(4) head.next = a1 a1.next = a2 a2.next = a3 p = rever(head) while p: print(p.data) p = p.next
最終打印結果4,3,2,1
鏈表翻轉的四種方式:鏈接
單向鏈表的詳細操作方式:鏈接
常見數據結構:參看鏈接