二插查詢樹(BST)

2021-09-19 10:14:55 字數 4647 閱讀 8030

二插查詢樹是這樣一種二叉樹結構,它的每乙個結點包含乙個key和它附帶的資料,對每乙個結點v:

所有的key小於v都被儲存在v的左子樹

所有key大於v的都存在v的右子樹

class

bstnode

(object):

def__init__

(self, key, value, left=

none

, right=

none):

self.key, self.value, self.left, self.right = key, value, left, right

class

bst(

object):

def__init__

(self, root =

none):

self.root = root

defbuild_from

(self, nodelist)

: req =

for i in nodelist:

key = i.get(

'key'

) node = bstnode(key, value = key)

req[key]

= node

for i in nodelist:

key = i[

'key'

] node = req.get(key)

node.left = req.get(i[

'left'])

node.right = req.get(i[

'right'])

if i[

'is_root']:

self.root = node

return self.root

def__contains__

(self, key)

:return self._bst__search(self.root,key)

isnot

none

查詢:

根據定義從跟結點開始如果值大於該節點就訪問右子樹,否則訪問左子樹,直到結點的值為none。

def

_bst_search

(self, subtree, key)

:if subtree is

none

:return

none

elif key < subtree.key:

return self._bst_search(subtree.left, key)

elif key > subtree.key:

return self._bst_search(subtree.right, key)

else

:return subtree

defget(self, key, default=

none):

node = self._bst_search(self.root, key)

if node is

none

:return default

else

:return node.value

插入:

def

_bst_insert

(self, subtree, key, value)

:#插入一定會插入葉節點

""" 插入並且返回根節點

:param subtree:

:param key:

:param value:

"""if subtree is

none

:# 插入的節點一定是根節點,包括 root 為空的情況

subtree = bstnode(key, value)

elif key < subtree.key:

subtree.left = self._bst_insert(subtree.left, key, value)

elif key > subtree.key:

subtree.right = self._bst_insert(subtree.right, key, value)

return subtree

defadd(self, key, value)

: node = self._bst_search(self.root, key)

if node is

notnone

:# 更新已經存在的 key

node.value = value

return

false

else

: self.root = self._bst_insert(self.root, key, value)

#細節 self.size +=

1return

true

刪除操作作用比上邊的操作要麻煩的很多,首先需要定位乙個結點,刪除節點後,我們需要始終保持bst的性子。刪除節點涉及到三種情況。

節點是葉節點

節點有乙個孩子

節點有孩子

這是最簡單的一種情況,只需要將它的父親指向它的指標設定為none就好。

刪除有乙個孩子的節點時,我們拿掉需要刪除的節點,之後把它的父親指向它的父親指向它的孩子就行,因為根據bst左子樹都小於節點,右子樹都大於節點的特性,刪除它之後這個條件依舊滿足。(節點的右子樹)的全部節點都是大於該節點的。因為在構建二叉樹的時候,只有大於右子樹的節點才會往子樹上新增。

找到待刪除節點n的後繼節點s。

複製節點s到節點n。

從n的右子樹刪除節點s,並更新其後繼節點後的右子樹。

現在關鍵就是找到後繼節點。

**如下:

def

_bst_remove

(self, subtree, key)

:#刪除節點並返回根節點

if subtree is

none

:return

none

elif key < subtree.key:

subtree.left = self._bst_remove(subtree.left, key)

return subtree

elif key > subtree.key:

subtree.right = self._bst_remove(subtree.right, key)

return subtree

else

:#找到了需要刪除的節點

if subtree.left is

none

and subtree.right is

none

:#葉節點,返回none把其父親指向它的指標置為none

return

none

elif subtree.left is

none

or subtree.right is

none

:#只有乙個孩子

if subtree.left is

notnone

:return subtree.left#返回它的孩子並它的父親指過去

else

:return subtree.right

else

:#兩孩子,尋找後繼節點替換,並從待節點的右子樹中刪除後繼節點

successor_node = self._bst_min_node(subtree.right)

#找到右子樹的最小值

subtree.key, subtree.value = successor_node.key, successor_node.value

subtree.right =self._bst_remove(subtree.right, successor_node.key)

#刪除右結點的最小值並且返回右結點

return subtree

defremove()

:assert key in self

self.size -=

1return self._bst_remove(self.root, key)

上邊介紹的操作時間複雜複雜度和二叉樹形狀有關,平均來說時間複雜度是和樹的高度成正比的,樹的高度h是log(n),但最壞情況以上操作的時間複雜度都是o(n),

其實還按照其定義,最小值就一直向右子樹找,最大值一直向右子樹找:

def

_bst_min_node

(self, subtree)

:if subtree is

none

: reuturn none

elif surtree.left is

none

:#找到左子樹的頭

return subtree

else

:return self._bst_min_node(subtree.left)

defbst_min

(self)

: node = self._bst_min_node(self.root)

return node.value if node else

none

二叉查詢樹(BST) 樹

目錄1,定義 二叉查詢樹 binary search tree 又名二叉搜尋樹或二叉排序樹。可以是一顆空樹,或者是具有下列性質的二叉樹 1 若它的左子樹不空,則左子樹上所有結點的指均小於它的根結點的值 2 若它的右子樹不空,則右子樹上所有結點的指均大於它的根結點的值 2,c 實現二叉樹的基本操作 i...

二分查詢樹(BST)

這個出現頻率比較高,為了防止忘了,寫一下好了 二分查詢樹的性質 來自維基百科 若任意節點的左子樹不空,則左子樹上所有結點的值均小於或等於它的根結點的值 任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值 任意節點的左 右子樹也分別為二叉查詢樹。沒有鍵值相等的節點 英語 no dupli...

二叉查詢樹 BST

當所有的靜態查詢結構新增和刪除乙個資料的時候,整個結構都需要重建。這對於常常需要在查詢過程中動態改變資料而言,是災難性的。因此人們就必須去尋找高效的動態查詢結構,我們在這討論乙個非常常用的動態查詢樹 二叉查詢樹。二叉查詢樹的特點 下面的圖就是兩棵二叉查詢樹,我們可以總結一下他的特點 1 若它的左子樹...