是否有多种条件进行快速排序?例如,我有一组边。每条边都有一个源,目的地和长度。我想先在我的数组中放入一个较小长度的边。但是如果长度相同,我想用较小的源顶点进行排序。如果这些源顶点相同,我想按两个目标顶点中较小的一个排序。
例如:
4(来源)2(目的地)3(长度)
1(来源)5(目的地)3(长度)
由于它们都具有相同的长度,因此我们查看源顶点。由于第二条边小于第一条边,我们交换它们,因为我们按源顶点进行比较。
下面是我的快速排序,我老实说也不确定为什么它没有正确排序。如果有办法让quicksort效率降低但更稳定,我很乐意接受建议!
void quickSort(edge *e, int left, int right)
{
int i = left, j = right;
int temp, temp1, temp2;
int pivot = (left + right)/2;
while(i <= j)
{
while(e[i] < e[pivot])
i++;
while(e[pivot] < e[j])
j--;
if(i <= j)
{
temp = e[i].getLength();
temp1 = e[i].getEdgeSrc();
temp2 = e[i].getEdgeDes();
e[i].setLength(e[j].getLength());
e[i].setEdgeSrc(e[j].getEdgeSrc());
e[i].setEdgeDes(e[j].getEdgeDes());
e[j].setLength(temp);
e[j].setEdgeSrc(temp1);
e[j].setEdgeDes(temp2);
i++;
j--;
} //if statement
}///while loop
if(left < j)
quickSort(e, left, j);
if(i < right)
quickSort(e, i, right);
}
我的条件分类:
bool edge::operator<(const edge &other) const
{
if (length < other.length)
return true;
else if ((length == other.length) && (source < other.source))
return true;
else if((length == other.length) && (source == other.source) && (destination < other.destination))
return true;
return false;
}
同样,如果有人知道通过减少它的时间复杂性而使其稳定来正确制作这个快速排序的方法,我很乐意接受任何建议!谢谢!有什么帮助吗?
编辑:这是我调用我的快速排序的方式。我根据读取的边数调用它。
quickSort(e, 0, edges-1); //-1 because if you put in edges, it'd go past the bounds of the array
编辑:当我尝试在我的算法中输入类似的东西时:
0 1 1
0 3 1
1 3 1
2 5 1
4 10 1
4 8 1
10 8 1
11 6 2
11 7 2
6 7 1
9 6 1
9 7 1
这是输出:
0 1 1
0 3 1
1 3 1
2 5 1
4 8 1
4 10 1
6 7 1
6 9 1
8 10 1&lt; - 应低于7 9 1
7 9 1&lt; - 应高于8 10 1
6 11 2
7 11 2
答案 0 :(得分:1)
以这种方式写它是更清洁
if (length != other.length)
return length<other.length;
if ( source != other.source)
return source < other.source;
return destination < other.destination;
你也应该能够temp = e[i]
等等,因为成员都是整体。
这(以及您提交的代码)应该完成您想要的任务。
如果您遇到稳定性问题,那是因为quicksort isnt stable。您可以通过添加更多条件来绕过它,以便lhs==rhs
不会发生。或者,您可以尝试Mergesort
坦率地说,我对快速排序没什么经验,但是你的impl看起来与Wikipedias In Place Algorithm明显不同。例如,您的枢轴根本不会移动。你能检查一下这是不是问题吗?
看起来链接的算法也使用pivot作为值而不是索引(就像你一样)。在您认为您的透视值可能会移动之前,它看起来在语法上与您的完全相同,之后您的透视索引将指向其他东西
int pivot = arr[(left + right) / 2];
这有帮助吗?
答案 1 :(得分:0)
编辑:这是就地快速排序的伪代码:http://en.wikipedia.org/wiki/Quicksort#In-place_version
这与您的代码的不同之处在于,pivot是一个值(左右值的平均值)而不是索引。
如果您正在寻找一个简单的非最优解,请按目标顶点合并整个列表,然后按原点顶点合并输出整个列表,然后按边长合并输出整个列表。这利用了mergesort是一种稳定的排序算法,并且在边数上有运行时间O(E)。