我正在研究我正在研究的霍夫曼编码项目的快速排序算法(解释为什么所有函数名称都以huff开头)。当使用调试器遍历它时,函数似乎在找到最高项时冻结(当试图从向量的右侧找到“不应该”在那一侧的术语时)。这个代码可能(可能是)其他问题,但我现在正专注于这个问题。顺便说一下,大部分时间(所有时间)我都叫cout,这是为了调试目的。
编辑:我从评论中对我的代码做了很多更正,但没有一个能解决我的问题。出于这个原因,我正在更新代码。
void huff_sort_partition(vector<Node*>* v, int b, int e){
int tempt = b+((rand()%(e-b))+1);
int p_idx = (*v)[tempt]->weight;
cout << tempt << endl;
int l = b+0;
int r = e;
cout << "P:" << p_idx << " L-R:" << l << "-" << r << endl;
while(l < r){
while((*v)[l]->weight < p_idx){
l++;
}
while((*v)[r]->weight > p_idx){
r--;
}
Node* s = (*v)[b+l];
(*v)[b+l] = (*v)[b+r];
(*v)[b+r] = s;
}
huff_sort_partition(v, b, l-1);
huff_sort_partition(v, l+1, e);
}
void Huff::huff_sort(vector<Node*>* v){
srand ( time(NULL) );
cout << "------sort------" << endl;
huff_sort_partition(v, 0, v->size());
}
编辑:我想我会添加这个,因为还没有人回答这个问题。如果代码“应该”工作,那么注释(这样我可以在这段代码之外找出原因,为什么它不能工作)。
答案 0 :(得分:1)
b,l
使用和停止条件时出现问题。
b
是从哪里开始修改的索引,e
是一个停止的索引。
因此,当您第一次为e
调用函数时,您必须引用最后一个索引而不是大小。
此外,您在huff_sort_partition
中缺少停止条件 - 为了不永远运行,您应该检查b
和e
索引是否相对于每个0/2都是正确的。
请尝试下面代码的固定版本
void huff_sort_partition(vector<Node*>* v, int b, int e){
if (b >= e ) {
return;
}
int p = (*v)[b+(rand() % (e - b + 1))]->weight;
int l = 0;
int r = e-b;
cout << "P:" << p << " L-R:" << l << "-" << r << endl;
while(l < r){
while((*v)[b+l]->weight < p){
l++;
}
while((*v)[b+r]->weight > p){
r--;
}
Node* s = (*v)[b+l];
(*v)[b+l] = (*v)[b+r];
(*v)[b+r] = s;
}
huff_sort_partition(v, b, b+l-1);
huff_sort_partition(v, b+r+1, e);
cout << "P:" << p << " L-R:" << l << "-" << r << endl;
for_each(v->begin(), v->end(), show_freq);
}
void Huff::huff_sort(vector<Node*>* v){
srand ( time(NULL) );
cout << "------sort------" << endl;
huff_sort_partition(v, 0, v->size() - 1);
}
答案 1 :(得分:1)
当有多个节点具有数据透视权重时,请考虑代码中发生的情况 - 为简单起见,请考虑权重[1, 9, 5, 2, 7, 5, 6, 8, 3, 7]
,并且枢轴索引为5,所以
void huff_sort_partition(vector<Node*>* v, int b, int e){
int p = (*v)[b+(rand() % (e - b + 1))]->weight;
我们有p = 5
int l = 0;
int r = e-b;
l = 0
和r = 9
cout << "P:" << p << " L-R:" << l << "-" << r << endl;
while(l < r){
while((*v)[b+l]->weight < p){
l++;
}
1 < 5
,然后增加l
,l = 1
,v[1] = 9 > 5
。
while((*v)[b+r]->weight > p){ // where it freezes up and wont move on
r--;
}
7 > 5
,递减r
,r = 8
,v[8] = 3 < 5
。交换v[1]
和v[8]
,提供[1, 3, 5, 2, 7, 5, 6, 8, 9, 7]
。
下一轮,l = 1 < 8 = r
。 v[1] = 3 < 5
,l
变为2,v[2] = 5
不小于5,循环结束。现在输入第二个内部循环,v[8] = 9 > 5
,v[7] = 8 > 5
,v[6] = 6 > 5
; v[5] = 5
不大于5,交换v[2]
和v[5]
,提供[1, 3, 5, 2, 7, 5, 6, 8, 9, 7]
。
下一轮,l = 2 < 5 = r
,v[2] = 5
不小于5,v[5] = 5
不大于5,交换v[2]
和v[5]
。哎呀,我们被困住了。
防止这种情况的通常方法是将枢轴交换掉,并使两个条件中的一个成为弱不等式,也必须在内环中检查条件l < r
,或者在案例中所有条目都相等,一个将从数组/向量的末尾运行。然后在分区之后,将枢轴交换到正确的位置。
以下代码使用标准方式(未经测试,可能存在拼写错误):
void huff_sort_partition(vector<Node*>* v, int b, int e){
// Nothing to sort if there are fewer than two elements
if (e <= b) return;
int tempt = b+((rand()%(e-b))+1);
int p_idx = (*v)[tempt]->weight;
// swap pivot out of the way
Node *tmp_Node = (*v)[tempt];
(*v)[tempt] = (*v)[e];
(*v)[e] = tmp_Node;
cout << tempt << endl;
int l = b;
int r = e - 1;
cout << "P:" << p_idx << " L-R:" << l << "-" << r << endl;
while(l < r){
while((l < r) && (*v)[l]->weight < p_idx){
l++;
}
while((l < r) && (*v)[r]->weight >= p_idx){
r--;
}
if (l < r){
Node* s = (*v)[l];
(*v)[l] = (*v)[r];
(*v)[r] = s;
// stuff at l and r is okay now, we don't need to test again
++l;
--r;
}
}
// Now l is the first index with weight >= pivot weight,
// swap pivot into place
tmp_Node = (*v)[l];
(*v)[l] = (*v)[e];
(*v)[e] = tmp_Node;
huff_sort_partition(v, b, l-1);
huff_sort_partition(v, l+1, e);
}