二叉树

17.11.9

(1)创建1棵排序二叉树,用非递归的方法(用栈)遍历

参考:http://blog.csdn.net/kerryfish/article/details/24309617

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Stack;
public class BuildBTpaixu {
    public void buildTree(int[]arr) {
        for(int node:arr) {
            insert(node);
        }
    }
    BinaryNode2 root;
    private void insert(int ele) {
        root=insert(root,ele);
    }
    private BinaryNode2 insert(BinaryNode2 root,int ele) {
        if(root==null)
            return new BinaryNode2(ele);
        if(root.ele>ele)
            root.left=insert(root.left,ele);
        else if(root.ele<ele)
            root.right=insert(root.right,ele);
        else
            root.left=insert(root.left,ele);
        return root;
    }
//     先序遍历
//    模拟递归的过程,将左子树不断压入栈,直到为null,然后处理栈的右子树。这种方式具备扩展性【原作者所说】
    public void preOrder(BinaryNode2 root) {
        if(root==null)return;
        Stack<BinaryNode2>stack=new Stack<BinaryNode2>();
        
        while(root!=null||!stack.isEmpty()) {
            while(root!=null) {
                System.out.print(root.ele+" ");
                stack.push(root);
                root=root.left;
            }
            root=stack.pop();
            root=root.right;//如果是null,出栈处理右子树
        }
        
    }
//    中序遍历,思想同以上。
    public void inOrder(BinaryNode2 root) {
        if(root==null)return;
        Stack<BinaryNode2>stack=new Stack<BinaryNode2>();
        while(root!=null||!stack.isEmpty()) {
            while(root!=null) {
                stack.push(root);
                root=root.left;
            }
            root=stack.pop();
            System.out.print(root.ele+" ");
            root=root.right;
        }    
    }
    /**
     * 后序遍历不同于前序、中序遍历,它是要先处理左右子树,在处理根(回溯),所以需要一个记录哪些节点
     * 已经被访问过的结构(可以在树里面加一个标记),用map实现。
     * @param root
     */
    public void postOrder(BinaryNode2 root) {
        if(root==null)return;
        Stack<BinaryNode2>stack=new Stack<BinaryNode2>();
        Map<BinaryNode2,Boolean>map=new HashMap<>();
        stack.push(root);
        while(!stack.isEmpty()) {
            BinaryNode2 temp=stack.peek();
            if(temp.left!=null&&!map.containsKey(temp.left)) {
                temp=temp.left;
                while(temp!=null) {
                    stack.push(temp);
                    temp=temp.left;
                }
                continue;
            }
            if(temp.right!=null&&!map.containsKey(temp.right)) {
                stack.push(temp.right);
                continue;
            }
            BinaryNode2 t=stack.pop();
            map.put(t, true);
            System.out.print(t.ele+" ");
        }
    }
    public void levelTravel(BinaryNode2 root){
        if(root==null)return;
        Queue<BinaryNode2>q=new LinkedList<BinaryNode2>();
        q.add(root);
        while(!q.isEmpty()) {
            BinaryNode2 temp=q.poll();
            System.out.print(temp.ele+" ");
            if(temp.left!=null) {
                q.add(temp.left);
            }
            if(temp.right!=null) {
                q.add(temp.right);
            }
        }
    }
    public static void main(String[] args) {
        int[]arr= {2,4,5,1,3};
        BuildBTpaixu btp=new BuildBTpaixu();
        btp.buildTree(arr);
        BinaryNode2 root=btp.root;
        System.out.println("二叉树的根是:"+root.ele);
        System.out.println("中序遍历:");
        btp.inOrder(root);
        System.out.println();
        System.out.println("前序遍历:");
        btp.preOrder(root);
        System.out.println();
        System.out.println("后序遍历:");
        btp.postOrder(root);
        System.out.println();
        System.out.println("层次遍历:");
        btp.levelTravel(root);
    }
}

(2) 递归遍历&返回当前二叉树的深度

/**
 * 参考:http://blog.csdn.net/gfj0814/article/details/51637696
 * 性质1:在二叉树的第i层上至多有2^(i-1)个节点(i >= 1)
 * 性质2:深度为k的二叉树至多有2^(k-1)个节点(k >=1)
 * 性质3:对于任意一棵二叉树T而言,其叶子节点数目为N0,度为2的节点数目为N2,则有N0 = N2 + 1
 */
import java.util.List;
import java.util.ArrayList;

public class BinaryTraversal {
    BinaryNode root;
    private List<BinaryNode>list=new ArrayList<BinaryNode>();
    public BinaryTraversal(){
        init() ;
    }
    
    public List<BinaryNode> getList() {
        return list;
    }

    public void setList(List<BinaryNode> list) {
        this.list = list;
    }

