二叉树模拟



接着我们就要写一个比较复杂的数据结构的,但是这个数据结构是很重要的,假如你想深入的学习算法等等.我们来模拟一下二叉树。

public class BiTree {
    public final static int MAX = 40;
    private BiTree leftTree; // 左子树  
    private BiTree rightTree; // 右子树
    private Object data; // 节点数据
    BiTree[] elements = new BiTree[MAX]; // 层次遍历时保存各个节点
    private int front; //层次遍历时队首 
    private int rear; //层次遍历时队尾

    //构造函数
    public BiTree() {
    }

    public BiTree(Object data) {
        this.data = data;
    }

    public BiTree(Object data, BiTree lefTree, BiTree righTree) {
        this.data = data;
        this.leftTree = lefTree;
        this.rightTree = righTree;
    }

    //递归遍历二叉树(前序)
    public void preOrder(BiTree tree) {
        if (tree != null) {
            visit(tree.data); //展示数据
            preOrder(tree.leftTree);
            preOrder(tree.rightTree);
        }
    }

    //递归遍历二叉树(中序)
    public void inOrder(BiTree tree) {
        if (tree != null) {
            inOrder(tree.leftTree);
            //访问数据
            visit(tree.data);
            inOrder(tree.rightTree);
        }
    }

    //递归遍历二叉树(后序)
    public void postOrder(BiTree tree) {
        if (tree != null) {
            postOrder(tree.leftTree);
            postOrder(tree.rightTree);
            visit(tree.data);
        }
    }

    //非递归实现遍历(前序)
    public void iterativePreOrder(BiTree tree) {
        //堆栈
        Stack<BiTree> stack = new Stack<BiTree>();

        if (tree != null) {
            stack.push(tree);

            while (!stack.isEmpty()) {
                //先访问根
                tree = stack.pop();
                //访问根节点
                visit(tree.data);

                if (tree.rightTree != null) {
                    stack.push(tree.rightTree);
                }

                if (tree.leftTree != null) {
                    stack.push(tree.leftTree);
                }
            }
        }
    }

    //中序实现二叉树遍历(非递归)
    public void iterativeInOrder(BiTree tree) {
        //堆栈
        Stack<BiTree> stack = new Stack<BiTree>();

        while (tree != null) //遍历所有的tree
         {
            while (tree != null) //装入最左边的tree
             {
                if (tree.rightTree != null) {
                    stack.push(tree.rightTree);
                }

                stack.push(tree);
                //指向左tree
                tree = tree.leftTree;
            }

            //遍历树
            tree = stack.pop();

            //右树为空的时候,说明需要输出左边的树
            while (!stack.empty() && (tree.rightTree == null)) {
                visit(tree.data);
                tree = stack.pop();
            }

            //当左树遍历完成后要遍历根接点
            visit(tree.data);

            //然后继续遍历
            if (!stack.empty()) {
                tree = stack.pop();
            } else {
                tree = null; //退出循环
            }
        }
    }

    //非递归实现遍历(后续)
    public void iterativePostOrder(BiTree tree) {
        //临时变量
        BiTree tempTree = tree;
        Stack<BiTree> stack = new Stack<BiTree>();

        //遍历所有的tree
        while (tree != null) {
            while (tree.leftTree != null) {
                stack.push(tree); //装载左树
                tree = tree.leftTree;
            }

            //当前节点无右子或右子已经输出
            while ((tree != null) &&
                    ((tree.rightTree == null) || (tree.rightTree == tempTree))) {
                visit(tree.data);
                tempTree = tree; // 记录上一个已输出节点

                if (stack.empty()) {
                    return;
                }

                tree = stack.pop();
            }

            //装入根接点
            stack.push(tree);
            tree = tree.rightTree;
        }
    }

    //层次遍历二叉树
    public void LayerOrder(BiTree tree) {
        elements[0] = tree;
        front = 0;
        rear = 1;

        while (front < rear) {
            try {
                if (elements[front].data != null) {
                    //输出数据
                    System.out.print(elements[front].data + " ");

                    //装入左树
                    if (elements[front].leftTree != null) {
                        elements[rear++] = elements[front].leftTree;
                    }

                    if (elements[front].rightTree != null) {
                        elements[rear++] = elements[front].rightTree;
                    }

                    //数组向前移动
                    front++;
                }
            } catch (Exception e) {
                break;
            }
        }
    }

    //求二叉树的高度
    public static int height(BiTree tree) {
        if (tree == null) {
            return 0;
        } else { //递归饭会树的高度

            int leftTreeHeight = height(tree.leftTree);
            int rightTreeHeight = height(tree.rightTree);

            return (leftTreeHeight > rightTreeHeight) ? (leftTreeHeight + 1)
                                                      : (rightTreeHeight + 1);
        }
    }

