java有序二叉樹的刪除節(jié)點(diǎn)方式
java有序二叉樹的刪除節(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)的左子樹還是右子樹
4)根據(jù)前面的情況進(jìn)行刪除
2、刪除的節(jié)點(diǎn)只有一個(gè)子樹
步驟:
1)先找到要?jiǎng)h除的節(jié)點(diǎn)
2)再找到要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn)(考慮是否有父節(jié)點(diǎn))
3)確定刪除的節(jié)點(diǎn)是有左子樹還是有右子樹
4)找到刪除的節(jié)點(diǎn)是父節(jié)點(diǎn)的左子樹還是右子樹
5)根據(jù)前面的情況進(jìn)行刪除
3、刪除的節(jié)點(diǎn)有兩個(gè)子樹
步驟:
1)先找到要?jiǎng)h除的節(jié)點(diǎn)
2)再找到要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn)(考慮是否有父節(jié)點(diǎn))
3)找到刪除節(jié)點(diǎn)右子樹當(dāng)中最小的或左子樹最大的節(jié)點(diǎn)
4)將3)找到的這個(gè)節(jié)點(diǎn)的值替換掉要?jiǎng)h除的節(jié)點(diǎn)的值
5)刪除找到的3)
通過上面步驟它們都有一個(gè)共同特點(diǎn)就是需要找到刪除的節(jié)點(diǎn)和要?jiǎng)h除節(jié)點(diǎn)的父節(jié)點(diǎn),所以我們可以把這兩個(gè)找節(jié)點(diǎn)都寫成方法:
找到刪除節(jié)點(diǎn)代碼如下(通過遞歸的方式找到要?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ù)以上步驟寫刪除方法代碼:
//二叉樹刪除節(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.沒有找到要?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í),我們選擇找刪除節(jié)點(diǎn)右子樹的最小值,我們可以寫一個(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í),我們選擇找刪除節(jié)點(diǎn)右子樹的最小值,我們可以寫一個(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)配置問題
這篇文章主要介紹了springboot啟動(dòng)mongoDB報(bào)錯(cuò)之禁用mongoDB自動(dòng)配置問題,具有很好的參考價(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-07mybatis-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-07Java數(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)、開發(fā)環(huán)境配置等,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12Java實(shí)現(xiàn)企業(yè)員工管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)企業(yè)員工管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02