1. 程式人生 > >java資料結構二叉樹的遍歷和二叉查詢樹

java資料結構二叉樹的遍歷和二叉查詢樹

資料結構

**一、實驗目的
1、掌握二叉樹的特點及其儲存方式;
2、掌握二叉樹的建立;
3、掌握二叉樹前序、中序、後序遍歷的基本方法及應用;
4、掌握二叉查詢樹的特點;
5、掌握二叉查詢樹查詢(包含contain)、插入和刪除操作的實現。
二、實驗內容
1、用前序方法建立一棵二叉樹;
2、實現前序、中序和後序遍歷二叉樹的操作;
3、實現統計二叉樹葉子結點個數或計算二叉樹深度的操作;
4、將輸入的一組資料逐個插入實現建立二叉查詢樹;
5、用非遞迴實現二叉查詢樹的查詢和刪除操作。
三、實驗環境
eclipse環境
四、實驗步驟
1、二叉連結串列節點類的定義;
2、二叉樹類的定義;
3、建立下圖所示的二叉樹

以字串的形式“根左右”定義一棵二叉樹時,寫出建立二叉樹的操作:
4、程式設計實現以上二叉樹的前序、中序和後序遍歷操作,輸出遍歷序列;
5、完成統計以上二叉樹中葉子結點的個數或計算以上二叉樹的深度;
6、定義二叉查詢樹類;實現二叉查詢樹的查詢、插入和刪除操作;
7、從鍵盤上輸入六個整數45、24、53、12、37、9構造二叉查詢樹,輸出二叉查詢樹的中序遍歷結果;
8、在二叉查詢樹上查詢37和50,並輸出能否查詢成功;
9、刪除資料元素24和53,輸出其中序遍歷結果。
五、問題討論
1、先序、中序、後序遍歷二叉樹的區別?
2、在先序、中序非遞迴演算法中為什麼使用棧?能不能借助其它資料結構來實現?
3、二叉查詢樹中序遍歷結果有什麼特點?
4、在二叉查詢樹中插入一個新結點,總是插入到葉結點下面嗎?
5、在任意一棵非空二叉查詢樹中,刪除某結點後又將其插入,則所得二叉查詢樹與原二叉查詢樹相同嗎?
六、實驗報告內容
1、實驗目的
2、實驗內容和具體要求
3、完成情況和實驗記錄,實驗記錄為實驗過程中遇到的問題及解決方法
4、程式清單
5、所輸入的資料及相應的執行結果
6、問題討論回答
7、實驗心得**

原始碼:
package 實驗二;

//二叉樹的建立、前序、中序、後序遍歷、統計葉子節點以及計算二叉樹的深度

public class Test2 <AnyType extends Comparable<?super AnyType>>{
    BTNode<AnyType> rootNode=new BTNode<AnyType>();
    int i=0;
    int count=0;
    static BTNode root;

