java有序二叉樹(shù)的刪除節(jié)點(diǎn)方式
java有序二叉樹(shù)的刪除節(jié)點(diǎn)
刪除節(jié)點(diǎn)時(shí)會(huì)有三種可能
1、刪除的節(jié)點(diǎn)為葉子節(jié)點(diǎn)
我們?nèi)绻麆h除為葉子節(jié)點(diǎn),則步驟應(yīng)該是:
1)先找到要?jiǎng)h除的葉子節(jié)點(diǎn)
2)再找到要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn)(考慮是否有父節(jié)點(diǎn))
3)找到刪除的節(jié)點(diǎn)是父節(jié)點(diǎn)的左子樹(shù)還是右子樹(shù)
4)根據(jù)前面的情況進(jìn)行刪除
2、刪除的節(jié)點(diǎn)只有一個(gè)子樹(shù)
步驟:
1)先找到要?jiǎng)h除的節(jié)點(diǎn)
2)再找到要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn)(考慮是否有父節(jié)點(diǎn))
3)確定刪除的節(jié)點(diǎn)是有左子樹(shù)還是有右子樹(shù)
4)找到刪除的節(jié)點(diǎn)是父節(jié)點(diǎn)的左子樹(shù)還是右子樹(shù)
5)根據(jù)前面的情況進(jìn)行刪除
3、刪除的節(jié)點(diǎn)有兩個(gè)子樹(shù)
步驟:
1)先找到要?jiǎng)h除的節(jié)點(diǎn)
2)再找到要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn)(考慮是否有父節(jié)點(diǎn))
3)找到刪除節(jié)點(diǎn)右子樹(shù)當(dāng)中最小的或左子樹(shù)最大的節(jié)點(diǎn)
4)將3)找到的這個(gè)節(jié)點(diǎn)的值替換掉要?jiǎng)h除的節(jié)點(diǎn)的值
5)刪除找到的3)
通過(guò)上面步驟它們都有一個(gè)共同特點(diǎn)就是需要找到刪除的節(jié)點(diǎn)和要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn),所以我們可以把這兩個(gè)找節(jié)點(diǎn)都寫成方法:
找到刪除節(jié)點(diǎn)代碼如下(通過(guò)遞歸的方式找到要?jiǎng)h除節(jié)點(diǎn)位置并記錄下來(lái)):
//找到要?jiǎng)h除的節(jié)點(diǎn)
public TreeNode searchDelnode(TreeNode node,Integer val) {
if(node==null) {
return null;
}
if(node.val==val) {
return node;
}else if(val>node.val){
if(node.rightNode==null) {
return null;
}
return searchDelnode(node.rightNode, val);
}else {
if(node.leftNode==null) {
return null;
}
return searchDelnode(node.leftNode, val);
}
}找被刪除節(jié)點(diǎn)的父節(jié)點(diǎn)代碼如下所示:
//找到要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn)
public TreeNode searchDelpartent(TreeNode node,Integer val) {
if(node==null) {
return null;
}
if((node.leftNode!=null&&node.leftNode.val==val)||(node.rightNode!=null&&node.rightNode.val==val)) {
return node;
}else {
if(node.leftNode!=null&&val<node.val) {
return searchDelpartent(node.leftNode, val);
}else if(node.rightNode!=null&&val>node.val){
return searchDelpartent(node.rightNode, val);
}else {
return null;
}
}
}我們可以根據(jù)以上步驟寫刪除方法代碼:
//二叉樹(shù)刪除節(jié)點(diǎn)
public void del(TreeNode node,Integer val) {
if(node==null) {
return;
}
//1.找到要?jiǎng)h除的節(jié)點(diǎn)
TreeNode targetNode=searchDelnode(node, val);
//2.沒(méi)有找到要?jiǎng)h除的節(jié)點(diǎn)
if(targetNode==null) {
return;
}
//3.找到要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn)
TreeNode parentNode=searchDelpartent(node, val);
if(node.rightNode==null&&node.leftNode==null) {
root=null;
return;
}
if(parentNode==null&&(targetNode.rightNode!=null||targetNode.leftNode!=null)) {
int min=searchRightMin(targetNode.rightNode);
targetNode.val=min;
return;
}
if(targetNode.leftNode==null&&targetNode.rightNode==null) {
if(parentNode.rightNode!=null&&parentNode.rightNode.val==targetNode.val) {
parentNode.rightNode=null;
}else if(parentNode.leftNode!=null&&parentNode.leftNode.val==val){
parentNode.leftNode=null;
}
}else if(targetNode.leftNode!=null&&targetNode.rightNode!=null) {
//在刪除節(jié)點(diǎn)由左右兩個(gè)子樹(shù)時(shí),我們選擇找刪除節(jié)點(diǎn)右子樹(shù)的最小值,我們可以寫一個(gè)方法,在這個(gè)方法里不僅找到最小值,并把這個(gè)位置的元素進(jìn)行刪除
int min=searchRightMin(targetNode.rightNode);
targetNode.val=min;
}else {
if(targetNode.rightNode!=null) {
if(parentNode.rightNode.val==targetNode.val) {
parentNode.rightNode=targetNode.rightNode;
}else {
parentNode.leftNode=targetNode.rightNode;
}
}else{
if(targetNode.rightNode.val==targetNode.val) {
parentNode.rightNode=targetNode.leftNode;
}else {
parentNode.leftNode=targetNode.leftNode;
}
}
}
}在刪除節(jié)點(diǎn)由左右兩個(gè)子樹(shù)時(shí),我們選擇找刪除節(jié)點(diǎn)右子樹(shù)的最小值,我們可以寫一個(gè)方法,在這個(gè)方法里不僅找到最小值,并把這個(gè)位置的元素進(jìn)行刪除
代碼如下:
public int searchRightMin(TreeNode node) {
TreeNode temp=node;
while(temp.leftNode!=null) {
temp=temp.leftNode;
}
del(root, temp.val);
return temp.val;
}
}寫一個(gè)測(cè)試類進(jìn)行測(cè)試:
public class Test {
public static void main(String[] args) {
BinaryTree binaryTree=new BinaryTree();
binaryTree.insert(1);
binaryTree.insert(2);
binaryTree.insert(3);
binaryTree.insert(4);
binaryTree.insert(5);
binaryTree.insertDigui(6, binaryTree.root);
binaryTree.insertDigui(7, binaryTree.root);
binaryTree.insertDigui(8, binaryTree.root);
binaryTree.insertDigui(9, binaryTree.root);
binaryTree.del(binaryTree.root, 2);
binaryTree.Order();
System.out.println();
binaryTree.startErgodic(binaryTree.root);
System.out.println();
binaryTree.midErgodic(binaryTree.root);
System.out.println();
binaryTree.endErgodic(binaryTree.root);
}
}結(jié)果如下圖所示:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot啟動(dòng)mongoDB報(bào)錯(cuò)之禁用mongoDB自動(dòng)配置問(wèn)題
這篇文章主要介紹了springboot啟動(dòng)mongoDB報(bào)錯(cuò)之禁用mongoDB自動(dòng)配置問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
實(shí)例講解Java批量插入、更新數(shù)據(jù)
這片文章介紹了一個(gè)Java批量添加數(shù)據(jù),多個(gè)字段同時(shí)添加多條數(shù)據(jù)具體實(shí)例,面向的是Oracle數(shù)據(jù)庫(kù),需要的朋友可以參考下2015-07-07
mybatis-plus實(shí)現(xiàn)多表查詢的示例代碼
MyBatis-Plus提供了多種方式實(shí)現(xiàn)多表查詢,包括使用注解、MyBatis-PlusJoin擴(kuò)展和XML配置文件,每種方法都有其適用場(chǎng)景和優(yōu)勢(shì),本文就來(lái)具體介紹一下,感興趣的可以了解一下2024-11-11
如何利用postman完成JSON串的發(fā)送功能(springboot)
這篇文章主要介紹了如何利用postman完成JSON串的發(fā)送功能(springboot),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Java數(shù)據(jù)結(jié)構(gòu)之圖的原理與實(shí)現(xiàn)
圖(Graph)是由頂點(diǎn)的有窮非空集合和頂點(diǎn)之間邊的集合組成,通常表示為:G(V,E),其中,G表示一個(gè)圖,V是圖G中頂點(diǎn)的集合,E是圖G中邊的集合。本文將詳細(xì)介紹圖的原理及其代碼實(shí)現(xiàn),需要的可以參考一下2022-01-01
使用IDEA創(chuàng)建SpringBoot項(xiàng)目
本文詳細(xì)介紹了使用SpringBoot創(chuàng)建項(xiàng)目,包含配置、啟動(dòng)、開(kāi)發(fā)環(huán)境配置等,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12
Java實(shí)現(xiàn)企業(yè)員工管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)企業(yè)員工管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02