    // 求data所对应结点的层数,如果对象不在树中,结果返回-1;否则结果返回该对象在树中所处的层次,规定根节点为第一层
    public int level(Object data) {
        int leftLevel;
        int rightLevel;

        if (this == null) {
            return -1;
        }

        if (data == this.data) {
            return 1;
        }

        //计算左树
        leftLevel = (leftTree == null) ? (-1) : leftTree.level(data);
        //计算左树
        rightLevel = (rightTree == null) ? (-1) : rightTree.level(data);

        if ((leftLevel < 0) && (rightLevel < 0)) {
            return -1;
        }

        return (leftLevel > rightLevel) ? (leftLevel + 1) : (rightLevel + 1);
    }

    // 求二叉树的结点总数(递归)
    public static int nodes(BiTree tree) {
        if (tree == null) {
            return 0;
        } else {
            int left = nodes(tree.leftTree);
            int right = nodes(tree.rightTree);

            return left + right + 1;
        }
    }

    // 求二叉树叶子节点的总数
    public static int leaf(BiTree tree) {
        if (tree == null) {
            return 0;
        } else {
            int left = leaf(tree.leftTree);
            int right = leaf(tree.rightTree);

            if ((tree.leftTree == null) && (tree.rightTree == null)) {
                return (left + right) + 1; //增加一个叶子节点
            } else {
                return left + right;
            }
        }
    }

    //求二叉树父节点个数
    public static int fatherNodes(BiTree tree) {
        //节点为空或者单节点
        if ((tree == null) ||
                ((tree.leftTree == null) && (tree.rightTree == null))) {
            return 0;
        } else {
            int left = fatherNodes(tree.leftTree);
            int right = fatherNodes(tree.rightTree);

            return left + right + 1;
        }
    }

    // 求只有一个孩子结点的父节点个数
    public static int oneChildFather(BiTree tree) {
        int left;
        int right;

        if ((tree == null) ||
                ((tree.rightTree == null) && (tree.leftTree == null))) {
            return 0;
        } else {
            left = oneChildFather(tree.leftTree);
            right = oneChildFather(tree.rightTree);

            if (((tree.leftTree != null) && (tree.rightTree == null)) ||
                    ((tree.leftTree == null) && (tree.rightTree != null))) {
                return left + right + 1;
            } else {
                return left + right; /* 加1是因为要算上根节点 */
            }
        }
    }

    // 求二叉树只拥有左孩子的父节点总数
    public static int leftChildFather(BiTree tree) {
        if ((tree == null) || (tree.leftTree == null)) {
            return 0;
        } else {
            int left = leftChildFather(tree.leftTree);
            int right = leftChildFather(tree.rightTree);

            if (((tree.leftTree != null) && (tree.rightTree == null))) {
                return left + right + 1;
            } else {
                return left + right;
            }
        }
    }

    // 求二叉树只拥有右孩子的结点总数
    public static int rightChildFather(BiTree tree) {
        if ((tree == null) || (tree.rightTree == null)) {
            return 0;
        } else {
            int left = rightChildFather(tree.leftTree);
            int right = rightChildFather(tree.rightTree);

            if ((tree.leftTree == null) && (tree.rightTree != null)) {
                return left + right + 1;
            } else {
                return left + right;
            }
        }
    }

    // 计算有两个节点的父节点的个数
    public static int doubleChildFather(BiTree tree) {
        int left;
        int right;

        if (tree == null) {
            return 0;
        } else {
            left = doubleChildFather(tree.leftTree);
            right = doubleChildFather(tree.rightTree);

            if ((tree.leftTree != null) && (tree.rightTree != null)) {
                return (left + right + 1);
            } else {
                return (left + right);
            }
        }
    }

    // 访问根节点
    public void visit(Object data) {
        System.out.print(data + " ");
    }

    // 将树中的每个节点的孩子对换位置
    public void exChange() {
        if (this == null) {
            return;
        }

        if (leftTree != null) {
            leftTree.exChange(); //交换左树
        }

        if (rightTree != null) {
            rightTree.exChange(); //交换右树
        }

        BiTree temp = leftTree;
        leftTree = rightTree;
        rightTree = temp;
    }

    //递归求所有结点的和
    public static int getSumByRecursion(BiTree tree) {
        if (tree == null) {
            return 0;
        } else {
            int left = getSumByRecursion(tree.leftTree);
            int right = getSumByRecursion(tree.rightTree);

            return Integer.parseInt(tree.data.toString()) + left + right;
        }
    }

    //非递归求二叉树中所有结点的和
    public static int getSumByNoRecursion(BiTree tree) {
        Stack<BiTree> stack = new Stack<BiTree>();
        int sum = 0; //求和

        if (tree != null) {
            stack.push(tree);

            while (!stack.isEmpty()) {
                tree = stack.pop();
                sum += Integer.parseInt(tree.data.toString());

                if (tree.leftTree != null) {
                    stack.push(tree.leftTree);
                }

                if (tree.rightTree != null) {
                    stack.push(tree.rightTree);
                }
            }
        }

        return sum;
    }

