构造哈夫曼树 代码实现 并且层次遍历, 前序遍历

本代码是由java代码实现

什么是哈夫曼树,怎么构造:

假设给定权值:2, 3, 7, 9, 18, 25

那么构造出的树直观上应该是这样:

 

实现步骤

第一步:

使用两个最小的权值  2  3 构造树(小的放在左子树,大的放在右子树)

 此时  权值删除 2 3 加入 5 并且进行排序

权值为:5, 7, 9, 18, 25

第二步:

使用两个最小的权值 5 7 构造树(小的放在左子树,大的放在右子树)

  此时  权值删除 5 7  加入 12 并且进行排序

权值为: 9,12, 18, 25

第三步:

使用两个最小的权值 9 12 构造树(小的放在左子树,大的放在右子树)

 

此时  权值删除 9 12  加入 21 并且进行排序

权值为:  18,21, 25

第四步:

使用两个最小的权值 18 21 构造树(小的放在左子树,大的放在右子树)

 

 

此时  权值删除 18  21  加入 39 并且进行排序

权值为: 25,39

第五步:

使用两个最小的权值 25 39 构造树(小的放在左子树,大的放在右子树)

此时哈夫曼树就建好了,这就是哈夫曼树的思想。

下面根据思想代码实现, 

首先:创建HuffmanTreeNode(哈夫曼树节点类)

public class HuffmanTreeNode {
    /**
     * 每个哈夫曼树节点的权值
     */
    public int weight;
    /**
     * 标志着是否进行构成一个哈夫曼树
     */
    public int flag;
    /**
     * 定义节点父亲  左孩子 右孩子
     */
    public HuffmanTreeNode lChild, rChild;

    public HuffmanTreeNode() {
    }

    public HuffmanTreeNode(int weight) {
        this.weight = weight;

    }


}

然后写HuffmanTree(构造Huffman树)类

public class HuffmanTree {
    public HuffmanTreeNode creatHuffmanTree(int[] w){

        int n = w.length;
        //构建哈夫曼树一共需要的节点个数
        int m = n * 2 - 1;
        //创建一个 哈曼树节点数组  里面存放哈夫曼节点
        HuffmanTreeNode[] htn = new HuffmanTreeNode[m];
        int i;

        for(i = 0; i < n; i++)
        {
            htn[i] = new HuffmanTreeNode(w[i]);

        }


        //开始构建哈夫曼树
        for(i = n; i < m; i++)
        {
            //这个方法实现找出权值最小的节点的
            HuffmanTreeNode min1 = selectMin(htn,i - 1);
            //flag设置为1 标志着构造哈夫曼树使用了这个权值
            min1.flag = 1;
            //继续找出
            HuffmanTreeNode min2 = selectMin(htn,i - 1);
            min2.flag = 1;

            //构建哈夫曼树
            htn[i] = new HuffmanTreeNode();
            htn[i].weight = min1.weight + min2.weight;


            //父节点左右子节点 小的放左边 大的放右边
            htn[i].lChild = min1;
            htn[i].rChild = min2;
        }


        //此时 i = 11  但是哈夫曼节点数组长度长为11 下标只能为10  为11的时候越界
        // 所以返回的时候应该返回 i-1处的节点 此节点就是哈夫曼树的根节点
        return htn[i-1];

    }
    //在【0 - end 中找出权值最小的节点】
    public HuffmanTreeNode selectMin(HuffmanTreeNode[] htn, int end) {
        int j = 0;
        //找出HuffmanTreeNode数组当中 HuffmanTreeNode 类中的 flag属性为0的 元素
        for( j = 0; j <= end; j++)
        {
            if(htn[j].flag == 0)
            {
                break;
            }
        }
        //定义一个新变量 用于保存最小的权值的类
        HuffmanTreeNode min = htn[j];
        for(int i = 0; i <= end; i++)
        {
            HuffmanTreeNode curNode = htn[i];
            if(curNode.flag == 0 && curNode.weight < min.weight)
            {
                min = curNode;
            }
        }
        return min;
    }
}

然后使用HuffmanTest(哈夫曼树测试)类验证并且附带层次遍历和前序遍历输出:


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

/*
构造哈夫曼树

给出以下权重2, 3, 7, 9, 18, 25,构造哈夫曼树。 以先序遍历方式输出节点,换行隔开。

注意:构造哈夫曼树时,节点值小的在左侧。
 */


public class HuffmanTest {
    public static void main(String[] args) {
        int[] w = {2, 3, 7, 9, 18, 25};

        HuffmanTree t = new HuffmanTree();
        HuffmanTreeNode root = t.creatHuffmanTree(w);//构造哈夫曼树

        System.out.println("构造哈夫曼树的层次遍历结果(换行打印):");
        //构造的哈夫曼树进行层次遍历
        levelOrder(root);

        System.out.print("构造哈夫曼树的前序遍历结果: ");
        //哈夫曼树进行前序遍历
        prevOrder(root);
        System.out.println();
    }

    public static void levelOrder(HuffmanTreeNode root) {
        Queue<HuffmanTreeNode> queue = new LinkedList<HuffmanTreeNode>();//创建队列
        if(root == null)
        {
            return;
        }

        HuffmanTreeNode theLast = root;//theLast 存放所在层的最后一个树节点
        HuffmanTreeNode nextLast = root;//存放下一层的最后一个树节点

        HuffmanTreeNode temp;//用于存放队列头元素的地址
        queue.add(root);
        while (queue.peek() != null)
        {
            temp = queue.poll();
            System.out.print(temp.weight + " ");
            if(temp.lChild != null)
            {
                queue.add(temp.lChild);
                nextLast = temp.lChild;
            }

            if(temp.rChild != null)
            {
                queue.add(temp.rChild);
                nextLast = temp.rChild;
            }

            if(theLast == temp) //判断是否到达当前层的最后一个节点
            {
                System.out.println();//换行
                theLast = nextLast;
            }
        }
    }

    public static void prevOrder(HuffmanTreeNode root) {
        if(root == null)
        {
            return;
        }
        System.out.print(root.weight + " ");
        prevOrder(root.lChild);

        prevOrder(root.rChild);
    }
}

以上就是哈夫曼树实现,觉得可以的话可以关注走一手 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值