    //二叉樹節點類的初始化
    public static class BTNode<AnyType>{
        public
BTNode<AnyType> leftchild; public BTNode<AnyType> rightchild; public AnyType data; BTNode(){ this.data=null; this.leftchild=rightchild=null; } BTNode(AnyType thedata){ this.data=thedata; this.leftchild=rightchild=null; } public BTNode<AnyType> getleftChild( ){ return leftchild; } public BTNode<AnyType> getrightChild( ){ return rightchild; } public Object getdata( ){ return data; } } //二叉樹的建立 public BTNode<AnyType>CreateBinaryTree(AnyType[] st){ BTNode<AnyType> rootNode=null; if(i<st.length){ if (st[i]=="*"){ rootNode = null; i++; } else{ AnyType data=st[i]; i++; rootNode=new BTNode<AnyType>(data); rootNode.leftchild=CreateBinaryTree(st); rootNode.rightchild=CreateBinaryTree(st); } } return rootNode; } //二叉樹的前序遍歷void的直接輸出 public void FontOrder(BTNode<AnyType> t){ if(t!=null){ System.out.print(t.data+" "); FontOrder(t.leftchild); FontOrder(t.rightchild); } } //二叉樹的中序遍歷void型別直接輸出 public void MiddleOrder(BTNode<AnyType> t){ if(t!=null) { MiddleOrder(t.leftchild); System.out.print(t.data+" "); MiddleOrder(t.rightchild); } } //二叉樹的後序遍歷void型別直接輸出 public void Behind( BTNode<AnyType> t){ if(t!=null) { Behind(t.leftchild); Behind(t.rightchild); System.out.print(t.data+" "); } } //二叉樹得到二叉樹的葉子節點數返回int型別 public int Getleaves(BTNode<AnyType> rootNode ){ int left,right; if(rootNode==null) return 0; left = Getleaves(rootNode.leftchild); right = Getleaves(rootNode.rightchild); if(left<right){ return right+1; }else return left+1; } //二叉樹計算深度返回int型別 public int Getdepth(BTNode<AnyType> rootNode ){ if(rootNode!=null) { count++; Getdepth(rootNode.leftchild); Getdepth(rootNode.rightchild); } return count/2; } //Test2的main方法人口實現實驗要求的二叉樹 public static void main(String[] args) { String[] st={"a","b","d","*","c","e","*","f"}; Test2 answer=new Test2(); //實驗第一問實現二叉樹 root=answer.CreateBinaryTree(st); System.out.println("二叉樹的前序遍歷:"); answer.FontOrder(root); System.out.println( "\n二叉樹的中序遍歷:"); answer.MiddleOrder(root); System.out.println("\n二叉樹的後序遍歷:"); answer.Behind(root); System.out.println("\n二叉樹的深度:"); System.out.println(answer.Getdepth(root)); System.out.println("二叉樹的葉子節點數:"); System.out.println(answer.Getleaves(root)); } } /*二叉樹的前序遍歷: a b d c e f 二叉樹的中序遍歷: d e f c b a 二叉樹的後序遍歷: f e c d b a 二叉樹的葉子節點數: 6*/ package 實驗二; //二叉查詢樹的節點類 class BinaryNode<AnyType>{ AnyType element; BinaryNode<AnyType> left; BinaryNode<AnyType> right; BinaryNode(AnyType theelement){ element=theelement; left=right=null; } BinaryNode(AnyType theelement,BinaryNode<AnyType> lt,BinaryNode<AnyType>rt){ element=theelement; left=lt; right=rt; } } //二叉查詢樹數值的插入,查詢以及刪除操作 public class BinaryTree<AnyType extends Comparable<? super AnyType>> { private BinaryNode<AnyType> root; public boolean isEmpty(){ return root==null; } //判斷到底查詢到不到,若存在數值那麼返回true並告訴查詢到。 public boolean contains(AnyType x){ return contains(x,root); } private boolean contains(AnyType x,BinaryNode<AnyType>t){ if(t==null){ System.out.println("親,你要的資料不存在哦!"); return false;} int result=x.compareTo(t.element); if(result<0) return contains(x,t.left); else if(result>0) return contains(x,t.right); else{ System.out.println("找到了!"); return true; } } public AnyType findMin() throws Exception{ if(isEmpty())throw new Exception("錯誤提示:當前二叉查詢樹為空!"); return findMin(root).element; } //查詢到二叉查詢樹中最小數,然後刪除的時候用的到 private BinaryNode<AnyType>findMin(BinaryNode<AnyType> t){ if(t==null) return null; else if(t.left==null) return t; return findMin(t.left); } public void insert(AnyType x){ root=insert(x,root); } //按照要求逐個的插入到二叉查詢樹中 private BinaryNode<AnyType>insert(AnyType x,BinaryNode<AnyType>t){ if(t==null) return new BinaryNode<AnyType>(x,null,null); int compareresult=x.compareTo(t.element); if(compareresult<0) t.left=insert(x,t.left); else if(compareresult>0) t.right=insert(x,t.right); else ; return t; } //按照要求實現插入後、刪除後的中序遍歷操作 public void MiddleOrder(){ if(root!=null) MiddleOrder(root); } public void MiddleOrder(BinaryNode <AnyType> t){ if(t!=null){ MiddleOrder(t.left); System.out.print(" "+ t.element); MiddleOrder(t.right); } } //按照要求實現二叉查詢樹的刪除 public void remove(AnyType x){ if(root!=null) remove(x,root); } public BinaryNode<AnyType>remove(AnyType x,BinaryNode<AnyType>t){ if(t==null) return t; int comresult=x.compareTo(t.element); if(comresult<0) t.left=remove(x,t.left); else if(comresult>0) t.right=remove(x,t.right); else if(t.left!=null&&t.right!=null){ t.element=findMin(t.right).element; t.right=remove(t.element,t.right); } else t=(t.left!=null)?t.left:t.right; return t; } public static void main(String [] args){ BinaryTree r=new BinaryTree(); BinaryNode tree = null; Integer [] str={45,24,53,12,37,9}; for(int i=0;i<str.length;i++){ r.insert(str[i]); } System.out.print("中序遍歷為:"); r.MiddleOrder(); System.out.println("\n查詢數值37的查詢結果:"); r.contains(37); System.out.println("查詢數字50的查詢結果:"); r.contains(50); System.out.println("刪除24的操作的中序遍歷為:"); r.remove(24); r.MiddleOrder(); System.out.println("\n刪除53的操作的中序遍歷為:"); r.remove(53); r.MiddleOrder(); } /* 中序遍歷為: 9 12 24 37 45 53 查詢數值37的查詢結果: 找到了! 查詢數字50的查詢結果: 親,你要的資料不存在哦! 刪除24的操作的中序遍歷為: 9 12 37 45 53 刪除53的操作的中序遍歷為: 9 12 37 45 */ } package 實驗二; public class BITreeNode <AnyType> { AnyType data; BITreeNode<AnyType> leftchild,rightchild; BITreeNode(){ this.data=null; this.leftchild=rightchild=null; } BITreeNode(AnyType thedata){ this.data=thedata; this.leftchild=rightchild=null; } /* BITreeNode(AnyType thedata,BITreeNode<AnyType> lt,BITreeNode<AnyType> rt){ data=thedata; leftchild=lt; rightchild=rt; } BITreeNode(AnyType data){ this(data,null,null); }*/ public BITreeNode<AnyType> getleftchild(){ return leftchild; } public BITreeNode<AnyType>getrightchild(){ return rightchild; } public Object getdata(){ return data; } public static class BINaryTree<AnyType extends Comparable<? super AnyType>>{ BITreeNode<AnyType>rootNode; int count=0; public BINaryTree(){ rootNode=null; } public BINaryTree(AnyType rootNodeItem){ rootNode.data=rootNodeItem; rootNode.leftchild=rootNode.rightchild=null; } public BINaryTree(BITreeNode<AnyType> t){ rootNode=t; } public boolean isEmpty(){ System.out.println("目前二叉查詢樹資料為空!"); return rootNode==null; } public void makeEmpty(){ rootNode=null; } public BITreeNode<AnyType> getrootNode(){ return rootNode; } public boolean contains(AnyType x){ return contains(x); } //找到最小數 public AnyType findMin(BITreeNode<AnyType> rootNode)throws Exception{ if(isEmpty()); if(rootNode.leftchild==null) return (AnyType) rootNode; return findMin(rootNode.leftchild); } //根左右 public void FontOrder(BITreeNode<AnyType> rootNode){ if(rootNode!=null){ System.out.println(" "+rootNode.data); FontOrder(rootNode.leftchild); FontOrder(rootNode.rightchild); } } //左右根 public void MiddleOrder(BITreeNode<AnyType> rootNode){ if(rootNode!=null){ MiddleOrder(rootNode.leftchild); System.out.println(" "+rootNode.data); MiddleOrder(rootNode.rightchild); } } //左右根 public void BehindOrder(BITreeNode<AnyType> rootNode){ if(rootNode!=null){ BehindOrder(rootNode.leftchild); BehindOrder(rootNode.rightchild); System.out.println(" "+ rootNode.data); } } //統計節點個數 public int countleaves(BITreeNode<AnyType> rootNode){ if(rootNode!=null){ countleaves(rootNode.leftchild); countleaves(rootNode.rightchild); }else{ count++; } return count/2; } //統計二叉樹 的深度 public int getdepth(BITreeNode <AnyType> rootNode){ int left,right; if(rootNode==null) return 0; left=getdepth(rootNode.leftchild); right=getdepth(rootNode.rightchild); if(left<right){ return right+1; }else{ return left+1; } } //用中序構造二叉查詢樹 public BITreeNode<AnyType> CreateBINaryTree(int[] st){ BITreeNode<AnyType> rootNode=null; int i=0; if(i<st.length){ if(st[i]==-1){ rootNode=null; i++; }else{ int data=st[i]; i++; rootNode =new BITreeNode<AnyType>(null); rootNode.leftchild=CreateBINaryTree(st); rootNode.rightchild=CreateBINaryTree(st); } } return rootNode; } //查詢二叉樹中節點 public boolean Find(BITreeNode<AnyType> t,AnyType x){ if(t==null){ System.out.println("沒有辦法來查詢!"); }else{ while(t!=null){ int result=x.compareTo(t.data); if(result==0){ System.out.println("查詢到元素,在二叉樹中!"); return true; }else if(result>0){ t=t.rightchild; }else if(result<0){ t=t.leftchild; } } } return false; } } public static void main(String [] args ){ int [] st={45,24,53,12,37,9}; BINaryTree answer=new BINaryTree(); //實驗第一問實現二叉樹 answer.CreateBINaryTree(st); System.out.println("二叉樹的前序遍歷:"); answer.FontOrder( answer.CreateBINaryTree(st)); System.out.println( "\n二叉樹的中序遍歷:"); answer.MiddleOrder(answer.CreateBINaryTree(st)); System.out.println("\n二叉樹的後序遍歷:"); answer.BehindOrder(answer.CreateBINaryTree(st)); System.out.println("\n二叉樹的深度:"); System.out.println(answer.getdepth(answer.CreateBINaryTree(st))); System.out.println("二叉樹的葉子節點數:"); System.out.println(answer.countleaves(answer.CreateBINaryTree(st))); } }