如图所示
在写小算法,哈夫曼树编码解码。
我尝试着在建树的步骤中使用优先队列,但是在运算符重载后,我发现了一个问题。
运算符重载的是结构体类型,但是优先队列中存储的是指针,在向优先队列中添加了结点后输出权值,输出的却是地址。
随后写了个小demo实验一番,如图所示,结果更奇怪了,在存入三个指针后,输出了两个地址和一个值
这是为什么?
小demo代码
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct demo {
int number;
bool operator < (const demo &a) const {
return number<a.number;
}
bool operator > (const demo &a) const {
return number>a.number;
}
//Init
demo() {
number = 0;
}
demo(int num) {
number = num;
}
};
int main() {
//优先队列
priority_queue<demo*, vector<demo*>, greater<demo*> > aaa;
for(int u = 1; u<= 3; u++) {
demo* ddd = new demo(u);
aaa.push(ddd);
delete ddd;
}
//输出所有
while(!aaa.empty()) {
cout << aaa.top()->number << endl;aaa.pop();
}
}
问题已解决,修改后代码为
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct demo {
int number;
bool operator < (const demo &a) const { return number<a.number;}
bool operator > (const demo &a) const { return number>a.number;}
//Init
demo() { number = 0;}
demo(int num) { number = num;}
};
int main() {
//优先队列
priority_queue<demo*, vector<demo*>, greater<demo*> > aaa;
demo* ddd = NULL;
for(int u = 1; u<= 3; u++) {
ddd = new demo(u);
aaa.push(ddd);
}
//输出所有
while(!aaa.empty()) {
cout << aaa.top()->number << " ";aaa.pop();
}
}
demo代码运行过吗?demo类的所有成员都是私有的?
aaa.push(ddd); 这里push存储的都是指针而已,你接着delete ddd就完蛋了。vector存储的全成了野指针了啊
push 了 后 把 delete 那句删掉
编写回溯算法代码时,要先考虑这个问题是一个什么搜索树,然后套用那个搜索树模板就行了。(例如:子集树就是:判断是否满足约束条件——计算、x[i]=1——递归左子树——归还——x[i]=0、递归右子树(注意限界思想))
(例如:排列树就是:循环——判断是否满足约束条件——交换——计算——递归(注意限界思想)——归还)
当然具体算法要具体分析
还要注意及时更新解和存储解,别忘了进入右子树、循环结束前,要将你算的、交换过的东西,要归还回去。注意到达叶结点干什么,没有到达怎么做
而分支限界算法的代码编写,首先编写三个类:活结点类、活结点属性类、入队类。然后选择好什么样的队列方式。一定要考虑好属性,然后什么时候添加结点、以及出队、和存储最优解
两个算法编写,还要注意限界函数的设置,怎么设计一个好的代价函数可以裁掉更多的空间。这就是两个算法的优化思想。
当然最重要的还要考虑好约束条件。
具体逻辑代码还是多写多练。多去总结。这里也就只讲个大体思路。