    public void init() {
        BinaryNode x=new BinaryNode("x");
        BinaryNode y=new BinaryNode("y");
        BinaryNode d=new BinaryNode("d",x,y);
        BinaryNode e=new BinaryNode("e");
        BinaryNode f=new BinaryNode("f");
        BinaryNode c=new BinaryNode("c",e,f);
        BinaryNode b=new BinaryNode("b",d,null);
        BinaryNode a=new BinaryNode("a",b,c);
        root=a;
    }
    public void preOrder(BinaryNode node) {
        list.add(node);
        if(node.left!=null) {
            preOrder(node.left);
        }
        if(node.right!=null) {
            preOrder(node.right);
        }
    }
    public void inOrder(BinaryNode node) {
        if(node.left!=null) {
            inOrder(node.left);
        }
        list.add(node);
        if(node.right!=null) {
            inOrder(node.right);
        }
    }
    public void postOrder(BinaryNode node) {
        if(node.left!=null) {
            postOrder(node.left);
        }
        if(node.right!=null) {
            postOrder(node.right);
        }
        list.add(node);
    }
    /**
     * 如果一颗树只有一个节点,深度是1;
     * 如果节点只有左子树没有右子树,那么树的深度是其左子树+1;
     * 如果节点只有右子树没有左子树,那么树的深度是其右子树+1;
     * 如果既有右子树也有左子树,就是其左右子树的较大值+1。
     */
    public int getTreeDepth(BinaryNode node) {
        if(node.left==null&&node.right==null) {
            return 1;
        }
        int left=0,right = 0;
        if(node.left!=null) {
            left=getTreeDepth(node.left);
        }
        if(node.right!=null) {
            right=getTreeDepth(node.right);
        }
        return right>left?right+1:left+1;
    }
    public static void main(String[] args) {
        BinaryTraversal bt1=new BinaryTraversal();
        System.out.println("第一个实例二叉树的根节点是:"+bt1.root.ele);
        System.out.println("第一个实例二叉树的深度是:"+bt1.getTreeDepth(bt1.root));

        System.out.println("循环中序遍历:");
        bt1.inOrder(bt1.root);
        for(BinaryNode node:bt1.getList()) {
            System.out.print(node.ele+" ");
        }
        
    }
}

(3)摘自李兴华老师的Java课程,对对象数组排序

import java.util.Arrays;
//完成两个功能:保存、取出
//二叉排序树,中序遍历输出的元素有序
class Person implements Comparable<Person>{
    //要实现对象数组的排序,必须实现所在类的Comparable<T>接口
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name=name;
        this.age=age;
    }
    @Override
    public String toString() {
        return "姓名"+this.name+"年龄"+this.age;
    }
    @Override
    public int compareTo(Person p) {
        return this.age-p.age;
    }    
}
class BinaryTree2{
    private class Node{
        private Node left;
        private Node right;
        @SuppressWarnings("rawtypes")
        private Comparable data;
        @SuppressWarnings("rawtypes")
        public Node(Comparable data) {
            this.data =data;
        }
        @SuppressWarnings("unchecked")
        public void addNode(Node newNode) {
            if(this.data.compareTo(newNode.data)>0) {
                //当前节点大于newNode,保存在左边
                if(this.left==null) {
                    this.left=newNode;
                }else {
                    this.left.addNode(newNode);
                }
            }else {
                if(this.right==null) {
                    this.right=newNode;
                }else {
                    this.right.addNode(newNode);
                }
            }
        }
        public void toArrayNode() {
            if(this.left!=null) {//有左节点
                this.left.toArrayNode();
            }
            BinaryTree2.this.retData[BinaryTree2.this.foot++]=this.data;
            if(this.right!=null) {
                this.right.toArrayNode();
            }
        }
    }
    private Node root;//保留住根节点
    private int count=0;//保存节点个数
    private Object[]retData;
    private int foot=0;
    @SuppressWarnings("rawtypes")
    public void add(Object obj) {
        Comparable data=(Comparable)obj;
        Node newNode=new Node(data);//将数据包装在Node节点之中
        if(this.root==null) {
            this.root=newNode;
        }else {
            this.root.addNode(newNode);
        }
        this.count++;
    }
    //取出数据,按中序遍历的方法
    public Object[]toArray(){
        if(this.count>0) {
            this.foot=0;
            this.retData=new Object[this.count];
            this.root.toArrayNode();
            return retData;
        }else {
            return null;
        }
    }
}
public class BuildBineryTreeLixh {
    public static void main(String[] args) {
        BinaryTree2 bt=new BinaryTree2();
        bt.add(new Person("wa",13));
        bt.add(new Person("xi",30));
        bt.add(new Person("li",8));
        System.out.println(Arrays.toString(bt.toArray()));
    }    
}

 

posted @ 2017-11-09 20:46  liumy  阅读(200)  评论(0编辑  收藏  举报