常见数据结构的 Python 实现(建议收藏)
生活随笔
收集整理的這篇文章主要介紹了
常见数据结构的 Python 实现(建议收藏)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數據結構作為計算機基礎的必修內容,也是很多大型互聯網企業面試的必考題。可想而知,它在計算機領域的重要性。
然而很多計算機專業的同學,都僅僅是了解數據結構的相關理論,卻無法用代碼實現各種數據結構。
今日整理了一份常見數據結構的 Python 實現,希望大家能夠參考代碼,親自動手通過代碼實現各種數據結構,以鞏固知識加深理解。
以下內容整理于《Python 實現各種常用算法》
棧
class Stack(object):def __init__(self, limit=10):self.stack = [] #存放元素self.limit = limit #棧容量極限def push(self, data): #判斷棧是否溢出if len(self.stack) >= self.limit:print('StackOverflowError')passself.stack.append(data)def pop(self):if self.stack:return self.stack.pop()else:raise IndexError('pop from an empty stack') #空棧不能被彈出def peek(self): #查看堆棧的最上面的元素if self.stack:return self.stack[-1]def is_empty(self): #判斷棧是否為空return not bool(self.stack)def size(self): #返回棧的大小return len(self.stack)單鏈表
class Node: def __init__(self, data):self.data = data self.next = None class Linked_List:def __init__(self):self.head = Nonedef initlist(self,data_list): #鏈表初始化函數self.head=Node(data_list[0]) #創建頭結點temp=self.headfor i in data_list[1:]: #逐個為 data 內的數據創建結點, 建立鏈表node=Node(i)temp.next=nodetemp=temp.nextdef is_empty(self): #判斷鏈表是否為空if self.head.next==None:print("Linked_list is empty")return Trueelse:return Falsedef get_length(self): #獲取鏈表的長度temp=self.head #臨時變量指向隊列頭部length=0 #計算鏈表的長度變量while temp!=None:length=length+1temp=temp.nextreturn length #返回鏈表的長度def insert(self,key,value): #鏈表插入數據函數if key<0 or key>self.get_length()-1:print("insert error")temp=self.headi=0while i<=key: #遍歷找到索引值為 key 的結點后, 在其后面插入結點pre=temptemp=temp.nexti=i+1node=Node(value)pre.next=nodenode.next=tempdef print_list(self): #遍歷鏈表,并將元素依次打印出來print("linked_list:")temp=self.headnew_list=[]while temp is not None:new_list.append(temp.data)temp=temp.nextprint(new_list)def remove(self,key): #鏈表刪除數據函數if key<0 or key>self.get_length()-1:print("insert error")i=0temp=self.headwhile temp !=None: #遍歷找到索引值為 key 的結點pre=temptemp=temp.nexti=i+1if i==key:pre.next=temp.nexttemp=Nonereturn Truepre.next=Nonedef reverse(self): #將鏈表反轉prev = Nonecurrent = self.headwhile current:next_node = current.nextcurrent.next = prevprev = currentcurrent = next_nodeself.head = prev雙鏈表
class Node(object):# 雙向鏈表節點def __init__(self, item):self.item = itemself.next = Noneself.prev = None class DLinkList(object):# 雙向鏈表def __init__(self):self._head = Nonedef is_empty(self):# 判斷鏈表是否為空return self._head == Nonedef get_length(self):# 返回鏈表的長度cur = self._headcount = 0while cur != None:count=count+1cur = cur.nextreturn countdef travel(self):# 遍歷鏈表cur = self._headwhile cur != None:print(cur.item)cur = cur.nextprint("")def add(self, item):# 頭部插入元素node = Node(item)if self.is_empty():# 如果是空鏈表,將_head指向nodeself._head = nodeelse:# 將node的next指向_head的頭節點node.next = self._head# 將_head的頭節點的prev指向nodeself._head.prev = node# 將_head 指向nodeself._head = nodedef append(self, item):# 尾部插入元素node = Node(item)if self.is_empty():# 如果是空鏈表,將_head指向nodeself._head = nodeelse:# 移動到鏈表尾部cur = self._headwhile cur.next != None:cur = cur.next# 將尾節點cur的next指向nodecur.next = node# 將node的prev指向curnode.prev = curdef search(self, item):# 查找元素是否存在cur = self._headwhile cur != None:if cur.item == item:return Truecur = cur.nextreturn Falsedef insert(self, pos, item):# 在指定位置添加節點if pos <= 0:self.add(item)elif pos > (self.length()-1):self.append(item)else:node = Node(item)cur = self._headcount = 0# 移動到指定位置的前一個位置while count < (pos-1):count += 1cur = cur.next# 將node的prev指向curnode.prev = cur# 將node的next指向cur的下一個節點node.next = cur.next# 將cur的下一個節點的prev指向nodecur.next.prev = node# 將cur的next指向nodecur.next = nodedef remove(self, item):# 刪除元素if self.is_empty():returnelse:cur = self._headif cur.item == item:# 如果首節點的元素即是要刪除的元素if cur.next == None:# 如果鏈表只有這一個節點self._head = Noneelse:# 將第二個節點的prev設置為Nonecur.next.prev = None# 將_head指向第二個節點self._head = cur.nextreturnwhile cur != None:if cur.item == item:# 將cur的前一個節點的next指向cur的后一個節點cur.prev.next = cur.next# 將cur的后一個節點的prev指向cur的前一個節點cur.next.prev = cur.prevbreakcur = cur.next隊列(鏈表形式實現)
class Node(object):def __init__(self,elem,next=None):self.elem = elem #表示對應的元素值self.next=next #表示下一個鏈接的鏈點 class Queue(object):def __init__(self):self.head = None #頭部鏈點為 Noneself.rear = None #尾部鏈點為 Nonedef is_empty(self):return self.head is None #判斷隊列是否為空def enqueue(self, elem):p = Node(elem) #初始化一個新的點if self.is_empty():self.head = p #隊列頭部為新的鏈點self.rear = p #隊列尾部為新的鏈點else:self.rear.next = p #隊列尾部的后繼是這個新的點self.rear =p #然后讓隊列尾部指針指向這個新的點def dequeue(self):if self.is_empty(): #判斷隊列是否為空print('Queue_is_empty') #若隊列為空,則退出 dequeue 操作else:result = self.head.elem #result為隊列頭部元素self.head = self.head.next #改變隊列頭部指針位置return result #返回隊列頭部元素def peek(self):if self.is_empty(): #判斷隊列是否為空print('NOT_FOUND') #為空則返回 NOT_FOUNDelse:return self.head.elem #返回隊列頭部元素def print_queue(self):print("queue:")temp=self.headmyqueue=[] #暫時存放隊列數據while temp is not None:myqueue.append(temp.elem)temp=temp.nextprint(myqueue)隊列(數組形式實現)
class Queue():def __init__(self):self.entries = [] #表示隊列內的參數self.length = 0 #表示隊列的長度self.front=0 #表示隊列頭部位置def enqueue(self, item):self.entries.append(item) #添加元素到隊列里面self.length = self.length + 1 #隊列長度增加 1def dequeue(self):self.length = self.length - 1 #隊列的長度減少 1dequeued = self.entries[self.front] #隊首元素為dequeuedself.front-=1 #隊首的位置減少1self.entries = self.entries[self.front:] #隊列的元素更新為退隊之后的隊列return dequeueddef peek(self):return self.entries[0] #直接返回隊列的隊首元素二叉樹
class Node(object):def __init__(self,item):self.item=item #表示對應的元素self.left=None #表示左節點self.right=None #表示右節點def __str__(self):return str(self.item) #print 一個 Node 類時會打印 __str__ 的返回值 class Tree(object):def __init__(self):self.root=Node('root') #根節點定義為 root 永不刪除,作為哨兵使用。def add(self,item):node = Node(item)if self.root is None: #如果二叉樹為空,那么生成的二叉樹最終為新插入樹的點self.root = nodeelse:q = [self.root] # 將q列表,添加二叉樹的根節點while True:pop_node = q.pop(0)if pop_node.left is None: #左子樹為空則將點添加到左子樹pop_node.left = nodereturnelif pop_node.right is None: #右子樹為空則將點添加到右子樹pop_node.right = nodereturnelse:q.append(pop_node.left)q.append(pop_node.right)def get_parent(self, item):if self.root.item == item:return None # 根節點沒有父節點tmp = [self.root] # 將tmp列表,添加二叉樹的根節點while tmp:pop_node = tmp.pop(0)if pop_node.left and pop_node.left.item == item: #某點的左子樹為尋找的點return pop_node #返回某點,即為尋找點的父節點if pop_node.right and pop_node.right.item == item: #某點的右子樹為尋找的點return pop_node #返回某點,即為尋找點的父節點if pop_node.left is not None: #添加tmp 元素tmp.append(pop_node.left)if pop_node.right is not None:tmp.append(pop_node.right)return Nonedef delete(self, item):if self.root is None: # 如果根為空,就什么也不做return Falseparent = self.get_parent(item)if parent:del_node = parent.left if parent.left.item == item else parent.right # 待刪除節點if del_node.left is None:if parent.left.item == item:parent.left = del_node.rightelse:parent.right = del_node.rightdel del_nodereturn Trueelif del_node.right is None:if parent.left.item == item:parent.left = del_node.leftelse:parent.right = del_node.leftdel del_nodereturn Trueelse: # 左右子樹都不為空tmp_pre = del_nodetmp_next = del_node.rightif tmp_next.left is None:# 替代tmp_pre.right = tmp_next.righttmp_next.left = del_node.lefttmp_next.right = del_node.rightelse:while tmp_next.left: # 讓tmp指向右子樹的最后一個葉子tmp_pre = tmp_nexttmp_next = tmp_next.left# 替代tmp_pre.left = tmp_next.righttmp_next.left = del_node.lefttmp_next.right = del_node.rightif parent.left.item == item:parent.left = tmp_nextelse:parent.right = tmp_nextdel del_nodereturn Trueelse:return False字典樹
class TrieNode:def __init__(self):self.nodes = dict() # 構建字典self.is_leaf = Falsedef insert(self, word: str): curr = selffor char in word:if char not in curr.nodes:curr.nodes[char] = TrieNode()curr = curr.nodes[char]curr.is_leaf = Truedef insert_many(self, words: [str]):for word in words:self.insert(word)def search(self, word: str):curr = selffor char in word:if char not in curr.nodes:return Falsecurr = curr.nodes[char]return curr.is_leaf堆
class heap(object):def __init__(self):#初始化一個空堆,使用數組來在存放堆元素,節省存儲self.data_list = []def get_parent_index(self,index):#返回父節點的下標if index == 0 or index > len(self.data_list) -1:return Noneelse:return (index -1) >> 1def swap(self,index_a,index_b):#交換數組中的兩個元素self.data_list[index_a],self.data_list[index_b] = self.data_list[index_b],self.data_list[index_a]def insert(self,data):#先把元素放在最后,然后從后往前依次堆化#這里以大頂堆為例,如果插入元素比父節點大,則交換,直到最后self.data_list.append(data)index = len(self.data_list) -1 parent = self.get_parent_index(index)#循環,直到該元素成為堆頂,或小于父節點(對于大頂堆) while parent is not None and self.data_list[parent] < self.data_list[index]:#交換操作self.swap(parent,index)index = parentparent = self.get_parent_index(parent)def removeMax(self):#刪除堆頂元素,然后將最后一個元素放在堆頂,再從上往下依次堆化remove_data = self.data_list[0]self.data_list[0] = self.data_list[-1]del self.data_list[-1]#堆化self.heapify(0)return remove_datadef heapify(self,index):#從上往下堆化,從index 開始堆化操作 (大頂堆)total_index = len(self.data_list) -1while True:maxvalue_index = indexif 2*index +1 <= total_index and self.data_list[2*index +1] > self.data_list[maxvalue_index]:maxvalue_index = 2*index +1if 2*index +2 <= total_index and self.data_list[2*index +2] > self.data_list[maxvalue_index]:maxvalue_index = 2*index +2if maxvalue_index == index:breakself.swap(index,maxvalue_index)index = maxvalue_index以上內容僅介紹了常見數據結構的 Python 實現,更多的其他數據結構可以前往實驗樓學習完整課程內容:https://www.shiyanlou.com/courses/1265
總結
以上是生活随笔為你收集整理的常见数据结构的 Python 实现(建议收藏)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 60 分钟极速入门 PyTorch
- 下一篇: 「我去,这也能行!」令人惊叹的8个深度学