演算法與資料結構之二分搜尋樹 BST

2021-09-22 01:54:54 字數 4913 閱讀 1348

二分搜尋樹是一顆二叉樹,二分搜尋樹的每個節點的值:大於其左子樹的所有節點的值,小於其右子樹的所有節點的值,每一顆子樹也是二分搜尋樹,二分搜尋樹儲存的元素必須具有可比較性

二分搜尋樹的定義

public

class

bstcomparable

>

}private node root;

private

int size;

public

bst(

)//二分搜尋樹是否為空

public

boolean

isempty()

//返回二分搜尋樹元素個數

public

intsize()

}

向二分搜尋樹中新增元素
//向二分搜尋樹中新增新的元素e

public

void

add(e e)

//向以node為根的二分搜尋樹中插入元素e,遞迴演算法

//返回插入新節點後二分搜尋樹的根

private node add

(node node, e e)

if(e.

compareto

(node.e)

<0)

else

if(e.

compareto

(node.e)

>0)

return node;

}

二分搜尋樹的查詢操作
//看二分搜尋樹中是否包含元素e

public

boolean

contains

(e e)

//看以node為根的二分搜尋樹中是否包含元素e,遞迴演算法

private

boolean

contains

(node node, e e)

if(e.

compareto

(node.e)==0

)else

if(e.

compareto

(node.e)

>0)

else

}

二分搜尋樹的前序遍歷
public

void

preorder()

//前序遍歷以node為根的二分搜尋樹,遞迴演算法

private

void

preorder

(node node)

system.out.

println

(node.e)

;preorder

(node.left)

;preorder

(node.right)

;}

為二分搜尋樹新增列印函式,以前序遍歷為例
@override

public string tostring()

//生成以node為根節點,深度為depth的描述二叉樹的字串

private

void

generatebststring

(node node,

int depth, stringbuilder res)

res.

(generatedepthstring

(depth)

+ node.e +

"\n");

generatebststring

(node.left, depth +

1, res)

;generatebststring

(node.right, depth +

1, res);}

private string generatedepthstring

(int depth)

return res.

tostring()

;}

二分搜尋樹的中序和後序遍歷

二分搜尋樹的中序遍歷的結果就是二分搜尋樹排序後的結果

public

void

inorder()

//中序遍歷以node為根的二分搜尋樹,遞迴演算法

private

void

inorder

(node node)

inorder

(node.left)

; system.out.

println

(node.e)

;inorder

(node.right)

;}

後序遍歷的乙個應用:為二叉樹釋放記憶體,比如在c++這些需要手動釋放記憶體空間的語言來說,對二叉樹記憶體的釋放就需要使用後序遍歷

public

void

posorder()

//中序遍歷以node為根的二分搜尋樹,遞迴演算法

private

void

posorder

(node node)

posorder

(node.left)

;posorder

(node.right)

; system.out.

println

(node.e)

;}

對前序,中序和後序的深入理解

對於乙個二叉樹的遍歷來說,拋開列印的情況,也就是,先遍歷左子樹,在遍歷右子樹,在真正的遞迴過程中,會來到每個節點三次,何謂三次?比如根節點為5,左孩子為3,右孩子為4,首先來到5,接著訪問5的左孩子3,訪問3的左孩子,返回到3,在訪問3的右孩子,在返回到3,依次類推,來到每個節點三次也就是說會進以這個節點為引數的

函式三次,前序遍歷就是第一次訪問該節點時,列印該節點的值,中序就是第二次訪問該節點時,列印該節點值,後序就是第三次訪問該節點的時候列印該節點的值。

遞迴和非遞迴方式實現二叉樹的先中後序遍歷

二分搜尋樹的層序遍歷

層序遍歷的應用:更快的找到問題的解,常用於和圖有關的最短路徑的演算法設計中

public

void

levelorder()

if(cur.right != null)

} system.out.

println()

;}

刪除二分搜尋樹的最小值和最大值
//尋找二分搜尋樹的最小元素

public e minimum()

return

minimum

(root)

.e;}

//返回以node為根的二分搜尋樹的最小值所在的節點

private node minimum

(node node)

return

minimum

(node.left);}

//尋找二分搜尋樹的最大元素

public e maximum()

return

maximum

(root)

.e;}

//返回以node為根的二分搜尋樹的最大值所在的節點

private node maximum

(node node)

return

maximum

(node.right);}

//從二分搜尋樹中刪除最小值所在的節點,返回最小值

public e removemin()

//刪除掉以node為根的二分搜尋樹中的最小節點

//返回刪除節點後新的二分搜尋樹的根

private node removemin

(node node)

node.left =

removemin

(node.left)

;return node;

}//從二分搜尋樹中刪除最大值所在的節點,返回最大值

public e removemax()

//刪除掉以node為根的二分搜尋樹中的最大節點

//返回刪除節點後新的二分搜尋樹的根

private node removemax

(node node)

node.right =

removemax

(node.right)

;return node;

}

刪除二分搜尋樹的任意元素
//從二分搜尋樹中刪除元素為e的節點

public

void

remove

(e e)

//刪除以node為根的二分搜尋樹中值為e的節點,遞迴演算法

//返回刪除節點後新的二分搜尋樹的根

public node remove

(node node, e e)

if(e.

compareto

(node.e)

<0)

else

if(e.

compareto

(node.e)

>0)

else

//待刪除節點右子樹為空的情況

if(node.right == null)

//待刪除左右節點都不為空的情況

//找到比待刪除節點大的最小節點,即待刪除節點右子樹的最小節點

//用這個節點頂替待刪除節點的位置

node successor =

minimum

(node.right)

; successor.right =

removemin

(node.right)

; successor.left = node.left;

node.right = null;

node.left = null;

return successor;

}}

資料結構與演算法之二分查詢

二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好 其 缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。首先,假設表中元素是按公升序排列,將表中間位置記錄的 關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功 否則利用中間位置 記錄將表分成...

資料結構與演算法之二分查詢

假設我們有1000萬個整數資料,每個資料佔8個位元組,如何設計資料結構和演算法,快速判斷某個整數是否出現在這1000萬資料中?我們希望這個功能不要占用太多的記憶體空間,最多不要超過100m,你會怎麼做?二分查詢時一種非常簡單易懂的快速查詢演算法,生活中到處可見。比如說,我們現在來做乙個猜字遊戲。我隨...

資料結構與演算法之二分查詢

二分查詢法作為一種常見的查詢方法,將原本是線性時間提公升到了對數時間範圍,大大縮短了搜尋時間,但它有乙個前提,就是必須在有序資料中進行查詢。二分查詢過程如下 1.將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功 2.否則利用中間位置記錄將表分成前 後兩個子表,如果中間位置記錄的關鍵...