哈夫曼编码go语言实现

//哈夫曼编码的实现,还未经过测试,只写了实现思路,后续还会改进优化
// Package huffman 构造哈夫曼树和哈夫曼编码
package huffman

// HuffmanTreeNode 哈夫曼树结点
type HuffmanTreeNode struct {
	Data rune  //结点数据域
	Weight int //结点权重
	Parent int //父结点索引
	LeftChild int //左子树根节点索引
	RightChild int //右子树根结点索引
}

// HuffmanCodes 用来存储哈夫曼编码表

var HuffmanCodes map[rune]int

// HuffmanTreeCoding 进行哈夫曼编码
func HuffmanTreeCoding(
	huffmanTree []HuffmanTreeNode, //哈夫曼树
	huffmanCodes map[rune][]byte, //用于存放哈夫曼编码表
	//用于存储n个结点的权重
	weight []int){
	if len(weight)<=1{
		return
	}

	huffmanTreeLength:=2*(len(weight))-1
	huffmanTree=make([]HuffmanTreeNode,huffmanTreeLength)

	for i := 0; i < len(weight); i++ {
		huffmanTree[i].Weight=weight[i]
	}

	for i := len(weight); i < huffmanTreeLength; i++ {
		huffmanTree[i].Weight=weight[i]
	}

	//构建哈夫曼树
	for i := len(weight); i < huffmanTreeLength; i++ {
		min,secondaryMin:=Select(huffmanTree,i-1)
		huffmanTree[min].Parent=i
		huffmanTree[secondaryMin].Parent=i
		huffmanTree[i].LeftChild=min
		huffmanTree[i].RightChild=secondaryMin
		huffmanTree[i].Weight=huffmanTree[min].Weight+huffmanTree[secondaryMin].Weight
	}


	for i := 0; i < len(weight); i++ {

		j:=i
		parent:=huffmanTree[j].Parent
		for {

			//这里每个字符串对应的哈夫曼编码存储在一个切片中,且为倒序存储,取用编码的时候需要倒着取
			if parent==0{
				break
			}
			if huffmanTree[parent].LeftChild==i {
				huffmanCodes[huffmanTree[i].Data] = append(huffmanCodes[huffmanTree[i].Data], '0')
			}else {
				huffmanCodes[huffmanTree[i].Data] = append(huffmanCodes[huffmanTree[i].Data], '1')
			}
			j=parent
			parent=huffmanTree[parent].Parent
		}
	}

}

// Select 从切片组成的哈夫曼树中,从huffmanTree[0...bound]中选出权重最小的两个结点,返回对应的结点
func Select(huffmanTree []HuffmanTreeNode,bound int) (min int,secondaryMin int) {
	min=0
	for i := 0; i < bound; i++ {
		if huffmanTree[i].Weight<huffmanTree[min].Weight{
			min=i
		}
	}
	secondaryMin=1
	for i := 0; i < bound; i++ {
		if huffmanTree[i].Weight<huffmanTree[secondaryMin].Weight &&i!=min{
			secondaryMin=i
		}
	}

	return min,secondaryMin

}

``

posted @ 2021-11-06 23:04  读史  阅读(238)  评论(0编辑  收藏  举报