    /**
      * @param args
      */
    public static void main(String[] args) {
        BiTree l = new BiTree(10);
        BiTree m = new BiTree(9);
        BiTree n = new BiTree(8);
        BiTree h = new BiTree(7);
        BiTree g = new BiTree(6);
        BiTree e = new BiTree(5, n, l);
        BiTree d = new BiTree(4, m, null);
        BiTree c = new BiTree(3, g, h);
        BiTree b = new BiTree(2, d, e);
        BiTree tree = new BiTree(1, b, c);

        System.out.println("递归前序遍历二叉树结果: ");
        tree.preOrder(tree);
        System.out.println();
        System.out.println("非递归前序遍历二叉树结果: ");
        tree.iterativePreOrder(tree);
        System.out.println();
        System.out.println("递归中序遍历二叉树的结果为:");
        tree.inOrder(tree);
        System.out.println();

        System.out.println("非递归中序遍历二叉树的结果为:");
        tree.iterativeInOrder(tree);
        System.out.println();

        System.out.println("递归后序遍历二叉树的结果为:");
        tree.postOrder(tree);
        System.out.println();

        System.out.println("非递归后序遍历二叉树的结果为:");
        tree.iterativePostOrder(tree);
        System.out.println();

        System.out.println("层次遍历二叉树结果: ");
        tree.LayerOrder(tree);
        System.out.println();
        System.out.println("递归求二叉树中所有结点的和为:" + getSumByRecursion(tree));
        System.out.println("非递归求二叉树中所有结点的和为:" + getSumByNoRecursion(tree));

        System.out.println("二叉树中,每个节点所在的层数为:");

        for (int p = 1; p <= 14; p++) {
            System.out.println(p + "所在的层为:" + tree.level(p));
        }

        System.out.println("二叉树的高度为:" + height(tree));
        System.out.println("二叉树中节点总数为:" + nodes(tree));

        System.out.println("二叉树中叶子节点总数为:" + leaf(tree));

        System.out.println("二叉树中父节点总数为:" + fatherNodes(tree));
        System.out.println("二叉树中只拥有一个孩子的父节点数:" + oneChildFather(tree));
        System.out.println("二叉树中只拥有左孩子的父节点总数:" + leftChildFather(tree));
        System.out.println("二叉树中只拥有右孩子的父节点总数:" + rightChildFather(tree));
        System.out.println("二叉树中同时拥有两个孩子的父节点个数为:" + doubleChildFather(tree));
        System.out.println("--------------------------------------");
        tree.exChange();
        System.out.println("交换每个节点的左右孩子节点后......");
        System.out.println("递归前序遍历二叉树结果: ");
        tree.preOrder(tree);
        System.out.println();
        System.out.println("非递归前序遍历二叉树结果: ");
        tree.iterativePreOrder(tree);
        System.out.println();
        System.out.println("递归中序遍历二叉树的结果为:");
        tree.inOrder(tree);
        System.out.println();
        System.out.println("非递归中序遍历二叉树的结果为:");
        tree.iterativeInOrder(tree);
        System.out.println();
        System.out.println("递归后序遍历二叉树的结果为:");
        tree.postOrder(tree);
        System.out.println();
        System.out.println("非递归后序遍历二叉树的结果为:");
        tree.iterativePostOrder(tree);
        System.out.println();
        System.out.println("层次遍历二叉树结果: ");
        tree.LayerOrder(tree);
        System.out.println();

        System.out.println("递归求二叉树中所有结点的和为:" + getSumByRecursion(tree));
        System.out.println("非递归求二叉树中所有结点的和为:" + getSumByNoRecursion(tree));

        System.out.println("二叉树中,每个节点所在的层数为:");

        for (int p = 1; p <= 14; p++) {
            System.out.println(p + "所在的层为:" + tree.level(p));
        }

        System.out.println("二叉树的高度为:" + height(tree));
        System.out.println("二叉树中节点总数为:" + nodes(tree));
        System.out.println("二叉树中叶子节点总数为:" + leaf(tree));
        System.out.println("二叉树中父节点总数为:" + fatherNodes(tree));
        System.out.println("二叉树中只拥有一个孩子的父节点数:" + oneChildFather(tree));
        System.out.println("二叉树中只拥有左孩子的父节点总数:" + leftChildFather(tree));
        System.out.println("二叉树中只拥有右孩子的父节点总数:" + rightChildFather(tree));
        System.out.println("二叉树中同时拥有两个孩子的父节点个数为:" + doubleChildFather(tree));
    }
}

转载自>http://watchmen.cn/portal.php?mod=view&aid=988

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值