数据结构-树

1.二叉树

public class BinaryTreeDao<E> {
    private Node root;
    public BinaryTreeDao (Node node){
        this.root = node;
    }
    public boolean add(Node node){
        //定义一个辅助变量,获取根结点
        Node temp = root;
        //进行遍历二叉树,找到合适的位置插入
        while (true) {
            //如果添加的数和树中的数相同,则不插入
            if (temp.num == node.num){
                return false;
            }
            //左子树
            //如果根节点大于要插入的数,就说明插入的数是二叉树的左子树
            if (temp.num > node.num){
                //如果当前结点的左节点为空,就将这个数插入
                if (temp.left == null){
                    temp.left = node;
                    return true;
                    //否则,进入下一个结点
                }else {
                    temp = temp.left;
                }
                //右子树
            }else {
                //当前结点的右节点为空,则插入
                if (temp.right == null){
                    temp.right = node;
                    return true;
                }else {
                    temp = temp.right;
                }
            }
        }
    }
    //判断树是否为空
    public boolean isEmpty(){
        return root == null;
    }
    //先序遍历
    List<Integer> list = new ArrayList<>();
    //将根结点传入
    public List<Integer> get(){
        return getAll(root);
    }
    public List<Integer> getAll(Node node){
        //就当前结点插入到集合中
        list.add(node.num);
        //如果左节点不为空,则进行递归
        if (node.left != null) {
            getAll(node.left);
        //这里涉及到递归的原理,当左节点循环结束后,就会从树的最低开始向根节点遍历
        }if (node.right != null){
            getAll(node.right);
        }
        return list;
    }
  //中序遍历
    public List<Integer> getIn(){
        return getInOrder(root);
    }
    public List<Integer> getInOrder(Node node){
        if (node.left != null){
            getInOrder(node.left);
        }
        list.add(node.num);
        if (node.right != null){
            getInOrder(node.right);
        }
        return list;
    }

    //后序遍历
    public List<Integer> getNext(){
        return getNextOrder(root);
    }
    public List<Integer> getNextOrder(Node node){
        if (node.left != null){
            getNextOrder(node.left);
        }
        if (node.right != null){
            getNextOrder(node.right);
        }
        list.add(node.num);
        return list;
    }
}

2.顺序存储二叉树

public class Test4 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7};
        ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
        arrBinaryTree.preOrder();
        System.out.println();
        arrBinaryTree.inOrder();
        System.out.println();
        arrBinaryTree.nextOrder();
    }
}
//顺序存储二叉树
class ArrBinaryTree{
    private int[] arr;
    public ArrBinaryTree(int[] arr){
        this.arr = arr;
    }
    public void preOrder(){
        this.preOrder(0);
    }
    public void inOrder(){
        this.inOrder(0);
    }
    public void nextOrder(){
        this.nextOrder(0);
    }
    //先序遍历
    public void preOrder(int index){
        if (arr == null || arr.length == 0){
            System.out.println("数组为空!");
        }
        System.out.print(arr[index]+" ");
      //左子树(下一个结点的下标为:index*2+1),index为当前下标
        if ((index*2)+1 <arr.length){
            preOrder(index*2+1);
        }
      //右子树
        if ((index*2)+2 <arr.length){
            preOrder(index*2+2);
        }
    }
    //中序遍历
    public void inOrder(int index){
        if (arr.length == 0 || arr == null){
            System.out.println("数组为空");
        }
        if ((index*2+1) < arr.length) {
            inOrder(index*2+1);
        }
        System.out.print(arr[index]+" ");
        if ((index*2+2) < arr.length) {
            inOrder(index*2+2);
        }
    }
    //后序遍历
    public void nextOrder(int index){
        if (arr.length == 0 || arr == null){
            System.out.println("数组为空");
        }
        if ((index*2+1) < arr.length){
            nextOrder(index*2+1);
        }
        if ((index*2+2) < arr.length){
            nextOrder(index*2+2);
        }
        System.out.print(arr[index]+" ");
    }
}

3.赫夫曼树

给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
若初始森林中共有n棵二叉树,最终求得的哈夫曼树共有2n-1个结点
哈夫曼树中没有度数为1的分支结点
若初始森林中共有n棵二叉树,进行n-1次合并后才能剩下一棵最终的哈夫曼树
构成赫夫曼树的步骤
(1)从小到大进行排序,将每一个数据,每个数据都是一个节点,每个节点可以看做是一颗最简单的二叉树
(2)取出根节点权值最小的两颗二叉树
(3)组成一颗新的二叉树,该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和
(4)再将这颗新的二叉树,以根节点的权值大小再次排序,不断重复1-2-3-4的步骤,知道数列中的所有数据处理完毕,就得到一个赫夫曼树

public class HaffManTree {
    public static void main(String[] args) {
        int arr[] = {13,7,8,3,29,6,1};
        Node root = createHaffManTree(arr);
        preOrder(root);
    }
    public static void preOrder(Node node){
        if (node != null){
            node.preOrder();
        }else {
            System.out.println("是空树,不能遍历!");
        }
    }
    //创建赫夫曼树的方法
    public static Node createHaffManTree(int[] arr){
        //1.遍历arr数组
        //2.将arr中每个元素构成一个Node
        //3.将Node放到ArrayList中
        List<Node> list = new ArrayList<>();
        for (int value:arr
             ) {
            list.add(new Node(value));
        }
        while (list.size() > 1){
            //从小到大排序
            Collections.sort(list);
            System.out.println(list);
            //取出权值最小的两颗二叉树
            Node left = list.get(0);
            Node right = list.get(1);
            //构成新的二叉树
            Node parent = new Node(left.value+right.value);
            parent.left = left;
            parent.right = right;
            //从集合中删除处理过的二叉树
            list.remove(left);
            list.remove(right);
            //将新的二叉树加入到集合中
            list.add(parent);
        }
        //返回赫夫曼树的root头结点
        return list.get(0);
    }
}
//创建结点类
class Node implements Comparable<Node>{
    int value;//结点权值
    Node left;//左子节点
    Node right;//右子节点
    public Node (int value){
        this.value = value;
    }
    public void preOrder(){
        System.out.println(this);
        if (this.left != null){
            this.left.preOrder();
        }
        if (this.right != null){
            this.right.preOrder();
        }
    }
    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    @Override
    public int compareTo(Node o) {
        //从小到大排序
        return this.value - o.value;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值