Binary Search Trees(BST)

BST的性質

BST的形狀爲node

  • 每一個BST中的節點x,存在一個key,一個指向父節點的parent指針,同時還有一個左子樹和右子樹

root的parent不存在git

  • 左子樹值y與父節點x知足 key(y) <= key(x),右子樹z知足 key(x) <=key(z)

插入實現機制

假設元素的插入順序爲30,40,17,20,14 剛開始的時候沒有元素,插入新的元素github

而後插入第二個元素40,它比30要大,置爲它的右節點

插入第三個元素17,比30要小,置爲它的左節點

而後是20,比30小,找到作子樹,左子樹的節點值爲17,再次比較

最後一次元素再次插入,獲得最終的BST結構

def insert(self,z):
	x = self.root
	y=None # x's parent
	while x!=None :
	    //找到要插入的位置
		y=x
		if x.key <= z.key:
			x=x.right
		else:
			x=x.left
	if y == None:
	//新插入的元素爲第一個節點
		self.root = z
		z.parent = None
	else:
	//接入新的節點
		z.parent = y
		if y.key <= z.key:
			y.right = z
		else:
			y.left = z
複製代碼

它的耗時爲O(lgn)bash

找到後繼節點

後繼節點即從值上來說,找到比要找的元素要大最接近的值,根據BST的性質,它確定在右子樹上,因此若是存在存在右子樹,就是右子樹上的最小值,不然回溯到父節點,直到父節點不存在,或者遇到第一個不存在右節點關係的父子節點即獲得後繼值ui

17的後繼是20,即17的右子樹的節點;spa

20的後繼是30,因爲20沒有右子樹,會先回溯到17,而後17是它的父節點的左子樹,那麼它就是後繼節點;指針

40的後繼不存在;code

def successor(self,node):
	if node == None:
		return None
	if node.right != None:
		# 後繼必定在node的右節點
		return self.minimum(node.right)
	y = node.parent
	# 後繼節點只能在右節點
	while  y!=None and node == y.right:
		node = y
		y=y.parent
	return y
複製代碼

最小值則一直遞歸到左子樹沒有節點便可cdn

def minimum(self,node=None):
	x = self.root if node == None else node
	while x!=None and x.left!=None:
		x = x.left
	return x
複製代碼

刪除節點

節點刪除以後,必需要維持原有的BST性質blog

  • 刪除節點13,它一個子節點都沒有,直接刪除便可

  • 刪除節點16,只有右節點,直接有右節點替代便可

  • 刪除5,它既有左子樹又有右子樹,須要找到後繼補上

def delete(self,node):
	if node.left == None:
		# 若是node.right 是None 至關於把要刪的節點直接置成None,不然 後繼者必定是第一個right值
		return self.transplant(node,node.right)
	elif node.right == None:
		# node.left 必定存在,只須要替換節點之間的指針
		return self.transplant(node,node.left)
	else:
		# 左子樹和右子樹都有,要維持BST的性質,必須找到後繼節點
		successor = self.minimum(node.right)
		if successor != node.right:
			# 最小的左邊的值必定不存在
			self.transplant(successor,successor.right)
			# right有變化
			successor.right = node.right
			# 修改原來節點的父節點 node.right 必定存在
			successor.right.parent = successor 
		self.transplant(node,successor)
		successor.left=node.left
		# 修改原子節點的父節點 node.left必定存在
		successor.left.parent = successor
		return node
複製代碼

指針變換關係爲

def transplant(self,d,r):
	""" d been delete r replecement"""
	if d.parent == None:
		self.root = r
	elif d == d.parent.left:
		d.parent.left = r
	else:
		d.parent.right = r
	if r!=None:
		r.parent = d.parent
	return d
複製代碼

代碼詳情

相關文章
相關標籤/搜索