二叉樹

package cc.tree.application;

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

class Node {
    char val;
    Node lchild;
    Node rchild;
    public Node(char var) {
        this.val = var;
    }
}

public class Main {

    public static void preRead(Node head) {  //先序
        if(head == null)
            return;
        System.out.println(head.val);
        preRead(head.lchild);
        preRead(head.rchild);
    }

    public static void midRead(Node head) {  //中序
        if(head == null) 
            return;
        preRead(head.lchild);
        preRead(head.rchild);
        System.out.println(head.val);
    }

    public static void lasRead(Node head) {  //後序
        if(head == null)
            return;
        System.out.println(head.val);
        preRead(head.lchild);
        preRead(head.rchild);
    }

    /*
     * 輸出根值,入棧,遍歷左子樹(左子樹也入棧了),沒左子樹了就退棧,
     * 根據棧頂元素回溯找到上一個分叉點,遍歷右子樹
     */
    public static void preRead1(Node head) {    //非遞歸先序
        Stack<Node> stack = new Stack<Node>();
        while(head != null || !stack.isEmpty()) {
            while(head != null) {
                System.out.println(head.val);
                stack.push(head);
                head = head.lchild;
            }
            if(!stack.isEmpty()) {
                head = stack.pop();
                head = head.rchild;
            }
        }
    }

    public static void midRead1(Node head) {  //非遞歸中序,和上面只是輸出語句位置不一樣
        Stack<Node> stack = new Stack<Node>();
        while(head != null || !stack.isEmpty()) {
            while(head != null) {
                stack.push(head);
                head = head.lchild;
            }
            if(!stack.isEmpty()) {
                head = stack.pop();
                System.out.println(head.val);
                head = head.rchild;
            }
        }
    }

    /*參考http://www.tuicool.com/articles/UzU3Ub
     * 
     * 後序遍歷結果可以通過將前序遍歷的遍歷順序的第二步和第三步互換一下即可。
     * 即:先遍歷根節點,然後遍歷右孩子,最後遍歷左孩子
     * 
     * 觀察後發現,tmp中得出結果完成相反,最後逆序下即可
     */
    public static void lasRead1(Node head) {    //非遞歸後序
        Stack<Node> stack = new Stack<Node>();
        Stack<Node> tmp = new Stack<Node>();
        while(head != null || !stack.isEmpty()) {
            while(head != null) {
                tmp.push(head);
                stack.push(head);
                head = head.rchild;
            }
            if(!stack.isEmpty()) {
                head = stack.pop();
                head = head.lchild;
            }
        }
        while(!tmp.isEmpty()) {
            System.out.println(tmp.pop().val);
        }
    }

    /*隊列初始化,將根節點壓入隊列
     *當隊列不爲空:彈出一個節點,訪問,若左子節點或右子節點不爲空,將其壓入隊列
     */
    public static void levelRead(Node head) {   //層序遍歷
        Queue<Node> queue = new LinkedList<Node>();
        if(head == null)
            return;
        queue.offer(head);
        while(!queue.isEmpty()) {
            head = queue.poll();
            System.out.println(head.val);
            if(head.lchild != null)
                queue.offer(head.lchild);
            if(head.rchild != null)
                queue.offer(head.rchild);
        }
    }

    /*
     * 如果二叉樹爲空,二叉樹的深度爲0
     * 如果二叉樹不爲空,二叉樹的深度 = max(左子樹深度, 右子樹深度) + 1
     */
    public static int depth(Node head) {    //求樹深度
        int lDepth = 0;
        int rDepth = 0;
        int depth = 0;
        if(head == null) 
            return 0;
        lDepth = depth(head.lchild);
        rDepth = depth(head.rchild);
        depth =  1 + (lDepth > rDepth ? lDepth : rDepth);
        return depth;
    }

    /*
     * 如果二叉樹爲空,節點個數爲0
     * 如果二叉樹不爲空,二叉樹節點個數 = 左子樹節點個數 + 右子樹節點個數 + 1
     */
    public static int countLeaf(Node head) {  //求葉子個數
        int sum = 0;
        int lSize = 0;
        int rSize = 0;
        if(head == null)
            return 0;
        if(head.lchild == null && head.rchild == null) 
            return 1;
        lSize = countLeaf(head.lchild);
        rSize = countLeaf(head.rchild);
        sum = lSize + rSize;
        return sum;
    }

    /*
     * 如果二叉樹爲空或者k<1返回0, 如果二叉樹不爲空並且k==1,返回1
     * 如果二叉樹不爲空且k>1,返回左子樹中k-1層的節點個數與右子樹k-1層節點個數之和
     */
    public static int levelNum(Node head, int k) {   //第K層的節點個數
        if(head == null || k < 1)  
            return 0;
        if(k == 1)
            return 1;
        int lNum = levelNum(head.lchild, k-1); //左子樹中k-1層的節點個數 
        int rNum = levelNum(head.rchild, k-1); //右子樹中k-1層的節點個數  
        return lNum + rNum;
    }

    /*
     *如果兩棵二叉樹都爲空,返回真;如果兩棵二叉樹一棵爲空,另一棵不爲空,返回假
     *如果兩棵二叉樹都不爲空,如果對應的左子樹和右子樹都同構返回真,其他返回假
     */
    public static boolean StructureCmp(Node head1, Node head2)//判斷兩棵二叉樹是否結構相同  
     {  
         if(head1 == null && head2 == null) 
             return true;  
         else if(head1 == null || head2 == null) // 有一個爲空,一個不爲空,返回假  
             return false;  
         boolean resultLeft = StructureCmp(head1.lchild, head2.lchild); 
         boolean resultRight = StructureCmp(head1.rchild, head2.rchild); 
         return (resultLeft && resultRight);  
     }   

    public static boolean isALV(Node head) { //判斷二叉樹是不是平衡二叉樹
        if(head == null) 
            return true;
        int lDepth = depth(head.lchild);
        int rDepth = depth(head.rchild);
        if(Math.abs(lDepth-rDepth) > 1)
            return false;   //左子樹和右子樹高度相差不大於1,再判斷左子樹和右子樹是不是AVL樹
        return isALV(head.lchild) && isALV(head.rchild);
    }

    public static void main(String[] args) {
        Node node1 = new Node('A');
        Node node2 = new Node('B');
        Node node3 = new Node('C');
        Node node4 = new Node('D');
        Node node5 = new Node('E');
        Node node6 = new Node('F');
        node1.lchild = node2; node1.rchild = node3;
        node2.lchild = node4; node2.rchild = node5;
        node3.lchild = node6; node3.rchild = null;
        node4.lchild = null; node4.rchild = null;
        node5.lchild = null; node5.rchild = null;
        node6.lchild = null; node6.rchild = null;

        //levelRead(node1);
       // System.out.println(depth(node1));
       // System.out.println(countLeaf(node1));
       // System.out.println(levelNum(node1,4));
         System.out.println(isALV(node1));

    }

}
發佈了227 篇原創文章 · 獲贊 24 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章