我在pset3上实现sort函数时遇到问题。我使用过GDB,发现我的sort函数没有排序。我不确定是否存在语法问题,或者逻辑是否有点搞砸了。
void sort(int values[], int n)
{
for (int k = 0; k < n; k++)
{
for (int j = 0; j < n; j++)
{
if (values[k] >= values[j])
{
int temp = values[k];
values[k] = values[j];
values[j] = temp;
}
}
}
}
答案 0 :(得分:1)
你很近,但你的循环不太正确 - 改变:
for (int k = 0; k < n; k++)
{
for (int j = 0; j < n; j++)
{
为:
for (int k = 0; k < n - 1; k++)
{
for (int j = k + 1; j < n; j++)
{
要理解为什么需要进行此更改,请考虑内部循环(j
)只需将索引k
上方的元素k
)需要从k
迭代到0
(比最后一个元素少一个),并且对于每个外部循环迭代,内部循环需要从{{迭代} 1}}(n - 2
之上的第一个元素)到k + 1
(最后一个元素)。
注意:纯粹的机会似乎原始代码 似乎正常工作,即使它乍一看似乎不应该。我已经使用各种边缘情况对其进行了测试,即使它执行了许多冗余交换,但最终结果似乎总是被排序(令人惊讶的是输出是以降序而固定代码在升序顺序,如预期的那样)。感谢Jonathan Leffler发现这一点 - 请参阅他的answer and demo program。
另一个小问题 - 这个测试:
k
应该只是:
n - 1
它不是不正确的(代码仍然可以工作),但交换相等的元素是没有意义的,所以写的效率有点低。
答案 1 :(得分:1)
我把你的代码转换成了一个完整的程序。它比MCVE大,因为它有支持代码用于改组数组,打印结果,以及运行这些的main()
当然。
#include <stdio.h>
#include <stdlib.h>
static int rand_int(int n)
{
int limit = RAND_MAX - RAND_MAX % n;
int rnd;
while ((rnd = rand()) >= limit)
;
return rnd % n;
}
static void shuffle(int *array, int n)
{
for (int i = n - 1; i > 0; i--)
{
int j = rand_int(i + 1);
int tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
}
static void print_array(int n, int a[n])
{
for (int i = 0; i < n; i++)
printf(" %d", a[i]);
putchar('\n');
}
static void sort(int values[], int n)
{
for (int k = 0; k < n; k++)
{
for (int j = 0; j < n; j++)
{
if (values[k] >= values[j])
{
int temp = values[k];
values[k] = values[j];
values[j] = temp;
}
}
}
}
int main(int argc, char **argv)
{
if (argc > 1)
{
long l = strtol(argv[1], 0, 0);
unsigned u = (unsigned)l;
printf("Seed: %u\n", u);
srand(u);
}
int data3[3] = { 3, 1, 2 };
print_array(3, data3);
sort(data3, 3);
print_array(3, data3);
int data5[5] = { 0, 2, 6, 1, 5, };
for (int i = 0; i < 5; i++)
{
shuffle(data5, 5);
print_array(5, data5);
sort(data5, 5);
print_array(5, data5);
}
int data9[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int i = 0; i < 9; i++)
{
shuffle(data9, 9);
print_array(9, data9);
sort(data9, 9);
print_array(9, data9);
}
return 0;
}
随机播放代码实现Fisher-Yates shuffle,并且是 基于answer Roland Illig的代码。如果在没有种子参数的情况下调用,则每次都会生成相同的输出。
使用GCC 6.2.0在macOS Sierra 10.12.1上编译和测试代码。
示例输出:
Seed: 123456789
3 1 2
3 2 1
6 0 1 5 2
6 5 2 1 0
0 6 1 2 5
6 5 2 1 0
0 1 2 6 5
6 5 2 1 0
5 0 6 1 2
6 5 2 1 0
1 6 5 2 0
6 5 2 1 0
0 4 8 3 7 5 1 6 2
8 7 6 5 4 3 2 1 0
7 4 0 5 6 8 3 2 1
8 7 6 5 4 3 2 1 0
1 2 7 5 0 8 3 6 4
8 7 6 5 4 3 2 1 0
3 8 7 5 2 1 0 6 4
8 7 6 5 4 3 2 1 0
1 4 2 6 3 0 7 5 8
8 7 6 5 4 3 2 1 0
2 3 7 4 8 0 5 6 1
8 7 6 5 4 3 2 1 0
3 4 5 8 6 2 0 7 1
8 7 6 5 4 3 2 1 0
3 6 7 4 8 2 5 1 0
8 7 6 5 4 3 2 1 0
0 8 7 3 4 6 5 1 2
8 7 6 5 4 3 2 1 0
这显示了数据每次都按降序排序,尽管有不同的随机输入。