AVL樹:解決BST可能致使的長鏈問題

BST存在的問題

BST的性質有可能致使全部的數據都插在了同一個鏈路上,致使沒有一個節點有左子樹,都是右子樹,像是一個鏈表,失去了它的lgn的性質node

AVL的性質

AVL是做者的名字縮寫git

每一個左子樹的高度與右子樹的高度差值不大於1github

若是是AVL+BST須要只須要在BST的基礎上加上AVL的性質,AVL自己須要去維護高度算法

N_h爲在一個高度爲h的AVL中節點的最少的數量,有bash

N_h=N_{h-1}+N_{h-2}+1

一個AVL樹,除去根節點這層,至少包含的左右兩部分爲:一邊是高度爲h-1,另外一邊是高度爲h-2spa

從上式可得:N_h>2N_{h-2}=\theta(2^{h/2}),即h<2lgn,於是獲得AVL的高度確定是lgn.net

AVL樹+BST的插入

插入過程當中,一旦出現層級超過1的狀況,須要進行旋轉,而對應出現2層的高度差異,只會出現以下4種code

  • 狀況1:
1  
\  
 2 
  \ 
   3
須要進行一次左旋
  2  
 / \ 
1   3
複製代碼
  • 狀況2
1  
 \ 
  3 
 / 
2
先右旋
1  
 \  
  2 
  \ 
   3
再左旋
  2  
 / \ 
1   3
複製代碼
  • 狀況3
3 
  / 
 2  
/  
1 
右旋
  2  
 / \ 
1  3
複製代碼
  • 狀況4
3 
/  
1  
\  
 2
對1進行左旋
   3 
  / 
 2  
/  
1
再右旋
  2  
 / \ 
1  3
複製代碼

保持平衡的算法爲get

def _reblance(self,node):
	while node is not None:
		self._update_height(node)
		if self._height(node.left) - self._height(node.right) >=2:
		//左子樹要高
			nodeL = node.left 
			if self._height(nodeL.left) < self._height(nodeL.right):
			    //狀況4
				self._left_roate(nodeL)
			//狀況3+狀況4
			self._right_roate(node)
		elif self._height(node.right) - self._height(node.left) >=2:
		//右子樹要高
			nodeR = node.right 
			if self._height(nodeR.left) > self._height(nodeR.right):
			    //狀況2
				self._right_roate(nodeR)
			//狀況1+狀況2
			self._left_roate(node)
		node = node.parent
複製代碼

左旋string

def _left_roate(self,node):
	'''當前節點的右節點高度-左節點高度>=2 從上到下,按照父子一對一對處理 '''
	pivot = node.right
	pivot.parent = node.parent 
	if node == self.root:
		self.root = pivot
	else:
		if node.parent.left is node:
			pivot.parent.left = pivot
		else:
			pivot.parent.right = pivot
	tempNode = pivot.left
	pivot.left = node
	node.parent = pivot
	node.right = tempNode
	if tempNode is not None:
		tempNode.parent = node
	self._update_height(pivot)
	self._update_height(node)
複製代碼

右旋

def _right_roate(self,node):
	'''當前節點的左節點高度-右節點高度>=2 右旋表示左邊節點高 '''
	pivot=node.left		
	pivot.parent = node.parent
	if node == self.root:
		self.root=pivot
	else:
		if node.parent.left is node:
			pivot.parent.left = pivot
		else:
			pivot.parent.right = pivot
	node.parent = pivot
	tempNode = pivot.right 
	pivot.right = node
	node.left = tempNode
	if tempNode is not None:
		tempNode.parent = node
	
	self._update_height(pivot)
	self._update_height(node)
複製代碼

代碼詳情

相關文章
相關標籤/搜索