日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构:二叉搜索树(BST)的基本操作

發布時間:2025/3/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构:二叉搜索树(BST)的基本操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

? 學習過數據結構的童鞋都應該知道,對樹的操作是一些最基本的技能(本文是對后面要寫B樹、B-樹、B+樹的一個前導,已經熟悉的朋友可以跳過了)。而在樹結構中,二叉樹又是最基礎的。雖然這些知識是比較基礎的,不過對于BST的操作中,刪除是一個相對比較麻煩的。這對于新手來說可能不太好理解,下面就以BST中節點的刪除為主,其他操作為輔的策略來編寫本篇文章。希望對你能有所幫助。

?

版權說明

著作權歸作者所有。
商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
作者:Q-WHai
發表日期: 2015年12月21日
鏈接:https://qwhai.blog.csdn.net/article/details/50366993
來源:CSDN
更多內容:分類 >> 算法與數學

?

基本操作:

1.插入

?

public void insert(int _value) {Node node = root;boolean inserted = false;while(!inserted) {if (_value == node.getValue()) {inserted = true;} else if (_value < node.getValue()) {Node leftNode = node.getLeft();if (leftNode == null) {leftNode = new Node(_value);node.setLeft(leftNode);inserted = true;} else {node = leftNode;}} else {Node rightNode = node.getRight();if (rightNode == null) {rightNode = new Node(_value);node.setRight(rightNode);inserted = true;} else {node = rightNode;}}}}

?

2.查找

? 這里就拿找到一個待刪除節點為例作說明。

?

private Node[] searchRemoveNode(int _value) {Node parentNode = null;Node removeNode = root;while(removeNode != null) {if (removeNode.getValue() == _value) {break;}if (removeNode.getValue() < _value) {parentNode = removeNode;removeNode = removeNode.getRight();}if (removeNode.getValue() > _value) {parentNode = removeNode;removeNode = removeNode.getLeft();}}return new Node[]{parentNode, removeNode};}

?

3.刪除

? 嗯,重點來了。

? 關于二叉搜索樹的刪除是相對比較麻煩的。這是為什么呢?我們知道二叉搜索可以快速查找某一個元素是否存在的原因,是BST遵循了一些規則。而我們麻煩的原因也正因為這個規則。

? 或許你會說,刪除有什么難的。直接記錄一下待刪除節點的左、右孩子節點,再遍歷孩子節點并按之前的方式插入到BST中不就是可以了么?有什么難的?

? 這是一個思路,但是不是太好,因為使用它我們總是會有一種提心吊膽的感覺。為什么?我們現在說明一種情況。比方說,我有一棵BST。它的待刪除節點是10000,左右孩子節點都有9999個節點。那么是不是就是說我們還要再把這9999 * 2個節點再插入到BST中呢?而且插入過程中還有對樹的遍歷。

? 說明上面那么太過生硬的方法之后,現在我就來說一個軟一點的方法。我們先來看下面的三張圖:

圖-1 刪除一個無子節點的節點

圖-2 刪除只有一個子節點的節點

圖-3 刪除有兩個子節點的節點

?

? 從上面的三張圖我們就可以看出,要刪除BST中的一個節點是要分情況討論的。在第一種情況中,沒什么好說的,就是直接刪除就OK。代碼如下:

?

private void removeNodeNoChild(Node parentNode, Node removeNode) {if (parentNode.getValue() == removeNode.getValue()) {return;} else if (parentNode.getValue() < removeNode.getValue()) {parentNode.setRight(null);} else {parentNode.setLeft(null);}}

? 在第二種方法中,我要刪除節點80。不過這個時候不能直接刪除,因為待刪除節點有一個子節點。我們把這個子節點掛到節點80的話父節點上就可以了。代碼如下:

?

private void removeNodeOneChild(Node parentNode, Node removeNode) {if (parentNode.getValue() == removeNode.getValue()) {return;}if (removeNode.getValue() < parentNode.getValue()) {// 父節點的左孩子parentNode.setLeft(removeNode.getLeft() == null ? removeNode.getRight() : removeNode.getLeft());} else {// 父節點的右孩子parentNode.setRight(removeNode.getLeft() == null ? removeNode.getRight() : removeNode.getLeft());}}

? 第三種情況就復雜一些。因為我們既不能直接刪除,也不能把節點30的子節點掛到節點30的父節點20上面(因為每個節點的右孩子只能有一個,而節點30有兩個孩子)。

?

? 我們的做法是找到待刪除節點(節點30)左孩子中最大的節點,這里我們打到了節點27。再把節點27來替換掉要刪除的節點30。這樣既快捷高效又保證不破壞BST的規則結構。代碼如下:

?

private void removeNodeTwoChild(Node parentNode, Node removeNode) {if (parentNode.getValue() == removeNode.getValue()) {return;}Node maxValueNode = maxValueNode(removeNode.getLeft());if (removeNode.getValue() < parentNode.getValue()) {// 父節點的左孩子parentNode.setLeft(maxValueNode);} else {// 父節點的右孩子parentNode.setRight(maxValueNode);}maxValueNode.setLeft(removeNode.getLeft());maxValueNode.setRight(removeNode.getRight());}

?

Demo源碼下載:

https://github.com/qwhai/simple-tree

?

征集

如果你也需要使用ProcessOn這款在線繪圖工具,可以使用如下邀請鏈接進行注冊:
https://www.processon.com/i/56205c2ee4b0f6ed10838a6d

總結

以上是生活随笔為你收集整理的数据结构:二叉搜索树(BST)的基本操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。