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)));
}
}