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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

排序二叉树BST(binary search/sort tree)

發(fā)布時(shí)間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 排序二叉树BST(binary search/sort tree) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

之前介紹說(shuō),樹這種存儲(chǔ)結(jié)構(gòu),能提高數(shù)據(jù)的存儲(chǔ),讀取效率。所以樹的應(yīng)用就可以體現(xiàn)在排序這一方面,比如有排序二叉樹,平衡二叉樹,紅黑樹等。本文介紹排序二叉樹。

為啥有排序二叉樹(二叉搜索樹)的出現(xiàn)?這要從二分查找算法說(shuō)起:

1.排序二叉樹是一種特殊結(jié)構(gòu)的二叉樹,可以非常方便地對(duì)樹中所有節(jié)點(diǎn)進(jìn)行排序和檢索。 2.排序二叉樹要么是一棵空二叉樹,要么是具有下列性質(zhì)的二叉樹: 3.若它的左子樹不空,則左子樹上所有節(jié)點(diǎn)的值均小于它的根節(jié)點(diǎn)的值; 4.若它的右子樹不空,則右子樹上所有節(jié)點(diǎn)的值均大于它的根節(jié)點(diǎn)的值; 5.它的左、右子樹也分別為排序二叉樹。 6.插入值與當(dāng)前節(jié)點(diǎn)比較,如果相同,表示已經(jīng)存在了,不能再插入。(即排序二叉樹不能存在值相同的點(diǎn))

排序二叉樹:

BST樹的搜索

BST樹的搜索,從根結(jié)點(diǎn)開始,如果查詢的關(guān)鍵字與結(jié)點(diǎn)的關(guān)鍵字相等,那么就命中;否則,如果查詢關(guān)鍵字比結(jié)點(diǎn)關(guān)鍵字小,就進(jìn)入左子節(jié)點(diǎn);如果比結(jié)點(diǎn)關(guān)鍵字大,就進(jìn)入右子節(jié)點(diǎn);如果左子節(jié)點(diǎn)或右子節(jié)點(diǎn)的指針為空,則報(bào)告找不到相應(yīng)的關(guān)鍵字;如果BST樹的所有非葉子結(jié)點(diǎn)的左右子樹的結(jié)點(diǎn)數(shù)目均保持差不多(平衡),那么B樹的搜索性能逼近二分查找;但它比連續(xù)內(nèi)存空間的二分查找的優(yōu)點(diǎn)是,改變BST樹結(jié)構(gòu)(比如插入與刪除結(jié)點(diǎn))無(wú)需移動(dòng)大段的內(nèi)存數(shù)據(jù),甚至通常是常數(shù)開銷。

如上圖:右邊也是一個(gè)BST樹,但它的搜索性能已經(jīng)是線性的了;同樣的關(guān)鍵字集合有可能導(dǎo)致不同的樹結(jié)構(gòu)索引;所以,使用BST樹還要考慮盡可能讓BST樹保持左圖的結(jié)構(gòu),和避免右圖的結(jié)構(gòu),也就是所謂的“平衡”問(wèn)題;解決方案就是平衡二叉樹了。

BST的創(chuàng)建

創(chuàng)建排序二叉樹的步驟,也就是不斷地向排序二叉樹添加節(jié)點(diǎn)的過(guò)程,向排序二叉樹添加節(jié)點(diǎn)的步驟如下:
以根節(jié)點(diǎn)當(dāng)前節(jié)點(diǎn)開始搜索。
拿新節(jié)點(diǎn)的值和當(dāng)前節(jié)點(diǎn)的值比較。
如果新節(jié)點(diǎn)的值更大,則以當(dāng)前節(jié)點(diǎn)的右子節(jié)點(diǎn)作為新的當(dāng)前節(jié)點(diǎn);如果新節(jié)點(diǎn)的值更小,則以當(dāng)前節(jié)點(diǎn)的左子節(jié)點(diǎn)作為新的當(dāng)前節(jié)點(diǎn)。
重復(fù) 2、3 兩個(gè)步驟,直到搜索到合適的葉子節(jié)點(diǎn)為止。
將新節(jié)點(diǎn)添加為第 4 步找到的葉子節(jié)點(diǎn)的子節(jié)點(diǎn);如果新節(jié)點(diǎn)更大,則添加為右子節(jié)點(diǎn);否則添加為左子節(jié)點(diǎn)。

BST刪除節(jié)點(diǎn)

