哈夫曼树template

class Node   //代表各个字符的结点
{
public:
	int data;
	string code;
    shared_ptr<Node> leftChild,rightChild;
    Node():leftChild(nullptr),rightChild(nullptr),code(""){}
};

template<typename T>
class Greater
{
public:
    bool operator()(T a, T b){ return a->data>b->data; }
};


void CreateTree(priority_queue<shared_ptr<Node>,vector<shared_ptr<Node>>,Greater<shared_ptr<Node>>> &t)
{
	int eleSize = t.size();
	//存储两个最小的结点和新结点
    shared_ptr<Node> lChild,rChild,newNode;
	if (t.empty()) return;
	//1.如果只有一个结点
	if (!t.empty() && t.size() < 2){
		lChild = t.top();
		newNode->leftChild = lChild;
		t.push(newNode);
        return;
	}
	//2.找出最小的两个结点构造新的结点
	for (int i = 0; i < eleSize-1; ++i){  //函数完成之后,heap中只存一个结点,为根结点

		lChild = t.top(),t.pop();
		rChild = t.top(),t.pop();
        newNode=make_shared<Node>(); //注意新节点虽然同名,但是就是一个新的
        newNode->leftChild = lChild,newNode->rightChild = rChild;
		newNode->data = lChild->data+rChild->data;
		//将新建的结点重新插入到堆
		t.push(newNode);
	}
    return;
}

//创建赫夫曼编码
void CreateCode(shared_ptr<Node> t, unordered_map<int,string> &code){  //传入树根+不断递归
	if (t == nullptr) return;

	if (t->leftChild){
		t->leftChild->code = t->code + "0";
		CreateCode(t->leftChild,code);
	}
	if (t->rightChild){
		t->rightChild->code = t->code + "1";
		CreateCode(t->rightChild,code);
	}
	if (t->leftChild == nullptr && t->rightChild == nullptr)  //只对叶子结点的编码进行存储
		code[t->data]=t->code;
}
int main()
{
	//小根堆来存储输入的结点
	//这里heap存的是结点指针,必须用函数对象或者lamda表达式来确定比较方式
	priority_queue<shared_ptr<Node>,vector<shared_ptr<Node>>,Greater<shared_ptr<Node>>> heap;
    setbuf(stdout, NULL);
	//用来确保没有重复输入
	set<int> arr;

	cout << "请输入需要构造的结点(用空格隔开,按回车结束):" << endl;
	int e,n;
    cin>>n;
	while (n--){
        cin>>e;
        arr.insert(e);
    }

	//将输入的数据存入小根堆
	for (auto ele : arr){
		//构建结点放入小根堆
        shared_ptr<Node> newNode = make_shared<Node>();
		newNode->data = ele;
		heap.push(newNode);
	}
    CreateTree(heap);
    shared_ptr<Node> tree = heap.top();
	//创建huffMan编码
    unordered_map<int,string> code;
	CreateCode(tree, code);
	//查找相应的编码
    e=6;
    cout << e << "的编码为" << code[e];
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值