最近在读《大话数据结构》,周末闲下来就把书里的哈夫曼编码、求最小生成树的Prim、Kruskal以及求最短路的Dijkstra算法都实现了一遍,也顺便复习了一下优先队列的使用,代码可能不是很优雅欢迎指正!
#include
#include
#include
#include
#include
using namespace std;
struct TreeNode
{
char letter;
int val;
TreeNode *left;
TreeNode *right;
TreeNode(char c, int v) : letter(c), val(v), left(NULL), right(NULL){}
};
struct cmp
{
bool operator()(const TreeNode* a, const TreeNode* b) const
{
return a->val > b->val;
}
};
map<char, string> mp;//dfs求字母对应的编码
void dfs(TreeNode* p, string now)
{
if (p->letter>='A' && p->letter<='F') mp[p->letter] = now;
if (p->left) dfs(p->left, now + "0");
if (p->right) dfs(p->right, now + "1");
}
int main()
{
string ss = "BADCADFEED";
int a[6] = {27, 8, 15, 15, 30, 5};
priority_queue<TreeNode*, vector<TreeNode*>, cmp> heap;
for (int i = 0; i < 6; i++)
heap.push(new TreeNode(i+'A', a[i]));
TreeNode* p;
while (!heap.empty()){//合并值最小的两个,建立二叉树
p = heap.top();
heap.pop();
if (heap.empty()) break;
TreeNode* q = heap.top();
heap.pop();
TreeNode* tmp = new TreeNode('#', p->val+q->val);
tmp->left = p;
tmp->right = q;
heap.push(tmp);
}
mp.clear();
string now = "";
dfs(p, now);
//for (auto it : mp) cout << it.first << it.second << endl;
string new_ss = "";
for (char c : ss) new_ss += mp[c];
cout << new_ss << endl;//编码出来的字符串
for (int i = 0; i < new_ss.size(); i++){
TreeNode* tmp = p;
while (tmp->letter == '#'){
if (new_ss[i]=='0') tmp = tmp->left;
else tmp = tmp->right;
i++;
}
i--;
cout << tmp->letter;
}//由编码求原字符串
return 0;
}
我把图论里这三个算法都写在一起了,其中Prim算法和Dijkstra算法十分相似,复制以后稍微改改就是,毕竟原理都是取离v0最近的点,而书中这个Kruskal算法我觉得有点并查集的意思,通过找父亲来判断是否有环,反正学就完事了!至于Floyed算法我觉得没啥写的必要了。
#include
#include
#include
#include
#include
#include
using namespace std;
const int N = 15;
int n, m;
int dis[N];
struct node
{
int v, w;
node(int v, int w) : v(v), w(w){}
};
vector<node> mp[N];
struct cmp
{
bool operator()(const int &a,const int &b)
{
return dis[a] > dis[b];
}
};
struct Node
{
int u, v, w;
bool operator<(const Node& a) const
{
return w < a.w;
}
}edge[2*N];
void Prim()//get the node closest to v0, update vk's path
{
int k, adjvex[n];
memset(adjvex, 0, sizeof adjvex);
memset(dis, 0x3f, sizeof dis);
dis[0] = 0;
priority_queue<int, vector<int>, cmp> heap;
for (size_t i = 0; i < mp[0].size(); i++){
dis[mp[0][i].v] = mp[0][i].w;
heap.push(mp[0][i].v);
}
while (!heap.empty()){
k = heap.top();
heap.pop();
if (dis[k]==0) continue;
cout << adjvex[k] << " " << k << endl;
dis[k] = 0;
for (size_t i = 0; i < mp[k].size(); i++)
if (dis[mp[k][i].v]>0 && mp[k][i].w < dis[mp[k][i].v]){
dis[mp[k][i].v] = mp[k][i].w;
heap.push(mp[k][i].v);
adjvex[mp[k][i].v] = k;
}
}
}
int Find(int *parent, int f)
{
while (parent[f])
f = parent[f];
return f;
}
void Kruskal()//use the shortest path and judge whether there is a cycle
{
int parent[n];
memset(parent, 0, sizeof parent);
for (int i = 0; i < m; i++){
int u = Find(parent, edge[i].u);
int v = Find(parent, edge[i].v);
if (u != v){
parent[u] = v;
cout << edge[i].u << " " << edge[i].v << endl;
}
}
}
void Dijkstra()
{
int k, adjvex[n];
int vis[n];
memset(vis, 0, sizeof vis);
memset(adjvex, 0, sizeof adjvex);
memset(dis, 0x3f, sizeof dis);
dis[0] = 0;
//for (size_t i = 0; i < mp[0].size(); i++)
// dis[mp[0][i].v] = mp[0][i].w;
priority_queue<int, vector<int>, cmp> heap;
heap.push(0);
while (!heap.empty()){
k = heap.top();
heap.pop();
if (vis[k]) continue;
vis[k] = 1;
for (size_t i = 0; i < mp[k].size(); i++)
if (!vis[mp[k][i].v] && dis[k]+mp[k][i].w < dis[mp[k][i].v]){//这里和prim不同
dis[mp[k][i].v] = mp[k][i].w + dis[k];
heap.push(mp[k][i].v);
adjvex[mp[k][i].v] = k;
}
}
cout << endl;
for (int i = 1; i < n; i++){
int now = i;
while (now){
cout << now << "->";
now = adjvex[now];
}
cout << endl;
}
}
int main()
{
int u, v, w;
cin >> n >> m;
for (int i = 0; i < m; i++){
cin >> u >> v >> w;//Undirected graph
mp[u].push_back(node(v, w));
mp[v].push_back(node(u, w));
edge[i].u = u;
edge[i].v = v;
edge[i].w = w;
}
cout << endl;
Prim();
cout << endl;
sort(edge, edge+m);
Kruskal();
cout << endl;
Dijkstra();
return 0;
}
/*
9 15
0 1 10
0 5 11
1 2 18
1 6 16
1 8 12
2 3 22
2 8 8
3 4 20
3 6 24
3 7 16
3 8 21
4 5 26
4 7 7
5 6 17
6 7 19
*/