Java實(shí)現(xiàn)二叉查找樹的增刪查詳解
定義
二叉查找樹(ADT)是一個(gè)具有對于樹種的某個(gè)節(jié)點(diǎn)X,它的左節(jié)點(diǎn)都比X小,它的右節(jié)點(diǎn)都比X大的二叉樹。如下就是一個(gè)符合
要求的二叉查找樹:

增加節(jié)點(diǎn)
1.定義節(jié)點(diǎn)類:
class Node{
int val;
Node left;
Node right;
public Node(int val){
this.val=val;
}
}
2.插入元素
我們采用遞歸的方法:
1.判斷與根節(jié)點(diǎn)是否相同,相同無需操作
2.比根元素小往左邊查找,左節(jié)點(diǎn)不存在的話則作為左節(jié)點(diǎn)插入即可
3.比根元素大往右邊查找,右節(jié)點(diǎn)不存在的話則作為右節(jié)點(diǎn)插入即可
代碼實(shí)現(xiàn)如下:
Node root;
/**
* 添加元素
* @param val
*/
public void add(int val){
if(root==null){
root=new Node(val);
return;
}
addNode(val,root);
}
private void addNode(int val,Node root){
if(root==null || root.val==val){
return;
}
if(root.val>val){
if(root.left==null){
root.left=new Node(val);
}else {
addNode(val,root.left);
}
}else {
if(root.right==null){
root.right=new Node(val);
}else {
addNode(val,root.right);
}
}
}
查詢節(jié)點(diǎn)
我們采用遞歸的方法:
1.判斷與根節(jié)點(diǎn)是否相同,相同則返回true
2.比根元素小往左邊查找,左節(jié)點(diǎn)為null則返回false表示不存在
3.比根元素大往右邊查找,右節(jié)點(diǎn)為null則返回false表示不存在
代碼實(shí)現(xiàn)如下:
/**
* 判斷指定值是否存在
* @param val 指定值
* @return true--存在 false--不存在
*/
public boolean findVale(int val){
return isExit(root,val);
}
private boolean isExit(Node node,int val){
if(node==null){
return false;
}
if(node.val==val){
return true;
}else if(node.val>val){
return isExit(node.left,val);
}else {
return isExit(node.right,val);
}
}
刪除節(jié)點(diǎn)
刪除元素時(shí)要判斷元素的情況:
1.刪除的元素沒有葉子節(jié)點(diǎn),直接刪除,如刪除值為1的節(jié)點(diǎn),雖然平衡性不是太好,但是還是符合二叉查找樹的特性

2.刪除的元素只有一個(gè)節(jié)點(diǎn),刪除元素并將指針指向其子節(jié)點(diǎn) ,如刪除值為4的節(jié)點(diǎn):

3.刪除的元素有左右兩個(gè)節(jié)點(diǎn),從右節(jié)點(diǎn)中找出大于該節(jié)點(diǎn)的最小節(jié)點(diǎn),作為新的節(jié)點(diǎn)A,如刪除節(jié)點(diǎn)值為2的節(jié)點(diǎn):

代碼實(shí)現(xiàn)如下:
/**
* 刪除元素
* 1.刪除的元素沒有葉子節(jié)點(diǎn),直接刪除
* 2.刪除的元素只有一個(gè)節(jié)點(diǎn),刪除元素并將指針指向其子節(jié)點(diǎn)
* 3.刪除的元素有兩個(gè)節(jié)點(diǎn),從右節(jié)點(diǎn)中找出大于該元素的最小值,作為新的節(jié)點(diǎn)
* @param val
*/
public void deleteElement(int val){
deleteElement(null,root,val,true);
}
/**
* 刪除元素
* @param prev 父節(jié)點(diǎn)
* @param root 當(dāng)前節(jié)點(diǎn)
* @param val 刪除值
* @param isright 是否是右節(jié)點(diǎn)
*/
private void deleteElement(Node prev,Node root,int val,boolean isright){
if(root.val==val){
//刪除的元素沒有葉子節(jié)點(diǎn),直接刪除
if(root.left==null && root.right==null){
changeValue(prev,null,isright);
}else if(root.left!=null && root.right!=null){
//3.刪除的元素有兩個(gè)節(jié)點(diǎn),從右節(jié)點(diǎn)中找出大于該元素的最小值,作為新的節(jié)點(diǎn)
changeValue(prev,new Node(findMinGt(root,root.right,true)),isright);
if(prev==null){
//對于頭結(jié)點(diǎn)的刪除特殊處理
prev=this.root;
prev.left=root.left;
prev.right=root.right;
return;
}
if(isright){
prev.right.right=root.right;
prev.right.left=root.left;
}else {
prev.left.right=root.right;
prev.left.left=root.left;
}
}//刪除的元素只有一個(gè)節(jié)點(diǎn),刪除元素并將指針指向其子節(jié)點(diǎn)
else if(root.left!=null){
changeValue(prev,root.left,isright);
}else {
changeValue(prev,root.right,isright);
}
return;
}
if(root.val>val){
deleteElement(root,root.left,val,false);
}else{
deleteElement(root,root.right,val,true);
}
}
//改變元素值
private void changeValue(Node prev,Node value,boolean isright){
if(prev==null){
root=value;
return;
}
if(isright){
prev.right=value;
}else {
prev.left=value;
}
}
//尋找大于根節(jié)點(diǎn)的最小值
private int findMinGt(Node prev,Node root,boolean isRight){
if(root.left==null && root.right==null){
changeValue(prev,null,isRight);
return root.val;
}
if(root.left==null){
changeValue(prev,null,isRight);
return root.val;
}
return findMinGt(root,root.left,false);
}到此這篇關(guān)于Java實(shí)現(xiàn)二叉查找樹的增刪查詳解的文章就介紹到這了,更多相關(guān)Java二叉查找樹增刪查內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Spring Boot中集成RabbitMQ詳細(xì)步驟(最新推薦)
本文將介紹如何在Spring Boot項(xiàng)目中集成RabbitMQ,實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者的基本配置,本文分步驟給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-12-12
淺談java中異常拋出后代碼是否會繼續(xù)執(zhí)行
這篇文章主要給大家介紹了java中異常拋出后代碼是否會繼續(xù)執(zhí)行,文章通過幾種情況的代碼示例給大家詳細(xì)分析了這個(gè)情況,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-10-10
關(guān)于springboot 配置文件中屬性變量引用方式@@解析
這篇文章主要介紹了關(guān)于springboot 配置文件中屬性變量引用方式@@解析,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
java線程并發(fā)cyclicbarrier類使用示例
CyclicBarrier類似于CountDownLatch也是個(gè)計(jì)數(shù)器,不同的是CyclicBarrier數(shù)的是調(diào)用了CyclicBarrier.await()進(jìn)入等待的線程數(shù),當(dāng)線程數(shù)達(dá)到了CyclicBarrier初始時(shí)規(guī)定的數(shù)目時(shí),所有進(jìn)入等待狀態(tài)的線程被喚醒并繼續(xù),下面使用示例學(xué)習(xí)他的使用方法2014-01-01
SpringBoot整合Spring Security的詳細(xì)教程
這篇文章主要介紹了SpringBoot整合Spring Security的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08