當(dāng)程序從排序二叉樹中刪除一個(gè)節(jié)點(diǎn)之后,為了讓它依然保持為排序二叉樹,程序必須對(duì)該排序二叉樹進(jìn)行維護(hù)。維護(hù)可分為如下幾種情況:

  • (1)被刪除的節(jié)點(diǎn)是葉子節(jié)點(diǎn),則只需將它從其父節(jié)點(diǎn)中刪除即可。
  • (2)被刪除節(jié)點(diǎn) p 只有左子樹,將 p 的左子樹 添加成 p 的父節(jié)點(diǎn)的左子樹即可;被刪除節(jié)點(diǎn) p 只有右子樹,將 p的右子樹添加成p 的父節(jié)點(diǎn)的右子樹即可。
  • (3)若被刪除節(jié)點(diǎn) p的左、右子樹均非空,直至讓其中序后繼結(jié)點(diǎn)頂上去。

代碼:

  • 結(jié)點(diǎn)類
  • class TreeNode{public int data;public TreeNode left;public TreeNode right;TreeNode(int data){this.data=data;} }
  • 樹類
    插入結(jié)點(diǎn):遞歸方式
  • public boolean AddTreeNode1(TreeNode root, int data){TreeNode treeNode=new TreeNode(data);//樹為空if(root==null){root=treeNode;return true;}//比根節(jié)點(diǎn)小,插入到左子樹if(root.data>data){//當(dāng)根結(jié)點(diǎn)左節(jié)點(diǎn)非空時(shí),要繼續(xù)遞歸插入 if (root.left == null) {root.left = treeNode;return true;} else {return AddTreeNode1(root.left, data);}}//比根節(jié)點(diǎn)大,插入到右子樹else if (root.data < data) {//當(dāng)根結(jié)點(diǎn)右節(jié)點(diǎn)非空時(shí),要繼續(xù)遞歸插入 if (root.right == null) {root.right = treeNode;return true;} else {return AddTreeNode1(root.right, data);}} else {}return false;}

    查找結(jié)點(diǎn)

    public boolean SearchTreeNode(TreeNode root, int data){if(root==null){return false;}else if(root.data==data){return true;}else if(root.data>data){return SearchTreeNode(root.left,data);}else{return SearchTreeNode(root.right,data);}}

    刪除結(jié)點(diǎn)

    public boolean DeleteNode(TreeNode root, int data){//current為查找得到的節(jié)點(diǎn)TreeNode current=root;//parent為時(shí)刻更新父節(jié)點(diǎn)TreeNode parent=root;//tempParent為同時(shí)存在左右子樹的迭代臨時(shí)父節(jié)點(diǎn)TreeNode tempParent=root;//isLeft記錄current節(jié)點(diǎn)的左右屬性boolean isLeft=true;while(current.data!=data){parent=current;//到左子樹查找if(current.data>data){isLeft=true;current=current.left;}else if(current.data<data){ //到右子樹查找isLeft=false;current=current.right;}//查不到,返回falseif(current==null) {return false;}}//第一種情況:刪除節(jié)點(diǎn)為葉節(jié)點(diǎn)if(current.left==null && current.right==null){if(current==root) {root=null;}if(isLeft) {parent.left = null;}else{parent.right = null;}return true;}else if(current.right==null){ //第二種情況:刪除節(jié)點(diǎn)只有左節(jié)點(diǎn)if(current==root) {root=current.left;} else if(isLeft) {parent.left=current.left;} else {parent.right=current.left;}return true;}else if(current.left==null){ //第三種情況:刪除節(jié)點(diǎn)只有右節(jié)點(diǎn)if(current==root) {root=current.right;} else if(isLeft) {parent.left=current.right;} else {parent.right=current.right;}return true;}else{ //第四種情況:刪除節(jié)點(diǎn)均存在左節(jié)點(diǎn)和右節(jié)點(diǎn)if(current==root){root=root.left;}TreeNode tempNode=current.left;//沒(méi)有左節(jié)點(diǎn)if(tempNode.right==null){if(isLeft) {parent.left=tempNode;} else {parent.right=tempNode;}}else{ //存在左節(jié)點(diǎn),迭代到最右側(cè)子節(jié)點(diǎn),即直接前驅(qū)while(tempNode.right!=null){tempParent=tempNode;tempNode=tempNode.right;}if(isLeft){ //為左節(jié)點(diǎn),連接parent.left=tempNode;parent.left.left=current.left;}else{ //為右節(jié)點(diǎn),連接parent.right=tempNode;parent.right.left=current.left;}//刪除前驅(qū)節(jié)點(diǎn),連接if(tempNode.left==null) {tempParent.right=null;} else {tempParent.right=tempNode.left;}}return true;}}

    本文參考1
    本文參考2

    總結(jié)

    以上是生活随笔為你收集整理的排序二叉树BST(binary search/sort tree)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。