gpt4 book ai didi

java - FlagSort - 分而治之 - 小麻烦

转载 作者:行者123 更新时间:2023-11-29 09:13:55 24 4
gpt4 key购买 nike

在实现特定的排序算法时,我遇到了一个连 Google 都不想帮助我的问题...首先关于算法的一些话:

最重要的是将输入(数组)分成三部分:选择两个关键数字(红色和蓝色,断言红色 <= 蓝色),分区的元素将 (1) 小于两者,(2 ) 之间的某处和 (3) 大于两个枢轴。这是工作正常的部分!

数组排序应该递归地进行:在划分它们的分区之前使用任意枢轴对输入进行划分,从而以长度为 1 或 2 的粒子结束,这些粒子按 def 排序。或者更确切地说,可以很容易地进行排序。

问题是现在长度 >= 3 的分区由一个键值组成:如果再次分区,无论选择什么枢轴,之后所有元素都被放入同一个分区,最终遇到堆栈溢出。 这就是为什么我认为您能够帮助我,因为我确信有解决方案。

Mandatory JavaCode snippet: Partitioning - 对不起德国调试,也懒得翻译了。 IntTuple 只能容纳两个整数;没什么太荒谬的。

public static IntTuple partition(int[] E, int left, int right, int red, int blue){
if (red > blue) {
int v = red;
red = blue;
blue = v;
}
System.out.println("Partition Eingabe: " + Arrays.toString(E) + " Links=" + left + " Rechts=" + right + " Rot=" + red + " Blau=" + blue);
/*
* Es gilt r <= b, also gilt für beliebige x...
* ... x < r => x < b
* ... x > b => x > r.
*
* Das Gerüst für diesen Algorithmus wurde kopiert von Folie 7-13
*/
IntTuple result = new IntTuple (left, right); // rote und blaue Regionen sind leer
int u = left; // weiße Region ist leer, die unbekannte == E[left...right]
while (u <= result.v2) {
System.out.print("E[" + u + "]: ");
if (E[u] < red) {
System.out.print("rot ");
swap(E, result.v1, u);
result.v1++; // vergrößere die rote Region
u++; // verkleinere die unbekannte Region
} else if ((E[u] >= red) && (E[u] <= blue)) {
System.out.print("weiß ");
u++; // verkleinere die unbekannte Region
} else if (E[u] > blue) {
System.out.print("blau ");
swap(E, result.v2, u);
result.v2--; // vergrößere die blaue Region
}
System.out.print("Partition Schritt: [");
for(int i = left; i < right; i++)
System.out.print("" + E[i] + " ");
System.out.println("" + E[right] + "]");
}
System.out.print("Partition Ausgabe: [");
for(int i = left; i < right; i++)
System.out.print("" + E[i] + " ");
System.out.println("" + E[right] + "]" + " RotG=" + result.v1 + " BlauG=" + result.v2);
return result;
}

强制 JavaCode 片段:排序

private static void flagSort(int[] E, int left, int right){
System.out.println("Sortiere: " + left + " bis " + right);
if(left < right - 1) {
Random rnd = new Random();
IntTuple v = partition(E, left, right, rnd.nextInt(50), rnd.nextInt(50));
//IntTuple v = partition(E, left, right, E[left], E[left + 1]);
flagSort(E, left, v.v1 - 1);
flagSort(E, v.v1, v.v2);
flagSort(E, v.v2 + 1, right);
} else if((left == right - 1) && (E[left] > E[right])) {
swap(E, left, right);
}
}

非常感谢任何想法!

问候,LDer

更多:我想到了这个笨拙且笨拙的解决方案:

private static void flagSort(int[] E, int left, int right, boolean dual){
if(left < right) { // Singleton or empty segments are already sorted!
IntTuple v;
if(dual) // The last step has produced only a single white partition.
// Treat this partition with double pivot
v = partition(E, left, right, E[left], E[left]);
else // The last step has produced more than one partition, go on normally.
v = partition(E, left, right, E[left], E[left + 1]);
// Analyze partitions
if((left != v.v1) || (right != v.v2)) {
// 2 or 3 partitions available. Descend further.
flagSort(E, left, v.v1 - 1, false);
flagSort(E, v.v1, v.v2, false);
flagSort(E, v.v2 + 1, right, false);
} else if(!dual) {
// Only the white partition is not empty, partition it with double pivot
flagSort(E, v.v1, v.v2, true);
} // Last case: The only not-empty partition is white after partitioning with double pivot.
// Description of the algorithm immediately implies that this consists of only one key value, thus is sorted.
}
}

谁能帮忙创建一个更具可读性的版本?

更多:这个看起来好多了:

private static void flagSort(int[] E, int left, int right, int offset){
if(left < right) { // Singleton or empty segments are already sorted!
IntTuple v = partition(E, left, right, E[left], E[left + offset]);
// Analyze partitions
if ((left != v.v1) || (right != v.v2)) {
// 2 or 3 partitions available. Descend further.
flagSort(E, left, v.v1 - 1, 1);
flagSort(E, v.v1, v.v2, 1);
flagSort(E, v.v2 + 1, right, 1);
} else if (offset > 0)
// Only the white partition is not empty, partition it with double pivot
flagSort2(E, v.v1, v.v2, 0);
// Last case: The only not-empty partition is white after partitioning with double pivot.
// Description of the algorithm immediately implies that this consists of only one key value, thus is sorted.
}
}

特别感谢 toto2,尽管我没有明确传递红色/蓝色!

MORE:更多的随机性,因为 toto2 再次完全有一个点:

private static void flagSort(int[] E, int left, int right, int offset){
if(left < right) {
IntTuple v = partition(E, left, right, E[left + (offset % (right - left))],
E[left + ((2 * offset) % (right - left))]);
if ((left != v.v1) || (right != v.v2)) {
int random = rnd.nextInt(right - left);
flagSort(E, left, v.v1 - 1, random);
flagSort(E, v.v1, v.v2, random);
flagSort(E, v.v2 + 1, right, random);
} else if (offset > 0)
flagSort(E, v.v1, v.v2, 0);
}
}

最佳答案

每次调用分区方法时,都会发生一件简单的事情:蓝色和红色索引处的项目正是它们所属的位置。所以,当你调用这部分代码时:

    flagSort(E, left, v.v1 - 1);
flagSort(E, v.v1, v.v2);
flagSort(E, v.v2 + 1, right);

这些调用不能包含蓝色和红色,换句话说:

 flagSort(E, left, v.v1 - 1);
flagSort(E, v.v1 +1 , v.v2 -1);
flagSort(E, v.v2 + 1, right);

关于java - FlagSort - 分而治之 - 小麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10672901/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com