JAVA數據結構--二叉查找樹
阿新 • • 發佈:2017-11-27
true 暫時 技術 單個 二叉 compare opened 鍵值 extends
二叉查找樹定義
二叉查找樹(英語:Binary Search Tree),也稱二叉搜索樹、有序二叉樹(英語:ordered binary tree),排序二叉樹(英語:sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
- 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
- 若任意節點的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;
- 任意節點的左、右子樹也分別為二叉查找樹;
- 沒有鍵值相等的節點。
二叉查找樹相比於其他數據結構的優勢在於查找、插入的時間復雜度較低。為O(log n)。
三層二叉查找樹
二叉查找樹的操作主要是運用的遞歸的思想,可操作的Object類必須繼承了Comparable接口,個人實現查找樹主要是參考了《數據結構與算法分析》這本書。因為遍歷涉及到三種遍歷方式,所以屆時單獨開一篇。
樹的結點定義
1 private static class BinaryNode<T>{ 2 BinaryNode(T theElement) { 3 this(theElement,null,null); 4 } 5 BinaryNode(T theElement,BinaryNode<T> lt,BinaryNode<T> rt) { 6 element=theElement; 7 left=lt; 8 right=rt;9 } 10 T element;//根節點 11 BinaryNode<T> left;//左子樹 12 BinaryNode<T> right;//右子樹 13 }
contains方法
1 private boolean contains(T x,BinaryNode<T> t){ 2 if(t==null) 3 return false; 4 int compareResult=x.compareTo(t.element);5 if(compareResult<0) 6 return contains(x,t.left); //遞歸 7 else if (compareResult>0) { 8 return contains(x, t.right); 9 } 10 else { 11 return true; 12 } 13 }
contains方法主要是查找當前二叉樹是否還有某個節點,利用了comparaTo方法遞歸調用。
findMin()與findMax()方法
1 private BinaryNode<T> findMin(BinaryNode<T> t){ 2 //非遞歸寫法 3 if(t!=null) 4 while(t.left!=null) 5 t=t.left; 6 return t; 7 //遞歸寫法 8 /*if(t==null) 9 return null; 10 else if (t.left==null) { 11 return t; 12 } 13 return findMin(t.left);*/ 14 }
findMin與findMax方法類似,這裏只列出一種即可。然後仍有兩種方法解決此問題,一種為遞歸,一種非遞歸。
非遞歸方法就是采用了while循壞思想,直到找出最左的節點即可。
insert方法
1 private BinaryNode<T> insert(T x,BinaryNode<T> t){ 2 if(t==null)//生成新的節點 3 return new BinaryNode<T>(x, null, null); 4 if(contains(x))//如果二叉樹中已經有x元素,則不進行任何操作 5 return t; 6 else { 7 int compareResult=x.compareTo(root.element); 8 if(compareResult<0){ 9 t.left=insert(x, t.left); 10 } 11 else { 12 t.right=insert(x, t.right); 13 } 14 return t; 15 } 16 }
remove方法
1 private BinaryNode<T> remove(T x,BinaryNode<T> t){ 2 if(t==null) 3 return t; 4 int compareResult=x.compareTo(t.element); 5 if(compareResult<0){ 6 t.left=remove(x, t.left); 7 } 8 else if(compareResult>0){ 9 t.right=remove(x, t.right); 10 } 11 else if (t.left!=null&&t.right!=null) { //兩個孩子情況,采取懶惰刪除 12 t.element=findMin(t.right).element; 13 t.right=remove(t.element, t.right); 14 } 15 else { //單個孩子情況 16 t=(t.left!=null)?t.left:t.right; 17 } 18 return t; 19 }
刪除節點時需要考慮兩種情況,一種為兩個孩子的情況,一種為單個孩子的情況。
如圖為刪除5節點為單個孩子情況
此圖是刪除3節點兩個孩子的情況,具體做法是找出該節點右子樹中最小的節點替換當前刪除的節點
全部的代碼如下(暫缺遍歷)
1 package Tree; 2 3 public class BinarySearchTree<T extends Comparable<? super T>> { 4 private static class BinaryNode<T>{ 5 BinaryNode(T theElement) { 6 this(theElement,null,null); 7 } 8 BinaryNode(T theElement,BinaryNode<T> lt,BinaryNode<T> rt) { 9 element=theElement; 10 left=lt; 11 right=rt; 12 } 13 T element;//根節點 14 BinaryNode<T> left;//左子樹 15 BinaryNode<T> right;//右子樹 16 } 17 private BinaryNode<T> root;//定義根節點 18 public BinarySearchTree() { 19 root=null; 20 } 21 public void makeEmpty(){ 22 root=null; 23 } 24 public boolean isEmpty(){ 25 return root==null; 26 } 27 public boolean contains(T x){ 28 return contains(x,root); 29 } 30 public T findMin() throws Exception{ 31 if(isEmpty()) 32 throw new Exception(); 33 return findMin(root).element; 34 } 35 public T findMax() throws Exception{ 36 if(isEmpty()) 37 throw new Exception(); 38 return findMax(root).element; 39 } 40 public void insert(T x){ 41 root=insert(x,root); 42 } 43 public void remove(T x){ 44 root=remove(x,root); 45 } 46 private boolean contains(T x,BinaryNode<T> t){ 47 if(t==null) 48 return false; 49 int compareResult=x.compareTo(t.element); 50 if(compareResult<0) 51 return contains(x,t.left); //遞歸 52 else if (compareResult>0) { 53 return contains(x, t.right); 54 } 55 else { 56 return true; 57 } 58 } 59 private BinaryNode<T> findMin(BinaryNode<T> t){ 60 //非遞歸寫法 61 if(t!=null) 62 while(t.left!=null) 63 t=t.left; 64 return t; 65 //遞歸寫法 66 /*if(t==null) 67 return null; 68 else if (t.left==null) { 69 return t; 70 } 71 return findMin(t.left);*/ 72 } 73 private BinaryNode<T> findMax(BinaryNode<T> t){ 74 if(t!=null) 75 while(t.right!=null) 76 t=t.right; 77 return t; 78 } 79 private BinaryNode<T> insert(T x,BinaryNode<T> t){ 80 if(t==null)//生成新的節點 81 return new BinaryNode<T>(x, null, null); 82 if(contains(x))//如果二叉樹中已經有x元素,則不進行任何操作 83 return t; 84 else { 85 int compareResult=x.compareTo(root.element); 86 if(compareResult<0){ 87 t.left=insert(x, t.left); 88 } 89 else { 90 t.right=insert(x, t.right); 91 } 92 return t; 93 } 94 } 95 private BinaryNode<T> remove(T x,BinaryNode<T> t){ 96 if(t==null) 97 return t; 98 int compareResult=x.compareTo(t.element); 99 if(compareResult<0){ 100 t.left=remove(x, t.left); 101 } 102 else if(compareResult>0){ 103 t.right=remove(x, t.right); 104 } 105 else if (t.left!=null&&t.right!=null) { //兩個孩子情況,采取懶惰刪除 106 t.element=findMin(t.right).element; 107 t.right=remove(t.element, t.right); 108 } 109 else { //單個孩子情況 110 t=(t.left!=null)?t.left:t.right; 111 } 112 return t; 113 } 114 115 }View Code
也可訪問我的gihub數據結構的部分,暫時內容較少。
JAVA數據結構--二叉查找樹