算法学习记录002_树-哈夫曼树

一、运行结果

Node(data=null, weight=73)
left:Node(data=null, weight=33)
left:Node(data=null, weight=16)
left:Node(data=a, weight=8)
right:Node(data=null, weight=8)
left:Node(data=g, weight=1)
right:Node(data=c, weight=7)
right:Node(data=f, weight=17)
right:Node(data=null, weight=40)
left:Node(data=e, weight=19)
right:Node(data=null, weight=21)
left:Node(data=b, weight=10)
right:Node(data=d, weight=11)

二、源代码

import kotlin.collections.ArrayList

/**
 * 哈夫曼树
 */
class HuffmanTree {

    /**
     * 节点:让其成为可比的,根据权重排序
     */
    class Node<T>(var data: T?, var weight: Int) : Comparable<Node<T>> {

        //左节点的权重
        var leftNode: Node<T>? = null
        //右结点的权重
        var rightNode: Node<T>? = null

        override fun compareTo(other: Node<T>): Int {
            return this.weight - other.weight
        }

        override fun toString(): String {
            return "Node(data=$data, weight=$weight)"
        }

    }

    fun <T> createHuffmanTree(nodes: ArrayList<Node<T>>): Node<T>? {
        //nodes等于1的时候表示只根节点了
        while (nodes.size > 1) {
            nodes.sort() //根据结点权重排序
 //           println(nodes)
            val leftNode = nodes[0]
            val rightNode = nodes[1]
            var parentNode = Node<T>(null, leftNode.weight + rightNode.weight)
            parentNode.leftNode = leftNode
            parentNode.rightNode = rightNode
            nodes.removeAt(0)//移除掉第一个元素
            nodes.removeAt(0)//移除掉第二个元素
            //把生成的父节点放到集合的最后面
            nodes.add(parentNode)
        }
        return if (nodes.isEmpty()) null else nodes[0]
    }

    /**
     * 递归打印哈夫曼树
     */
    fun <T> printTree(node: Node<T>?) {
        println(node)
        if (node?.leftNode != null) {
            print("left:")
            printTree(node.leftNode)
        }

        if (node?.rightNode != null) {
            print("right:")
            printTree(node.rightNode)
        }
    }
}

fun main() {
    var huffmanTree = HuffmanTree()
    var nodes = arrayListOf<HuffmanTree.Node<String>>()
    nodes.add(HuffmanTree.Node("a", 8))
    nodes.add(HuffmanTree.Node("b", 10))
    nodes.add(HuffmanTree.Node("c", 7))
    nodes.add(HuffmanTree.Node("d", 11))
    nodes.add(HuffmanTree.Node("e", 19))
    nodes.add(HuffmanTree.Node("f", 17))
    nodes.add(HuffmanTree.Node("g", 1))
    val tree = huffmanTree.createHuffmanTree(nodes)
    huffmanTree.printTree(tree)

}

源代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用中提到的,优先队列的时间复杂度为O(logn),其中n为队列中元素的个数。因此,使用priority_queue实现哈夫曼树的时间复杂度为O(nlogn),其中n为哈夫曼树中叶子节点的个数。 实现哈夫曼树的步骤如下: 1. 统计每个字符在文本中出现的频率,并将其作为权值构建一个森林,每个节点都是一棵只包含一个字符的。 2. 从森林中选出两棵根节点权值最小的,将它们合并成一棵新,新的根节点权值为两棵的根节点权值之和。 3. 将新插入到森林中,并删除原来的两棵。 4. 重复步骤2和3,直到森林中只剩下一棵,即为哈夫曼树。 下面是使用priority_queue实现哈夫曼树的C++代码示例: ```c++ #include <iostream> #include <queue> using namespace std; struct TreeNode { char ch; int freq; TreeNode *left, *right; TreeNode(char c, int f) : ch(c), freq(f), left(NULL), right(NULL) {} }; struct cmp { bool operator() (TreeNode* a, TreeNode* b) { return a->freq > b->freq; } }; TreeNode* buildHuffmanTree(string s) { int n = s.size(); vector<int> freq(256, 0); for (int i = 0; i < n; i++) { freq[s[i]]++; } priority_queue<TreeNode*, vector<TreeNode*>, cmp> pq; for (int i = 0; i < 256; i++) { if (freq[i] > 0) { pq.push(new TreeNode(i, freq[i])); } } while (pq.size() > 1) { TreeNode* left = pq.top(); pq.pop(); TreeNode* right = pq.top(); pq.pop(); TreeNode* parent = new TreeNode('#', left->freq + right->freq); parent->left = left; parent->right = right; pq.push(parent); } return pq.top(); } int main() { string s = "hello world"; TreeNode* root = buildHuffmanTree(s); // do something with the Huffman tree return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值