二叉排序樹,又稱爲二叉查找樹。它或者是一棵空樹。或者具有以下性質
(1)若它的左子樹不空,則左子樹所有的結點的值均小於它的根結構的值。
(2)若它在右子樹不空,則右子樹上所有結點的值均大於它的根結點的值。
(3)它的左右子樹也均爲二叉排序樹。
本人採用java語言實現了二叉排序樹的基本操作。
算法實現的難點:
(1)必須在BST類定義兩個全局變量
private BitNode root;//定義二叉樹的根節點的全局變量
private BitNode p;//定義一個全局變量,方便查找替換變量,因爲JAVA語言沒有指針操作。
(2)二叉樹刪除結點的操作比較麻煩,因爲刪除後仍然保證是二叉樹,分爲三種情況
<1>爲葉子結點刪除
<2>僅有左或右子樹的結點
<3>左右子樹都有的結點。
心得體會:因爲java語言沒有C語言的簡潔優雅,所以爲了實現遞歸參數的傳遞,一般情況下在類裏面都是操作this 指針,或者傳遞root根結點,root結點 是樹的操作的起始部分,非常重要。
在傳遞參數過程中,時刻觀察是否初始化,是否多次實例化等等。
比如
public boolean DeleteBST(BitNode root,int key) { if(root==null) return false; else { if(key==root.data) return Delete(root); else if(key<root.data) return DeleteBST(root.lchild,key); else return DeleteBST(root.rchild,key); } } public boolean DeleteKey(int key) { //調用根結點的引用對象 if(DeleteBST( root, key)) return true; else return false; }
這樣既實現了函數的調用,又不破壞程序的封裝性。下面爲全部實現技術
package Search; //二叉排序樹的相關操作 class BST { private BitNode root;//定義二叉樹的根節點的全局變量 private BitNode p;//定義一個全局變量 private int N;//樹的結點個數 class BitNode { int data;//定義結點數據 BitNode lchild,rchild;//左右孩子指針 } //f指向樹的雙親,P爲全局查找變量,防止在傳遞過程恢復原值 public boolean SearchBST(BitNode root,int key,BitNode f) { if(root==null) { p=f; return false; } else if(key==root.data) { p=root; return true; } //左右遞歸查找 else if(key<root.data) return SearchBST(root.lchild, key,root); else return SearchBST(root.rchild, key,root); } //二叉排序樹的插入操作 public boolean InsertBST(int key) { BitNode s; p=null; if(!SearchBST(root,key,null)) { s=new BitNode(); s.data=key; s.lchild=s.rchild=null; if(p==null) { root=s;//插入S爲新結點,尾部插入法 } else if(key<p.data) { p.lchild=s;//小於的爲左孩子 } else { p.rchild=s;//大於的爲右孩子 } N++; return true; } else return false; } //插入一個數組的結點 public void creatbst(int arr[]) { for(int i=0;i<arr.length;i++) { InsertBST(arr[i]); } p=null;//將全局變量消除掉 } //從二叉排序樹中刪除結點p,並重接它的左或右子樹 public boolean Delete(BitNode p) { BitNode q,s; if(p.rchild==null)//右子樹爲空,只需要重接它的左子樹 { q=p; p=p.lchild; q=null; N--; } if(p.lchild==null)//左子樹爲空,只需要重接它的右子樹 { q=p; p=p.rchild; q=null; N--; } else//左右子樹均不爲空 { q=p; s=p.lchild; while(s.rchild!=null)//轉左然後向右找到盡頭 { q=s; s=s.rchild; } p.data=s.data;//用P的前驅或者後繼的值來替換刪除掉的位置的值 if(q!=p) { q.rchild=s.lchild;//重接Q的右子樹 } else { q.lchild=s.lchild;//重接Q的左子樹 } s=null; } N--; return true; } //若二叉排序樹中存在key結點,則刪除該結點 public boolean DeleteBST(BitNode root,int key) { if(root==null) return false; else { if(key==root.data) return Delete(root); else if(key<root.data) return DeleteBST(root.lchild,key); else return DeleteBST(root.rchild,key); } } public boolean DeleteKey(int key) { //調用根結點的引用對象 if(DeleteBST( root, key)) return true; else return false; } public int size() { return N; } } public class Binarysort { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub BST bst=new BST(); int arr[]={62,88,58,47,35,73,51,99,29,37,48,56,93,36,49,50}; bst.creatbst(arr); System.out.println(bst.size()); bst.DeleteKey(47); System.out.println(bst.size()); } }