查詢演算法總結 3 二叉查詢樹

2021-08-01 17:01:53 字數 3678 閱讀 9085

**

當所有的靜態查詢結構新增和刪除乙個資料的時候,整個結構都需要重建。這對於常常需要在查詢過程中動態改變資料而言,是災難性的。因此人們就必須去尋找高效的動態查詢結構,我們在這討論乙個非常常用的動態查詢樹——二叉查詢樹 。

二叉查詢樹的特點:

(1) 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值

(2) 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值

(3) 它的左、右子樹也分別為二叉查詢樹

我們中序遍歷這兩棵樹發現乙個有序的資料序列: 【1 2 3 4 5 6 7 8 】

1、查詢操作

在a圖中查詢關鍵字6

1)如果數為空,查詢失敗

2)比較6和根節點,如果相等,查詢成功,如果6大於根節點,轉向節點的右子樹,如果小於6,轉向節點的左子樹;

3)遞迴查詢每乙個節點,直到找到和6相等的節點,否則查詢失敗。

2、插入操作:

現在我們要查詢乙個數9,如果不存在則,新增進a圖。我們看看二叉查詢樹動態新增的過程:

1). 數9和根節點4比較(9>4),則9放在節點4的右子樹中。

2). 接著,9和節點5比較(9>5),則9放在節點5的右子樹中。

3). 依次類推:直到9和節點8比較(9>8),則9放在節點8的右子樹中,成為節點8的右孩子。

這個過程我們能夠發現,動態新增任何乙個資料,都會加在原樹結構的葉子節點上,而不會重新建樹。 由此可見,動態查詢結構確實在這方面有巨大的優勢。

3、刪除操作:假設p指向待刪除的節點,parent指向p的父母節點。刪除p節點分為3中情況,根據不同的情況有不同的操作:

1)p是葉節點,直接刪除

2)需要刪除的節點只有乙個左子樹或右子樹,用子樹代替該點

3)需要刪除的節點左、右子樹都存在,此時不直接刪除p節點,而是用p節點在中序遍歷下的第乙個後續節點s代替p節點,然後刪除s節點。這樣將3)轉化為1)或者2)的問題。因為p在中序遍歷下的後續節點要麼是其右子節點且為葉子結點,要麼是右子樹中最左邊的乙個子孫節點,度為0或者1.

package binarytree;

/* * 二叉樹查詢樹的表示和操作

* 1、構建二叉樹查詢樹

* 2、二叉樹查詢樹的查詢,包括任意乙個值,最大值,最小值,任意值的前驅和後繼

* 3、二叉樹查詢樹的插入和刪除

* */

public

class

bstdemo

public node getroot()

//查詢,遞迴

public

intfind(node node,int value)

if(node.getkey()==value)

if(node.getkey()>value)

if(node.getkey()return find(node.getrchild(),value);

}return value;

}//查詢,非遞迴

public

intloopfind(node node,int value)

if(node.getkey()>value)

else

}system.out.println("查詢失敗");

return value;

}//查詢最小值

public node getmin(node node)

return node;

}//查詢最大值

public node getmax(node node)

return node;

}//獲取給定點的前驅

public node getpredecessor(node node)

//如果左子樹為空

node p=node.getparent();

node x;

while(p!=null && node==p.getlchild())

return p;

}//獲取給頂點的後繼

public node getsuccessor(node node)

//如果右子樹空

node p=node.getparent();

node x;

while(p!=null && node==p.getrchild())

return p;

}//插入,非遞迴

public

void

insert(int value)

//如果樹不為空,則查詢插入合適的位置

node node=root;

while(node!=null)

if(node.getkey()>value)else node=node.getlchild();

}elseelse node=node.getrchild();}}

}public

void

insertall(int array)

}//給定乙個節點,並刪除

public

void

remove(node node)else

if(node.getrchild()==null)else

//如果直接後繼是node的右子樹,因為suc沒有左子樹,所以用suc直接代替node

trans(node,suc);

suc.setlchild(node.getlchild());

suc.getlchild().setparent(node);}}

//用y替換x

public

void

trans(node x,node y)else

if(x==x.getparent().getlchild())else x.getparent().setrchild(y);

if(y==null)

}//判斷乙個二叉樹是否為二叉查詢樹

public

boolean

issorted(node node){

if(node==null) return

true;

return (node.getlchild()==null || node.getlchild()!=null && node.getkey()>node.getlchild().getkey()&& node.getrchild()==null || node.getrchild()!=null && node.getkey()由於二叉查詢樹的插入和刪除操作花費時間的主要部分是查詢操作,所以二叉查詢樹的各操作效能有查詢效率決定。

在一棵有n個節點的二叉差值奧數中查詢乙個節點,一次成功的查詢剛好做過一條從根節點到該節點的路徑,比較次數為該節點的高度level,1≤

leve

l≤h ,其中h是樹的高度。所以二叉查詢樹查詢成功的平均查詢長度不大於該樹的高度。而二叉查詢樹的高度和其形態有關,n個節點的文案二叉樹高度最小,為⌊l

ogn⌋

+1,n個節點的單支二叉樹高度最大,高度為n。所以二叉查詢樹的平均查詢長度為o(

logn

)−−o

(n) 。

二叉查詢樹的查詢效率與二叉樹的高度有關,高度越低,查處效率越高。因此,提高二叉查詢樹查詢效率的辦法是盡量降低二叉查詢樹的高度。

3 二叉查詢樹

二叉查詢樹要求,在樹中的任意乙個節點,其左子樹中的每個節點的值,都要小於這個節點的值,而右子樹節點的值都大於這個節點的值。刪除的情況比較複雜 第一種情況是,如果要刪除的節點沒有子節點,我們只需要直接將父節點中,指向要刪除節點的 指標置為 null。第二種情況是,如果要刪除的節點只有乙個子節點 只有左...

樹 二叉樹 查詢演算法總結

一 樹 樹的基本操作 二 二叉樹 最優二叉樹 哈夫曼樹 在所有含 n 個葉子結點 並帶相同權值的 m 叉樹中,必存在一棵其帶權路徑長度取最小值的樹,稱為 最優樹 赫夫曼演算法 以二叉樹為例 根據給定的 n 個權值 構造 n 棵二叉樹的集合f 其中每棵二叉樹中均只含乙個帶權值為 wi 的根結點,其左 ...

樹 二叉樹 查詢演算法總結

結點的子樹的個數稱為該結點的度,乙個樹中所有結點的度中的最大值稱為樹的度。1 在非空二叉樹中,第i層的結點總數不超過,i 1。2 深度為h的二叉樹最多有個結點 h 1 最少有h個結點。3 對於任意一棵二叉樹,如果其葉結點數為n0,而度數為2的結點總數為n2,則n0 n2 1。有n個結點的完全二叉樹各...