二叉搜尋樹JAVA實現

2021-07-14 22:25:41 字數 3706 閱讀 4672

引入:

二叉搜尋樹是這樣的一種二叉樹:

(1)每個元素都有乙個關鍵值,並且沒有任意兩個元素有相同的關鍵值

(2)根節點的左子樹中任意元素的關鍵值小於根節點的關鍵值。

(3)根節點的右子樹中任意元素的關鍵值大於根節點的關鍵值。

(4)根節點的左右子樹也是二叉搜尋樹。

我們這裡就用程式來實現這樣一顆二叉搜尋樹。

分析:

從定義看出,二叉搜尋樹是一種特殊的二叉樹,它給每個元素加上了序的概念,但又不同於最大最小堆,它總是 左《根《右的。我們分別看常用的幾個操作。查詢:

關鍵值查詢很簡單,就是從根元素開始遍歷,如果找到匹配的,則直接將其對應元素的值返回。

如果關鍵值比當前查詢元素的關鍵值小,那麼關鍵值一定在左子樹中,所以遞迴的在左子樹中查詢。

如果關鍵值比當前查詢元素的關鍵值大,那麼關鍵值一定在右子樹中,所以遞迴的在右子樹中查詢。

上述遞迴跳出的條件就是當前查詢元素為空,一旦為空都找不到匹配,則說明該二叉搜尋樹中沒有匹配值。 插入

: 插入之前必須保證二叉搜尋樹的第一條定義,所以先找下是否有匹配元素,如果有,則不執行插入動作。

然後從根開始折半找,根據子元素的值來確定這個值插入左邊還是右邊,直到選擇到乙個精確的位置,使得待插元素的關鍵值剛好落在當前元素和其某個子元素之間(或者沒有子元素)

刪除:刪除複雜多了,先遍歷找到要刪除的元素,

分為3種情況:

1.如果該元素左,右子樹都不為空,則吧該元素替換為其左子樹中的最大元素或者右子樹的最小元素(因為這2個元素剛好是與當前元素最近的2個元素)

2.如果該元素左,右子樹都為空( 也就是葉節點),那麼直接丟棄,當然也要考慮根節點的情況。

3.如果該元素左或者右子樹不為空,那麼需要找到該元素的父親元素,然後把其不為空的這個分支的根元素設為父親元素的直接子元素,當然也要考慮根節點的情況。

**:我們寫了乙個這樣的類,很詳細的注釋,尤其刪除部分,的確很複雜:

package com.charles.algo.binarysearchtree;

import com.charles.algo.binarytree.binarytreenode;

/** * 這個類是二叉搜尋樹的定義

* @author charles.wang

* */

public class binarysearchtree

/*** 返回關鍵字匹配的節點的值

*/public v search (int key)

//如果跳出了while迴圈還沒找到匹配的值,說明在這個搜尋樹中找不到,返回null

return null;

}/**

* 插入乙個節點到二叉搜尋樹中

* @param key

* @param value

*/public void insertnode( int key, v value)

//假設二叉搜尋樹已經存在,那麼從根開始,找到適合其插入的位置

//如果判斷某個位置是否是其可以插入?

//方法是,從根開始標記為當前節點,如果新節點的key比當前節點的key小,那麼說明插在當前節點的左子樹中

//這時候,如果左節點為空,那麼新節點就作為當前節點的左邊節點

// 如果左節點不為空,那麼比較左節點的key和新節點的key,

// 如果新節點的key大於左節點的key,那麼吧新節點插入到左節點和當前節點之間,退出迴圈

// 如果新節點的key小於左節點的key,那麼吧當前節點設為當前節點的左節點。

//右節點處理與上述類似

else

//當前節點的左節點不為空,則比較左節點的key和新節點的key

else

//如果新節點key比當前節點左節點還小,那麼說明適合插入的位置位於當前節點的左搜尋子樹中,於是移動當前節點

//到左子節點作為新的比較的基準

else}}

//插入到右子樹中

else

//如果當前節點的右節點不為空,那麼比較右節點的key和新節點的key

else

//如果新節點的key比當前節點的右邊節點還大,說明適合插入的位置位於當前節點的右搜尋子樹中,於是移動當前節點

//到右子節點作為新的比較的基準

else }}

}}

}/**

* 刪除指定key的節點

* @param key

*/public void deletenode(int key)

//吧最大節點插入到currentnode中,從而維持了原有的結構不變

currentnode.setkey(maxnode.getkey());

currentnode.setvalue(maxnode.getvalue());

//刪除左子樹的原最大節點

maxnodeparentnode.setrightchild(null);

return ;

}//情況2,如果當前節點既沒有左節點又沒有右節點,則直接丟棄

if(( currentnode.getleftchild()==null) && (currentnode.getrightchild()==null) )

//如果當前節點不為根節點,那麼必定有父親節點,這時候只要丟棄當前節點就可以了,判斷是判斷當前節點是父親節點的左兒子還是右兒子

if(currentnode==currentnodeparentnode.getleftchild())

else

currentnodeparentnode.setrightchild(null);

return;

}//情況3,如果當前節點只有左節點或者右節點中的1個,那麼吧兒子提公升上來

else

//如果當前節點不為根節點,那麼必定有父節點,則判斷當前節點是父親節點的左兒子還是右兒子,並且用左節點值取代之

else if(currentnode==currentnodeparentnode.getleftchild())

else

currentnodeparentnode.setrightchild(currentnode.getleftchild());

}//如果只有右節點

else

//如果當前節點不為根節點,那麼必定有父節點,則判斷當前節點是父親節點的左兒子還是右兒子,並且用右節點值取代之

if(currentnode==currentnodeparentnode.getleftchild())

else

currentnodeparentnode.setrightchild(currentnode.getrightchild());}}

}/**

* 因為二叉搜尋樹中,左《根《右,所以我們可以用中序遍歷的方法來列印出所有的節點

*/public void printallnodes()

/*** 中序遍歷某節點,它會先列印左邊節點,再列印當前節點,最後列印出右邊節點

* @param args

*/private void midorder(bstreenode currentnode)

}}

下面我們來驗證,我們先構造一組強度彼此不同的人,吧他們放入二叉搜尋樹,接著我們來演示查詢還有刪除操作是否每次刪除都維持著二叉搜尋樹中順序的關係:

public static void main(string args)

二叉搜尋樹 java實現

目錄 1 插入元素思想與實現 2 刪除元素思想與實現 3 完整 二叉搜尋樹定義 二叉搜尋樹,也稱有序二叉樹,排序二叉樹,是指一棵空樹或者具有下列性質的二叉樹 若任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值 若任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值 任意節...

二叉搜尋樹 二叉搜尋樹

題目 二叉搜尋樹 time limit 2000 1000 ms j a others memory limit 32768 32768 k j a others total submission s 6945 accepted submission s 3077 problem descripti...

二叉搜尋樹 修剪二叉搜尋樹

第一反應是重構,看來別人的解答發現,其實不用重構那麼複雜。treenode trimbst treenode root,int low,int high if root val high 下一層處理完左子樹的結果賦給root left,處理完右子樹的結果賦給root right。root left ...