数据结构与算法(python版)
最近學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu),對于從未接觸過數(shù)據(jù)結(jié)構(gòu)的我來說,老師不僅講解理論,還有代碼的逐層分析,非常不錯(cuò),受益匪淺!!!(以下是學(xué)習(xí)記錄)
黑馬程序員孔德海老師教程
目錄
- 重點(diǎn)+基礎(chǔ)語法
- 時(shí)間復(fù)雜度(主要關(guān)注最壞時(shí)間復(fù)雜度)
- time.it,list,dic內(nèi)置函數(shù)
- 數(shù)據(jù)結(jié)構(gòu)
- 順序表
- 順序表的2個(gè)形式
- 順序表的結(jié)構(gòu)與實(shí)現(xiàn)
- 順序表數(shù)據(jù)區(qū)擴(kuò)充
- 順序表的操作
- python_list使用順序表數(shù)據(jù)結(jié)構(gòu)
- 鏈表
- 單鏈表的實(shí)現(xiàn)
- 指定位置添加元素
- 查找節(jié)點(diǎn)是否存在
- 刪除節(jié)點(diǎn)
- 鏈表與順序表的對比
- 雙向鏈表
- 單向循環(huán)鏈表
- length(self)返回鏈表長度
- 頭部添加節(jié)點(diǎn)
- 棧
- 隊(duì)列
- 排序
- 冒泡排序O(n2)穩(wěn)定
- 選擇排序O(n2)不穩(wěn)定
- 插入排序O(n2)穩(wěn)定
- 希爾排序
- 快速排序(不穩(wěn)定)
- 歸并排序
- 排序算法效率比較
- 搜索
- 樹
- 樹的存儲
- 應(yīng)用
- 二叉樹的節(jié)點(diǎn)表示以及樹的創(chuàng)建
- 二叉樹的遍歷
- 廣度優(yōu)先遍歷(層次遍歷)
- 深度優(yōu)先遍歷
- 根據(jù)數(shù)據(jù)畫樹圖
- 樹的補(bǔ)充
- 二叉排序樹(BST)
- 平衡二叉樹(AVL)
- 紅黑樹
- 多路查找樹
- B-樹(多路平衡查找樹)
- B+樹
重點(diǎn)+基礎(chǔ)語法
如a=5 a=“s” a=Person() a=f 方法
java基本數(shù)據(jù)類型中,變量a存放的是數(shù)值。引用數(shù)據(jù)類型(對象,數(shù)組,集合)的變量a存放的是地址。
#1 strat=time.time()時(shí)間復(fù)雜度(主要關(guān)注最壞時(shí)間復(fù)雜度)
不同方法間的復(fù)雜度
import time start= time.time() for i in range(0,1001):for j in range(0,1001):for k in range(0,1001):if i+j+k==1000 and i**2+j**2==k**2:print(i,j,k) end = time.time() print("總開銷:",end-start)#總開銷: 126.49699997901917start1= time.time() for i in range(0,1001):for j in range(0,1001):k=1000-i-jif i**2+j**2==k**2:print(i,j,k) end1= time.time() print("總開銷:",end1-start1)#總開銷: 1.0120000839233398大O表示法,只記錄最顯著特征O(n)=nxn
比如對一個(gè)list排序,無序的復(fù)雜度要高于有序
基本步驟:順序,條件(取T最大值),循環(huán)
li.append()不能看成一步,只有分析函數(shù)中的封裝才能看到append的時(shí)間復(fù)雜度
time.it,list,dic內(nèi)置函數(shù)
from timeit import Timer def test3():l = [i for i in range(1000)] t3 = Timer("test3()", "from __main__ import test3")#1函數(shù)名,2import,因?yàn)檫@個(gè)Timer不一定在這里運(yùn)行 print("comprehension ",t3.timeit(number=10000), "seconds")#test3()執(zhí)行10000次后,10000次總的執(zhí)行時(shí)間import time start=time.time()#從1970年到現(xiàn)在的計(jì)時(shí)秒數(shù) end=time.time()-start#返回秒對于上例使用不同方法實(shí)現(xiàn)時(shí)
1. ('list(range(1000)) ', 0.014147043228149414, 'seconds') ('l = [i for i in range(1000)]', 0.05671119689941406, 'seconds') ('li.append ', 0.13796091079711914, 'seconds') ('concat加 ', 1.7890608310699463, 'seconds') 2.由于數(shù)據(jù)的存儲方式不同,導(dǎo)致插頭部和尾部 append()#2.159s insert(0,i)#30.00s pop(end)#0.00023,對尾部彈出 pop(0)#1.91數(shù)據(jù)結(jié)構(gòu)
數(shù)據(jù)是一個(gè)抽象的概念,將其分類后得到程序語言的基本類型,如int,float,char。數(shù)據(jù)結(jié)構(gòu)指對數(shù)據(jù)的一種封裝組成,如高級數(shù)據(jù)結(jié)構(gòu)list,字典。數(shù)據(jù)結(jié)構(gòu)就是一個(gè)類的概念,數(shù)據(jù)結(jié)構(gòu)有順序表、鏈表、棧、隊(duì)列、樹。
算法復(fù)雜度只考慮的是運(yùn)行的步驟,數(shù)據(jù)結(jié)構(gòu)要與數(shù)據(jù)打交道。數(shù)據(jù)保存的方式不同決定了算法復(fù)雜度
程序 = 數(shù)據(jù)結(jié)構(gòu) + 算法
總結(jié):算法是為了解決實(shí)際問題而設(shè)計(jì)的,數(shù)據(jù)結(jié)構(gòu)是算法需要處理的問題載體
抽象數(shù)據(jù)類型(Abstract Data Type)
抽象數(shù)據(jù)類型(ADT)的含義是指一個(gè)數(shù)學(xué)模型以及定義在此數(shù)學(xué)模型上的一組操作。
== 代碼編寫注意==
2.對于鏈表要先接入新的node,再打斷原來的,要注意順序
下面講的各種表都是一種數(shù)據(jù)的封裝結(jié)構(gòu)
順序表
順序表+鏈表=線性表:一根線串起來,兩種表都是用來存數(shù)據(jù)的
順序表的2個(gè)形式
計(jì)算機(jī)最小尋址單位是1字節(jié),就是一個(gè)字節(jié),才有一個(gè)地址,所有的地址都是統(tǒng)一大小0x27 4個(gè)字節(jié)
對于存放一個(gè)含有相同類型元素的list來講,用順序表封裝成一個(gè)數(shù)據(jù)結(jié)構(gòu)。
元素內(nèi)置順序表,是指存儲的數(shù)據(jù)類型都是一樣,這樣為每個(gè)元素開辟的空間都是一樣大的,在根據(jù)index找元素的時(shí)候
如list1=[1,2,3], 可以根據(jù)list的首地址0x12,很容易計(jì)算要查詢元素的物理地址=0x12+index x 4.
元素外置, 指存的數(shù)據(jù)類型不一樣,如list2=[1,3,“b”,4,“ccc”]
順序表的結(jié)構(gòu)與實(shí)現(xiàn)
對于python來講已經(jīng)做好封裝,不需要寫容量,元素個(gè)數(shù)
so常用的是分離式
順序表數(shù)據(jù)區(qū)擴(kuò)充
如果數(shù)據(jù)要來回增,刪,導(dǎo)致空間不穩(wěn)定,所以有了策略
順序表的操作
python_list使用順序表數(shù)據(jù)結(jié)構(gòu)
1.表頭與數(shù)據(jù)分離式 2.因?yàn)橐粋€(gè)list中有int,也有字符所以用的是元素外置 3.動態(tài)順序中的倍數(shù)擴(kuò)充
鏈表
# cur做判斷,邏輯(不是指針)走到最后一個(gè)元素時(shí),里面的方法體是執(zhí)行的 # 用cur.next做判斷,while循環(huán)中是不執(zhí)行的 # 如果發(fā)現(xiàn)少一次執(zhí)行語句,可以手動打印,就不用完全在while循環(huán)中執(zhí)行
java,c語言是需要中間變量temp,才能完成交換,只有python可以直接交換
單鏈表的實(shí)現(xiàn)
cur:指針地址
cur.elment:地址中的元素
cur=self._head先提出等式右邊地址,再給cur
多寫幾次單鏈表,有助理解,鏈表的運(yùn)行過程
1. """單鏈表的結(jié)點(diǎn),里面存放element區(qū)和next"""相當(dāng)于元祖(element,next) class SingleNode(object):def __init__(self,item):# _item存放數(shù)據(jù)元素self.item = item# _next是下一個(gè)節(jié)點(diǎn)的標(biāo)識self.next = None 2."""單鏈表數(shù)據(jù)結(jié)構(gòu)類,具有以下功能"""相當(dāng)于python中的list數(shù)據(jù)結(jié)構(gòu)類,同時(shí)它也具有以下功能 class SingleLinkList(object):"""存放一個(gè)屬性P,好用來指向第一個(gè)節(jié)點(diǎn)"""def __init__(self,):self._head = None# _ 私有屬性,head=None說明P指向的單鏈表中沒有nodedef is_empty(self):"""判斷鏈表是否為空"""return self._head == Nonedef length(self):"""鏈表長度"""# current游標(biāo)用來遍歷節(jié)點(diǎn),初始時(shí)指向頭節(jié)點(diǎn)cur = self._head#直接指到第一個(gè)節(jié)點(diǎn)count = 0# 尾節(jié)點(diǎn)指向None,當(dāng)未到達(dá)尾部時(shí)while cur != None:count += 1# 將cur后移一個(gè)節(jié)點(diǎn)cur = cur.next #相當(dāng)于指向下一個(gè)節(jié)點(diǎn)return countdef travel(self):"""遍歷鏈表"""cur = self._head#直接指到第一個(gè)節(jié)點(diǎn)while cur != None:print cur.item,#打印第一個(gè)節(jié)點(diǎn)cur = cur.next#相當(dāng)于指向下一個(gè)節(jié)點(diǎn)print ""def add(self, item):"""頭部添加元素"""# 先創(chuàng)建一個(gè)保存item值的節(jié)點(diǎn)node = SingleNode(item)# 將新節(jié)點(diǎn)的鏈接域next指向頭節(jié)點(diǎn),即_head指向的位置,有先后,否則會丟失鏈node.next = self._head# 將鏈表的頭_head指向新節(jié)點(diǎn)self._head = nodedef append(self, item):"""尾部添加元素"""node = SingleNode(item)# 先判斷鏈表是否為空,若是空鏈表,則將_head指向新節(jié)點(diǎn)if self.is_empty():self._head = node#append時(shí)候,我只要保證把我的node地址給你就行,node.next不用管# 若不為空,則找到尾部,將尾節(jié)點(diǎn)的next指向新節(jié)點(diǎn)else:cur = self._headwhile cur.next != None:cur = cur.nextcur.next = node#直接將node送給cur.next,內(nèi)部操作就是把node結(jié)點(diǎn)地址給他if __name__=="__main__":li=SingleLinkList()print(li.is_empty())print(li.length())node = SingleNode(3)li.append(11111)li.travel()3.使用node =Node(100)single_obj=SingleLinkList(node)#創(chuàng)建node,讓單鏈表指向它single_obj=SingleLinkList()#直接創(chuàng)建空鏈表指定位置添加元素

