二分搜尋樹是一顆二叉樹,二分搜尋樹的每個節點的值:大於其左子樹的所有節點的值,小於其右子樹的所有節點的值,每一顆子樹也是二分搜尋樹,二分搜尋樹儲存的元素必須具有可比較性
二分搜尋樹的定義
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.否則利用中間位置記錄將表分成前 後兩個子表,如果中間位置記錄的關鍵...