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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

二叉查找树BST----java实现

發布時間:2024/6/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉查找树BST----java实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 二叉查找樹BST----java實現

1.二叉查找樹簡單介紹

二叉查找樹又名二叉搜索樹和二叉排序樹。性質例如以下:

?

在二叉查找樹中:
(01) 若隨意節點的左子樹不空,則左子樹上全部結點的值均小于它的根結點的值。
(02) 隨意節點的右子樹不空,則右子樹上全部結點的值均大于它的根結點的值;
(03) 隨意節點的左、右子樹也分別為二叉查找樹。


(04) 沒有鍵值相等的節點(no duplicate nodes)。

2.二叉查找樹節點類

class TreeNode {int value;TreeNode parent;TreeNode left;TreeNode right;public TreeNode(int value, TreeNode parent, TreeNode left, TreeNode right) {this.value = value;this.parent = parent;this.left = left;this.right = right;} }

3.遍歷

? ?二叉查找樹的遍歷同二叉樹的遍歷,遞歸與非遞歸方法詳見二叉樹的遞歸遍歷和非遞歸遍歷(附具體樣例)

4.最大和最小值

a.BST中的最小值即最左的孩子。

//求BST的最小值public TreeNode getMin(TreeNode root){if(root==null)return null;while(root.left!=null)root=root.left; return root;}

b.BST中的最大值即最右的孩子。

//求BST的最大值public TreeNode getMax(TreeNode root){if(root==null)return null;while(root.right!=null)root=root.right;return root;}

5.前驅和后繼節點


ps:圖片來于網絡

a.BST中某節點前驅節點==小于該節點的全部節點中的最大值

前驅easy情形:5尋前驅 4

前驅復雜情形:11尋前驅 10

//查找BST中某節點的前驅節點.即查找數據值小于該結點的最大結點。public TreeNode preNode(TreeNode x){if(x==null)return null;// 假設x存在左孩子,則"x的前驅結點"為 "以其左孩子為根的子樹的最大結點"。

if(x.left!=null) return getMax(x.left); // 假設x沒有左孩子。

則x有下面兩種可能: // (01) x是"一個右孩子",則"x的前驅結點"為 "它的父結點"。 // (02) x是"一個左孩子",則 前驅節點為x的某一個祖先節點的父節點,并且該祖先節點是作為其父節點的右兒子 TreeNode p=x.parent; while(p!=null&&p.left==x) { x=p;//父節點置為新的x p=p.parent; //父節點的父節點置為新的父節點 } return p; }

b.BST中某節點后繼節點==大于該節點的全部節點中的最小值

后繼easy情形:5尋后繼 6

復雜情形:9尋后繼 10

?

//查找BST中某節點的后繼節點.即查找數據值大于該結點的最小結點。