def insert(self, pos, item):"""指定位置添加元素"""# 若指定位置pos為第一個(gè)元素之前,則執(zhí)行頭部插入if pos <= 0:self.add(item)# 若指定位置超過鏈表尾部,則執(zhí)行尾部插入elif pos > (self.length()-1):self.append(item)# 找到指定位置else:node = SingleNode(item)count = 0# pre用來指向指定位置pos的前一個(gè)位置pos-1,初始從頭節(jié)點(diǎn)開始移動到指定位置pre = self._headwhile count < (pos-1):count += 1pre = pre.next# 先將新節(jié)點(diǎn)node的next指向插入位置的節(jié)點(diǎn)node.next = pre.next# 將插入位置的前一個(gè)節(jié)點(diǎn)的next指向新節(jié)點(diǎn)pre.next = node查找節(jié)點(diǎn)是否存在
def search(self,item):"""鏈表查找節(jié)點(diǎn)是否存在,并返回True或者False"""cur = self._headwhile cur != None:#一直往后走,起到遇到none停止if cur.item == item:return Truecur = cur.nextreturn False刪除節(jié)點(diǎn)
def remove(self,item):"""刪除節(jié)點(diǎn)"""cur = self._headpre = Nonewhile cur != None:# 找到了指定元素if cur.item == item:# 如果第一個(gè)就是刪除的節(jié)點(diǎn)if not pre:# 將頭指針指向頭節(jié)點(diǎn)的后一個(gè)節(jié)點(diǎn)self._head = cur.nextelse:# 將刪除位置前一個(gè)節(jié)點(diǎn)的next指向刪除位置的后一個(gè)節(jié)點(diǎn)pre.next = cur.nextbreakelse:# 繼續(xù)按鏈表后移節(jié)點(diǎn)pre = curcur = cur.next鏈表與順序表的對比
鏈表只能記錄頭節(jié)點(diǎn)地址,因此在訪問,尾部插,中間查時(shí),都需要從頭節(jié)點(diǎn),遍歷過去,所以復(fù)雜度O(n)
雙向鏈表
對于前面單向的,當(dāng)前node不能查看其前面node的信息,所以引入雙向。添加,刪除node時(shí),要保證每個(gè)node中的P,N都 給上值,如:中間插入
頭部插入元素
尾部插入元素
中間插入
單向循環(huán)鏈表
由于是循環(huán)列表,最后的尾結(jié)點(diǎn)不再是None結(jié)束,而是指向self._head
由于一開始將cur = self._head設(shè)成游標(biāo),所以判斷語句只能是cur.next
while cur.next != self._head
使用cur.next不能進(jìn)到循環(huán)體,會導(dǎo)致少一次打印,可以手動打印
length(self)返回鏈表長度
def length(self):"""返回鏈表的長度"""# 如果鏈表為空,返回長度0if self.is_empty():return 0count = 1cur = self._head#指針啟動地址while cur.next != self._head:#因?yàn)檠h(huán)鏈表最后一個(gè)node要帶有self._head,所以通過判斷是否有self._head來看是否一個(gè)循環(huán)結(jié)束count += 1cur = cur.nextreturn count頭部添加節(jié)點(diǎn)
def add(self, item):"""頭部添加節(jié)點(diǎn)"""node = Node(item)if self.is_empty():self._head = nodenode.next = self._headelse:#添加的節(jié)點(diǎn)指向_headnode.next = self._head# 移到鏈表尾部,將尾部節(jié)點(diǎn)的next指向nodecur = self._headwhile cur.next != self._head:cur = cur.nextcur.next = node#_head指向添加node的self._head = node棧
棧=杯
順序表,鏈表是用來存數(shù)據(jù)的
棧和隊(duì)列不考慮數(shù)據(jù)是如何存放的,棧stack,隊(duì)列是一種容器,執(zhí)行什么樣的操作,抽象結(jié)構(gòu)。
6*(2+3)
隊(duì)列
雙端隊(duì)列
兩個(gè)棧尾部放一起
是上面的擴(kuò)展,含有的函數(shù)功能更多了
排序
排序算法的穩(wěn)定性
冒泡排序O(n2)穩(wěn)定
#可以將這個(gè)算法操作在順序表上(改變存儲位置),也可以操作在鏈表上(改變node節(jié)點(diǎn)) #不論list是什么要,O(n)=n^2 def bubble_sort(alist):for j in range(len(alist)-1,0,-1):#n-1,n-2,,,1# j表示每次遍歷需要比較的次數(shù),是逐漸減小的for i in range(j):if alist[i] > alist[i+1]:alist[i], alist[i+1] = alist[i+1], alist[i]li = [54,26,93,17,77,31,44,55,20] bubble_sort(li) print(li)#加個(gè)檢測是否交換的優(yōu)化的count,這樣復(fù)雜度為n #[1,2,3,4,5,9,8] def bubble_sort(alist):for j in range(len(alist)-1,0,-1):#n-1,n-2,,,1# j表示每次遍歷需要比較的次數(shù),是逐漸減小的count=0for i in range(j):if alist[i] > alist[i+1]:alist[i], alist[i+1] = alist[i+1], alist[i]count+=1if 0 == count:contine li = [54,26,93,17,77,31,44,55,20] bubble_sort(li) print(li)冒泡是穩(wěn)定的
選擇排序O(n2)不穩(wěn)定
比如[5,5,2],就是不穩(wěn)定的
選擇排序,插入排序,希爾排序是把序列分成兩部分,把其中的一部分元素往另外一部分做
插入排序O(n2)穩(wěn)定
希爾排序
def shell_sort(list):n=len(list)gap=n//2 #gap=4while gap>=1:#gap一直變化到1for j in range(gap,n):#for控制的是gap=4時(shí)的4個(gè)子序列i=jwhile i >0:#跟之前插入排序一樣,對于一個(gè)序列的具體操作,與普通插入的區(qū)別就是gap步長if list[i]<list[i-gap]:list[i],list[i-gap]=list[i-gap],list[i]i-=gapelse:breakgap//=2#gap減半list = [54,26,93,17,77,31,44,55,20] shell_sort(list) print(list)快速排序(不穩(wěn)定)
快速排序(英語:Quicksort),又稱劃分交換排序(partition-exchange sort),通過一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小,然后再按此方法對這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,整個(gè)排序過程可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列。
注意
1.version2 中,兩個(gè)while有一個(gè)是等號,保證相同大小的元素放到mid的同一邊,這是快排設(shè)計(jì)的一個(gè)思想
用version2的思想寫代碼
歸并排序
def merge_sort(alist):if len(alist) <= 1:#遞歸的終止條件 return alist# 二分分解num = len(alist)/2left = merge_sort(alist[:num]) right = merge_sort(alist[num:])# 合并return merge(left,right)def merge(left, right):'''合并操作,將兩個(gè)有序數(shù)組left[]和right[]合并成一個(gè)大的有序數(shù)組'''#left與right的下標(biāo)指針l, r = 0, 0result = []while l<len(left) and r<len(right):if left[l] < right[r]:result.append(left[l])l += 1else:result.append(right[r])r += 1result += left[l:]#當(dāng)上面的while循環(huán)出來時(shí),一個(gè)list的元素是取完的,保證將另外一個(gè)list余下的元素appendresult += right[r:]return result#是一個(gè)新list,不再使用之前l(fā)ist下標(biāo)alist = [54,26,93,17,77,31,44,55,20] sorted_alist = mergeSort(alist) print(sorted_alist)遞歸時(shí)要注意縮進(jìn),這樣可以幫助理解
排序算法效率比較
搜索
二分法
前提,二分查找只能作用于有序列表
遞歸法:當(dāng)list處理后得到的list,還想再進(jìn)行同樣的操作,使用遞歸,但是不能無限遞歸下去,所以終止條件很重要,在這個(gè)例子中,要么alist[midpoint]=item,return True,要么 if len(alist) = 0: return False,用來退出遞歸
#遞歸法,每次生成一個(gè)新的list def binary_search(alist, item):if len(alist) == 0:return Falseelse:midpoint = len(alist)//2if alist[midpoint]==item:return Trueelse:if item<alist[midpoint]:return binary_search(alist[:midpoint],item)else:return binary_search(alist[midpoint+1:],item)testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,] print(binary_search(testlist, 3)) print(binary_search(testlist, 13))binary_search([0, 1, 2, 8, 13, 17, 19, 32, 42,],item=3)midpoint=43<13binary_search([0, 1, 2, 8],item=3)midpoint=23>2binary_search([8],item=3)midpoint=1//2=03<8binary_search([],item=3)#a=[1,2,3,4] print(a[5:])會返回空列表return False非遞歸
遞歸法,調(diào)用函數(shù)自身,每次生成一個(gè)新的list,然后在list上操作.非遞歸法使用的是同一個(gè)list,所以first,last下標(biāo)很重要,在while循環(huán)中,不斷更新first,last值來實(shí)現(xiàn)對于list的取值控制
樹
和前面的二分查找是一樣的
樹的存儲
應(yīng)用
二叉樹的節(jié)點(diǎn)表示以及樹的創(chuàng)建
self.root = root#保存一個(gè)根節(jié)點(diǎn),可以有,也可以沒有,如果有的話說明self.root后面跟著一串?dāng)?shù)據(jù),然后.append,在這個(gè)基礎(chǔ)上進(jìn)行加.如果self.root=None,self.root = node,為樹創(chuàng)建第一個(gè)節(jié)點(diǎn)
A為第一層,2^ 0, 2^1, ,2^2
寫完代碼后,要分析下特殊情況是否可以跑通,若不能的話,再寫特殊語句對待
廣度優(yōu)先的add實(shí)現(xiàn)的二茶樹->考察隊(duì)列,先入先出
二叉樹的遍歷
廣度優(yōu)先遍歷(層次遍歷)
def breadth_travel(self):"""利用隊(duì)列實(shí)現(xiàn)樹的層次遍歷"""if self.root == None:returnqueue = []queue.append(root)while queue:#這個(gè)queue最后是要為空的(上面的那么add的queue,由于滿足條件就會return,所以不會空)node = queue.pop(0)print node.elem,if node.lchild != None:queue.append(node.lchild)if node.rchild != None:queue.append(node.rchild)深度優(yōu)先遍歷
每次把框縮小一開始0為根節(jié)點(diǎn),然后1為根節(jié)點(diǎn),然后3為根節(jié)點(diǎn),根節(jié)點(diǎn)一直變動
根據(jù)數(shù)據(jù)畫樹圖
一定要中序:用來分割數(shù)據(jù)
前、后序:用來找根
樹的補(bǔ)充
只列出大綱,后序?qū)W習(xí)
二叉排序樹(BST)
平衡二叉樹(AVL)
特點(diǎn):1.是二叉排序樹 ⒉滿足每個(gè)結(jié)點(diǎn)的平衡因子絕對值<=1
紅黑樹
紅黑樹是一個(gè)“適度平衡”的二叉搜索樹,而非如AVL一般“嚴(yán)格”的平衡。(說它不嚴(yán)格是因?yàn)樗皇菄?yán)格控制左、右子樹高度或節(jié)點(diǎn)數(shù)之差小于等于1。)
面試常問:什么是紅黑樹?
1.每個(gè)節(jié)點(diǎn)只能是紅色或者黑色。
2.根節(jié)點(diǎn)必須是黑色。
3.紅色節(jié)點(diǎn)的子節(jié)點(diǎn)只能是黑色。
4.從任一節(jié)點(diǎn)到其每個(gè)葉子節(jié)點(diǎn),的所有路徑上,包含黑色節(jié)點(diǎn)的數(shù)目相同。
多路查找樹
B-樹(多路平衡查找樹)
視頻增刪查
B樹又稱為多路平衡查找樹,是一種組織和維護(hù)外存文件系統(tǒng)非常有效的數(shù)據(jù)結(jié)構(gòu)。比如數(shù)據(jù)庫的索引。
B+樹
b+樹和b樹的區(qū)別_B+樹和B/B樹的區(qū)別?Mysql為啥用B+樹來做索引?
b+樹適合范圍查找,比如找年齡在18-22歲的人的信息,先用隨機(jī)查找找到18,再用順序查到到22,速度極快,這也是為啥Mysql用B+樹來做索引。
主要區(qū)別:
1.所有關(guān)鍵字都會在在葉子節(jié)點(diǎn)出現(xiàn)
2.內(nèi)部節(jié)點(diǎn)(非葉子節(jié)點(diǎn))不存儲數(shù)據(jù)(b樹內(nèi)部節(jié)點(diǎn)是存儲data的),數(shù)據(jù)只在葉子節(jié)點(diǎn)存儲(葉子節(jié)指其下沒有子樹了)
3.所有葉子結(jié)點(diǎn)構(gòu)成了一個(gè)鏈指針,而且所有的葉子節(jié)點(diǎn)按照順序排列。
B+樹比B樹有什么優(yōu)勢?
1.每一層更寬,更胖,存儲的數(shù)據(jù)更多。因?yàn)锽+樹只存儲關(guān)鍵字,而不存儲多余data.所以B+樹的每一層相比B樹能存儲更多節(jié)點(diǎn)。
2.所有的節(jié)點(diǎn)都會在葉子節(jié)點(diǎn)上出現(xiàn),查詢效率更穩(wěn)定。因?yàn)锽+樹節(jié)點(diǎn)上沒有數(shù)據(jù),所以要查詢數(shù)據(jù)就必須到葉子節(jié)點(diǎn)上,所以查詢效率比B樹穩(wěn)定。而在 B 樹中,非葉子節(jié)點(diǎn)也會存儲數(shù)據(jù),這樣就會造成查詢效率不穩(wěn)定的情況,有時(shí)候訪問到了非葉子節(jié)點(diǎn)就可以找到關(guān)鍵字,而有時(shí)需要訪問到葉子節(jié)點(diǎn)才能找到關(guān)鍵字。
3.查詢效率比B樹高。因?yàn)锽+樹更矮,更胖,所以和磁盤交互的次數(shù)比B樹更少,而且B+樹通過底部的鏈表也可以完成遍歷,但是B樹需要找到每個(gè)節(jié)點(diǎn)才能遍歷,所以B+樹效率更高。
總結(jié):
1.存的多 2.查詢穩(wěn)定 3.查的快
總結(jié)
以上是生活随笔為你收集整理的数据结构与算法(python版)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 75 新闻列表页面
- 下一篇: Android中的APK,TASK,PR