我有这个一维数组:
0, 0, 2, 0, 0, 0, 1, 7, 4, 0
我需要能够在C中对这个数组进行排序,其排序算法比冒泡排序更有效,比如插入排序。我还需要在不创建新数组的情况下对其进行排序。但是,我需要忽略0。
示例排序数组将是:
0, 0, 1, 0, 0, 0, 2, 4, 7, 0
答案 0 :(得分:3)
您运行与插入排序运行相同的算法,但实际移动值时,跳过零。
所以举个例子:
0, 0, 2, 0, 0, 0, 1, 7, 4, 0
假设没有零:2, 1, 7, 4
。您阅读1
,将其与之前的值(2)进行比较,然后将2移到1
所在的位置:
2, 1*, 7, 4 (copy 1 to register, shift the 2 since it is bigger than 1)
2, 2*, 7, 4 (write the 1 in that place)
1, 2*, 7, 4 (since there are no previous elements we are done)
在该迭代结束时,星号前的所有内容都已排序。
现在与零的区别在于您需要跟踪“上一个”和“当前”位置(<
和>
)
0, 0, 2, 0, 0<, 1*> (copy 1 to register, compare to value at `<`)
0, 0, 2, 0<, 0, 1*> (Since it is zero, move the previous head further back)
0, 0, 2<, 0, 0, 1*> (Since it is zero, move the previous head further back)
0, 0, 2<, 0, 0, 2*> (Check if 1 < 2. Since it is, write the 2 in the current head)
0, 0, 2<>, 0, 0, 2* (move the current head)
0, 0<, 2>, 0, 0, 2* (move the previous head back)
0<, 0, 2>, 0, 0, 2* (move the previous head back)
0<, 0, 1>, 0, 0, 2* (Since we hit the front, we know that we have to write the `1` in the place marked by the "current" position)
如果您没有达到目的,请考虑0, 1, 0, 3, 0, 2, 0
。第六次迭代中的步骤是
0, 1, 0, 3, 0, 2*<>, 0
....
0, 1<, 0, 3>, 0, 3*, 0 (do the comparison and see that 1 < 2 but 2 < 3, so we want to write the 2 here and end this iteration)
0, 1<, 0, 2>, 0, 3*, 0 (now we know the elements before the * are sorted, so we can move on)
答案 1 :(得分:0)
修改快速排序算法,以便:
当您决定项目是否在枢轴的左侧或右侧时,它保持不变0
确保您没有选择0作为枢轴值。因此,随机qsort可能是更好的选择
如果[递归]输入数组全部为零,请确保返回
例如,从the Rosetta code修改:
void quick_sort (int *a, int n) {
if (n < 2) return;
// don't sort all-zero sub-arrays:
int c = 0,i;
for (i=0; i < n; i++) { c += a[i]; }
if (!c) return;
// don't choose 0 as the pivot value:
int p;
do {
p = a[rand()%n];
} while (p == 0);
int *l = a;
int *r = a + n - 1;
// make sure not to move zeros:
while (l[0] == 0 || l <= r) {
if (*l < p) {
l++;
continue;
}
if (r[0] == 0 || *r > p) {
r--;
continue;
}
int t = *l;
*l++ = *r;
*r-- = t;
}
quick_sort(a, r - a + 1);
quick_sort(l, a + n - l);
}
答案 2 :(得分:-1)
首先,从观察开始,当您将域限制为整数时,只有一个零。要忽略的值不需要留在内存中。否则,如果你排序的不是整数,而是按第一个坐标排序的整数对,那么会有很多零(<0,0>
,<0,1>
,...),你必须以某种方式存储它们
在这种情况下,您可以将所有非零数字移动到数组的开头,将它们移动到最初包含零的点;在这样做时,记录零在数组末尾的索引。
此时,您可以对数组的开头进行排序,然后按零顺序交错值,就像在数组末尾有适当的索引一样。