public TreeNode postNode(TreeNode x) { if(x==null) return null; // 假設x存在右孩子,則"x的后繼結點"為 "以其右孩子為根的子樹的最小結點"。 if(x.left!=null) return getMin(x.right); // 假設x沒有右孩子。則x有下面兩種可能: // (01) x是"一個左孩子",則"x的后繼結點"為 "它的父結點"。 // (02) x是"一個右孩子",則 前驅節點為x的某一個祖先節點的父節點,并且該祖先節點是作為其父節點的左兒子 TreeNode p=x.parent; while(p!=null&&p.right==x) { x=p;//父節點置為新的x p=p.parent; //父節點的父節點置為新的父節點 } return p; }


6.查找

查找值為val的節點,假設小于根節點在左子樹查找,反之在右子樹查找

//查找值為val的節點 --遞歸版--public TreeNode searchRec(TreeNode root ,int val){if(root==null)return root;if(val<root.value)return searchRec(root.left,val);else if(val>root.value)return searchRec(root.right,val);elsereturn root;}//查找值為val的節點 --非 遞歸版--public TreeNode search(TreeNode root ,int val){if(root==null)return root;while(root!=null){if(val<root.value)root=root.left;else if(val>root.value)root=root.right;elsereturn root;}return root;}

7.插入

a.若當前的二叉查找樹為空,則插入的元素為根節點?

b.若插入的元素值小于根節點值。則將元素插入到左子樹中

c.若插入的元素值不小于根節點值,則將元素插入到右子樹中。首先找到插入的位置,要么向左,要么向右,直到找到空結點,即為插入位置,假設找到了同樣值的結點,插入失敗。

?

//BST插入節點 --遞歸版--public TreeNode insertRec(TreeNode root,TreeNode x){if(root==null)root=x;else if(x.value<root.value)root.left=insertRec(root.left, x);else if(x.value>root.value)root.right=insertRec(root.right, x);return root;}//BST插入節點 --非 遞歸版--public TreeNode insert(TreeNode root,TreeNode x){if(root==null)root=x;TreeNode p=null;//須要記錄父節點while(root!=null)//定位插入的位置{p=root;//記錄父節點if(x.value<root.value)root=root.left;elseroot=root.right;}x.parent=p;//定位到合適的頁節點的空白處后。依據和父節點的大小比較插入合適的位置if(x.value<p.value) p.left=x;else if(x.value>p.value)p.right=x;return root;}

8.刪除

二叉查找樹的刪除,分三種情況進行處理:
1.p為葉子節點。直接刪除該節點,再改動其父節點的指針(注意分是根節點和不是根節點),如圖a。
2.p為單支節點(即僅僅有左子樹或右子樹)。

讓p的子樹與p的父親節點相連,刪除p就可以。(注意分是根節點和不是根節點);如圖b。


3.有兩個孩子的情況,當前結點與左子樹中最大的元素交換。然后刪除當前結點。左子樹最大的元素一定是葉子結點,交換后。當前結點即為葉子結點。刪除參考沒有孩子的情況。還有一種方法是,當前結點與右子樹中最小的元素交換,然后刪除當前結點。如圖c。



ps:圖片來于網絡


//BST刪除節點public void delete(TreeNode root,TreeNode x){if(root==null)return ;TreeNode p=null;while(root!=null)//定位到須要刪除的節點{if(x.value<root.value){p=root;//記錄父節點root=root.left;}else if(x.value>root.value){p=root;//記錄父節點root=root.right;}else//找到啦{if(root.left==null&&root.right==null)//①待刪除的是 葉子節點{if(p==null)//待刪除的是根節點root=null;else{if(p.left==root)p.left=null;else if(p.right==root)p.right=null;}}else if(root.left!=null&&root.right==null)//② 待刪除的節點僅僅有左孩子{if(p==null)//待刪除的是根節點root=root.left;else{if(p.left==root)//待刪除的本身是一個左孩子p.left=root.left;else if(p.right==root)p.right=root.left;}}else if(root.left==null&&root.right!=null)//② 待刪除的節點僅僅有右孩子{if(p==null)//待刪除的是根節點root=root.right;else{if(p.left==root)//待刪除的本身是一個左孩子p.left=root.right;else if(p.right==root)p.right=root.right;}}else//③待刪除的節點即有左孩子又有右孩子 方法:得到待刪除節點右子樹的最小值。 {//該最小值與待刪除節點進行“ 值 ”交換。刪除該最小值位置處的節點TreeNode rMin=root.right; //求待刪除節點的后繼節點,即待刪除節點的右孩子的最小值(找到的后繼節點肯定沒有左孩子!!。)TreeNode rMinP=null;//由于須要刪除后繼節點位置,所以須要記錄父節點while(rMin!=null){rMinP=rMin;rMin=rMin.left;}int rootVtemp=root.value;//值交換root.value=rMin.value;rMin.value=rootVtemp;//刪除rMin位置的節點,此時此位置的值已是待刪節點的值if(rMinP.left==rMin)rMinP.left=rMin.right;else if(rMinP.right==rMin)rMinP.right=rMin.right;}}break;//找到后刪了后就跳出while循環}}

9.二叉樹查找樹常見面試題

a.推斷一個數組是不是二叉搜索樹的后序遍歷

package com.sheepmu;public class Offer24 {public static void main(String[] args){int[] a={5,7,6,9,11,10,8};int len=a.length;System.out.println(isProOfBST(a,len));}public static boolean isProOfBST(int[] a,int len) {if(a==null||len<=0)return false;int root=a[len-1];//后序遍歷的最后一個為根節點int i=0;while(a[i]<root)//找到左樹的個數i++;int j=i;//先看右樹中是否有非法數字,即比根節點小的數字while(j<len-1){if(a[j]<root)return false;j++;}//若左右子樹的數字都合法,即左子樹都比根的值小,右子樹都比根節點大;此時僅僅需遞歸推斷左右子樹是否是二叉搜索樹的后序遍歷//求左右子樹的數組,到這兒明顯發現用字符串非常爽呀直接subString()boolean left=true;if(i>0)//必需要推斷是否存在左樹{int[] aleft=new int[i];for(int x=0;x<i;x++) aleft[x]=a[x];left=isProOfBST(aleft,i);}boolean right=true;if(i<len-1)//必需要推斷是否存在右樹{int[] aright=new int[len-i-1]; // for(int y=i;y<len-1;y++)//粗心啊!!。!

// { // aright[y]=a[y]; // } for(int y=0;y<len-i-1;y++) aright[y]=a[i+y]; right=isProOfBST(aright,len-i-1); } return left&&right; } }

b.將一顆二叉搜索樹轉為為排序的雙向鏈表



轉載于:https://www.cnblogs.com/gccbuaa/p/6785621.html

總結

以上是生活随笔為你收集整理的二叉查找树BST----java实现的全部內容,希望文章能夠幫你解決所遇到的問題。

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