数据结构--树

1、基本概念

1.1 节点的度:节点拥有的子树数量称为节点的度。度为0的节点称为叶节点。不为0称为分支节点
1.2 树的深度:树中节点的最大层次称为树的深度
1.3 有序树:如果树中节点的各个子树从左至右是有次序的且不能互换的,称为有序树,否则为无序树
1.4 森林:m(m>=0)颗互不相交的树的集合

2、二叉树

2.1 特点:
每个节点最多有两颗子树。
左右子树有顺序,不能颠倒

2.2 特殊的二叉树
只有左子树的二叉树称为左斜树
只有右子树的二叉树称为右斜树
满二叉树:每个分支都有左右子树,且所有叶子都在同一层
完全二叉树:如果节点的编号与同样深度的满二叉树的节点的编号完全相同

2.3 树的遍历
深度优先遍历包括前序遍历,中序遍历,后续遍历,以及递归和非递归方式
广度优先遍历为层遍历

先序遍历

中序遍历

后序遍历

层遍历

public class Tree {
    public Node root;

    class Node{
        public int data;
        public Node left;
        public Node right;

        public Node(int data){
            this.data = data;
        }
    }

    /**
     * 创建完全二叉树
     * */
    public Node create(Node  node, int[] nums, int index){
        if (index>=nums.length)
            return null;

        node = new Node(nums[index]);

        node.left = create(node.left, nums, 2*index+1);
        node.right = create(node.right, nums, 2*index+2);

        return node;
    }

    /**
     * 先序遍历
     * */
    public void preTrav(Node node) {
        if(node == null)
            return;

        print(node.data);

        preTrav(node.left);

        preTrav(node.right);
    }

    /**
     * 中序遍历
     * */
    public void midTrav(Node node) {
        if(node == null)
            return;

        midTrav(node.left);

        print(node.data);

        midTrav(node.right);
    }

    /**
     * 后序遍历
     * */
    public void postTrav(Node node) {
        if(node == null)
            return;

        postTrav(node.left);

        postTrav(node.right);

        print(node.data);
    }

    /**
     * 非递归先序遍历
     *
     * 利用栈
     * 需要先把右子树压栈
     * */
    public void preTravFor(Node root) {
        if(root == null)
            return;

        Stack<Node> stack = new Stack<Node>();
        stack.push(root);

        while(!stack.isEmpty()) {
            Node tmpNode = stack.pop();

            print(tmpNode.data);

            if(tmpNode.right != null)
                stack.push(tmpNode.right);

            if(tmpNode.left != null)
                stack.push(tmpNode.left);
        }
    }

    /**
     * 非递归中序遍历
     * */
    public void midTravFor(Node root) {
        if(root == null)
            return;

        Stack<Node> stack = new Stack<Node>();
        Node curNode = root;

        while (curNode!=null || !stack.isEmpty()) {
            //将左子树全部压栈
            while (curNode!=null){
                stack.push(curNode);
                curNode = curNode.left;
            }

            curNode = stack.pop();

            print(curNode.data);

            curNode = curNode.right;
        }
    }

    /**
     * 非递归后序遍历
     * */
    public void postTravFor(Node root) {
        if(root == null)
            return;

        Stack<Node> stack = new Stack<>();
        Node curNode = root;
        Node rightNode=null;

        while(curNode!=null || !stack.isEmpty()) {
            //将左子树全部压栈
            while (curNode != null) {
                stack.push(curNode);
                curNode = curNode.left;
            }

            curNode = stack.pop();

            //当前结点没有右结点或上一个结点或是当前结点的右结点,则输出当前结点
            while (curNode.right==null || curNode.right==rightNode) {
                print(curNode.data);

                if(stack.isEmpty())
                    return;

                rightNode = curNode;
                curNode = stack.pop();
            }

            stack.push(curNode);
            curNode = curNode.right;
        }
    }

    /**
     * 层遍历
     *
     * 利用队列的先进先出
     * */
    public void storeyTrav(Node root){
        if(root == null)
            return;

        ArrayDeque<Node> queue = new ArrayDeque<Node>();
        queue.offer(root);

        while(!queue.isEmpty()) {
            Node tmpNode = queue.poll();

            print(tmpNode.data);

            if (tmpNode.left != null)
                queue.offer(tmpNode.left);

            if(tmpNode.right != null)
                queue.offer(tmpNode.right);
        }

    }

    /**
     * 二叉树的深度
     * */
    public int getMaxDepth(Node node){
        if(node == null)
            return 0;

        int left = getMaxDepth(node.left);
        int right = getMaxDepth(node.right);

        return left>right ? left+1 : right+1;
    }

    /**
     * 求二叉树的最大宽度 非递归
     *
     * 利用队列,求出每层的节点数
     * */
    public int getMaxWidthFor(Node root) {
        if(root == null)
            return 0;

        ArrayDeque<Node> queue = new ArrayDeque<Node>();
        int maxWidth = 0;
        int len = 1;
        queue.offer(root);

        while(true){
            if((len=queue.size()) == 0)
                break;

            while (len > 0) {
                Node tmpNode = queue.poll();
                len--;

                if(tmpNode.left != null)
                    queue.offer(tmpNode.left);
                if(tmpNode.right != null)
                    queue.offer(tmpNode.right);
            }

            maxWidth = maxWidth > queue.size()?maxWidth : queue.size();
        }

        return maxWidth;
    }

    /**
     * 求二叉树的最大宽度 递归方式
     * 
     * 将每层的节点数递加 放入数组中 再求数组中的最大值
     * */
    public int info[]=null;
    public boolean getMaxWidth(Node node, int depth) {
        if (node == null)
            return false;
        if (info == null)
            return false;

        info[depth]++;

        getMaxWidth(node.left, depth+1);
        getMaxWidth(node.right, depth+1);

        return true;
    }

    private void print(int data){
        System.out.print(data+"  ");
    }
}

调用

public static void main(String[] args) {
        Tree tree = new Tree();

        int data[] = new int[15];
        for (int i=0; i<data.length; i++){
            data[i] = i+1;
        }

        tree.root = tree.create(tree.root, data, 0);

        System.out.println("递归先序遍历");
        tree.preTrav(tree.root);
        System.out.println("\n非递归先序遍历");
        tree.preTravFor(tree.root);
        System.out.println("\n递归中序遍历");
        tree.midTrav(tree.root);
        System.out.println("\n非递归中序遍历");
        tree.midTravFor(tree.root);
        System.out.println("\n递归后序遍历");
        tree.postTrav(tree.root);
        System.out.println("\n非递归后序遍历");
        tree.postTravFor(tree.root);
        System.out.println("\n层遍历");
        tree.storeyTrav(tree.root);
        System.out.println("\n二叉树的深度==>"+tree.getMaxDepth(tree.root));
        System.out.println("\n二叉树的宽度 遍历==>"+tree.getMaxWidthFor(tree.root));

        tree.info = new int[10];
        tree.getMaxWidth(tree.root, 0);
        int maxWidth = 0;
        for(int info : tree.info){
            maxWidth = Math.max(info, maxWidth);
        }
        System.out.println("\n二叉树的宽度 递归==>"+maxWidth);

    }

参考:
大话数据结构
代码 http://blog.youkuaiyun.com/fantasy_lin_/article/details/52751559

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值