哈夫曼编码
描述:哈夫曼编码是可变字长编码(VLC)的一种,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字。
贪心策略:把编码映射成二叉树,把频率高的字符分配给靠近根节点的叶节点,把频率低的字符放置在远离根节点的叶节点。
自底向上构造二叉编码树,由森林不断合并得到一棵二叉树。
思路分析:为了便于找到频次最低的字符,哈夫曼算法建立一个以f为键值的优先队列Q,假设编码字符集中每一字符c的频率是f( c ).哈夫曼编码算法以自底向上的方式构造最优编码树T。
- 一开始,每个字符构成只包含一个节点的树
- 合并频率最低的两棵树,并产生一棵新树,其频率为合并的两棵树的频率之和,并将新树插入优先队列Q中。
- 循环n-1次后,优先队列中只剩下一棵树,即最优二叉编码树。
struct cmp{
bool operator()(connst int &x,const int &y){
return x>y ;
}
};//定义有限对列比较函数
double haffmanCoding(int n,int *freq){
int i,total = 0,sumFreq = 0,jointFreq ;
priority_queue<int,vector<int>,cmp> heap ;
for(int i=0;i<n;i++){
total += freq[i] ; //频率总和
heap.push(freq[i]) ;
}//形成有限对列
while(heap.size()>1){
//循环选择对列中频次最少的两个元素合并
jointFreq = 0 ; //合并两个节点的频率
for(int i=0;i<2;i++){
//删除频次最少的两元素
jointFreq += heap.top() ;
heap.pop() ;
}
sumFreq += jointFreq ;
heap.push(jointFreq) ; //优先队列中插入合并节点
}
return sumFreq/(1.0*total) ; 返回平均码长
}
//复杂度O(nlg(n))
单源最短路径
描述: 有向图G有n个顶点,给定每两个顶点的权值,权值为非负实数,如果权值为-1,表示没有边相连,默认第一个顶点为源。计算假设源可以到达任何一个顶点,从源到各顶点的最短路径长度。
特征:最短路径的子路径也是源到相应顶点的最短路径。
Dijstra算法:
贪心策略:选择集合V-S中受限路径长度最短的顶点,并把相应顶点加入到S中,相应地最短路径树T叶增加一条边。
代码:
#define INF 0x3f3f3f3f //预定义的充分大的数
#define MaxV 100
int preV[MaxV]; //最短路径树中的前驱节点信息表
int visited[MaxV]; //结点是否加入S的标记表,0是为加入,1是加入
void Dijkstra(int linkMatrix[][MaxV],int lowLR[MaxV