建立二叉樹:層次遍歷--樹的寬度高度,後序遍歷--祖先節點

shuaishuai3409發表於2016-05-06

建立二叉樹,遍歷二叉樹.詳細介紹了層次遍歷和後序遍歷的應用.
層次遍歷:樹的高度,樹的寬度,每一層節點個數等
後序遍歷:根節點到某節點的路徑,兩個節點的最近公共祖先等


package tree;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class TreeADT {
    private String data=null;  
    private TreeADT  leftChild=null;  
    private TreeADT  rightChild=null;      

    public TreeADT (String data){

        this.data=data;  
        this.leftChild=null;  
        this.rightChild=null;  
    }  

    //建立一顆二叉樹
    public void createBinTree(TreeADT  root){  
    TreeADT  newNodeB = new TreeADT ("B");  
        TreeADT  newNodeC = new TreeADT ("C");  
        TreeADT  newNodeD = new TreeADT ("D");  
        TreeADT  newNodeE = new TreeADT ("E");  
        TreeADT newNodeF = new TreeADT ("F");  
        newNodeF.rightChild=new TreeADT("G");
        root.leftChild=newNodeB;  
        root.rightChild=newNodeC;  
        root.leftChild.leftChild=newNodeD;  
        root.leftChild.rightChild=newNodeE;  
        root.rightChild.rightChild=newNodeF;  
    }  
    //訪問節點資料
    public void visted(TreeADT subTree){   
        System.out.println(subTree.data);;  
        }
    //前序遞迴遍歷
    public void preOrder(TreeADT subTree){  
         if(subTree!=null){  
                visted(subTree);  
                preOrder(subTree.leftChild);  
                preOrder(subTree.rightChild);  
            }  
        }
    //非遞迴,前序遍歷.
    public void noPreOrder(TreeADT subTree){
         Stack <TreeADT>stack=new Stack<TreeADT>();
         TreeADT p=subTree;
         while(!stack.empty()||p!=null){
             if(p!=null){
                 visted(p);
                 stack.push(p);
                 p=p.leftChild;
             }
             else{
                 p=stack.pop();
                 p=p.rightChild;
             }

         }
     }
    //遞迴中序遍歷
    public void inOrder(TreeADT subTree){
        if(subTree!=null){
            inOrder(subTree.leftChild);
            visted(subTree);
            inOrder(subTree.rightChild);
        }
    }
    //非遞迴中序遍歷
    public void noInOrder(TreeADT subTree){
        Stack<TreeADT> stack=new Stack<TreeADT>();
        TreeADT p=subTree;
        while(p!=null||!stack.empty()){
            if(p!=null){
                stack.push(p);
                p=p.leftChild;
            }
            else{
                p=stack.pop();
                visted(p);
                p=p.rightChild;
            }
        }

    }
    //遞迴後序遍歷
    public void postOrder(TreeADT subTree){
        if(subTree!=null){
            postOrder(subTree.leftChild);
            postOrder(subTree.rightChild);
            visted(subTree);
        }
    }
    //非遞迴後序遍歷
    public void noPostOrder(TreeADT subTree){
        Stack<TreeADT>stack=new Stack<TreeADT>();
        TreeADT p=subTree;
        TreeADT r=null;
        while(p!=null||!stack.empty()){
            if(p!=null){
                stack.push(p);
                p=p.leftChild;
            }
            else{
                p=stack.peek();
                if(p.rightChild!=null&&p.rightChild!=r){
                    p=p.rightChild;
                    stack.push(p);
                    p=p.leftChild;
                }
                else{
                    p=stack.pop();
                    visted(p);
                    r=p;
                    p=null;
                }

            }
        }

    }
    //層次遍歷
    public void levelOrder(TreeADT subtree){
        TreeADT p=subtree;
        Queue <TreeADT>queue=new  LinkedList<TreeADT>();//介面不能直接例項化,需要物件上轉型;queue是個介面,而stack是個類。。
        queue.add(p);
        while(!queue.isEmpty()){
            p=queue.remove();//一定要儲存佇列的指標
            visted(p);
            if(p.leftChild!=null) queue.add(p.leftChild);
            if(p.rightChild!=null) queue.add(p.rightChild);

        }
    }
     //非遞迴實現樹的高度
    public void  high(TreeADT subTree){
        int front=0;int rear=0;TreeADT[] Q=new TreeADT [20];int last=1;int level=0;
        TreeADT p=subTree;
        Q[++rear]=p;
        while(front<rear){
            p=Q[++front];
            if(p.leftChild != null){
                Q[++rear]=p.leftChild;
            }
            if(p.rightChild!=null){
                Q[++rear]=p.rightChild;
            }
            if(front==last){
                level++;
                last=rear;
            }
        }
        System.out.println(level);
    }
    //非遞迴實現求樹的每一層寬度
    public void len(TreeADT subTree){
        int front=0,rear=0,level=0,last=1,count[]=new int [10];TreeADT[]Q=new TreeADT[20];
        count[0]=1;
        TreeADT p=subTree;
        Q[++rear]=p;
        while(front<rear){
            p=Q[++front];
            if(p.leftChild!=null) {Q[++rear]=p.leftChild;count[level+1]++;}
            if(p.rightChild!=null){Q[++rear]=p.rightChild;count[level+1]++;}
            if(front==last){
                level++;
                last=rear;
            }
        }
        for(int i=0;i<level;i++){
            System.out.println(count[i]);
        }

    }
    //遞迴實現樹的高度和寬度
    public int  iteratorHigh(TreeADT subTree){
        TreeADT p=subTree;
        if(p==null){
            return 0;
        }
        else return  iteratorHigh(p.leftChild)>iteratorHigh(p.rightChild)?1+iteratorHigh(p.leftChild):1+iteratorHigh(p.rightChild);
    }
    public static void main(String[] args) {
// TODO Auto-generated method stub
        TreeADT  root =new TreeADT ("A");
        root.createBinTree(root);
        //root.inOrder(root);
        //root.noInOrder(root);
       //root.postOrder(root);
        //root.noPostOrder(root);
        root.levelOrder(root);

}

}

相關文章