二叉查找树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.若插入的元素值不小于根節點值,則將元素插入到右子樹中。首先找到插入的位置,要么向左,要么向右,直到找到空結點,即為插入位置,假設找到了同樣值的結點,插入失敗。
?
8.刪除
二叉查找樹的刪除,分三種情況進行處理:
1.p為葉子節點。直接刪除該節點,再改動其父節點的指針(注意分是根節點和不是根節點),如圖a。
2.p為單支節點(即僅僅有左子樹或右子樹)。
讓p的子樹與p的父親節點相連,刪除p就可以。(注意分是根節點和不是根節點);如圖b。
3.有兩個孩子的情況,當前結點與左子樹中最大的元素交換。然后刪除當前結點。左子樹最大的元素一定是葉子結點,交換后。當前結點即為葉子結點。刪除參考沒有孩子的情況。還有一種方法是,當前結點與右子樹中最小的元素交換,然后刪除當前結點。如圖c。
ps:圖片來于網絡
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实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core 简单实现七牛图
- 下一篇: 20169214 2016-2017-2