cs50 pset3排序函数

cs50 pset3排序函数,c,cs50,C,Cs50,我在pset3上实现排序功能时遇到问题。我使用了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])

我在pset3上实现排序功能时遇到问题。我使用了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;
            }
        }
    }
} 
void排序(int值[],int n)
{
对于(int k=0;k=值[j])
{
int temp=值[k];
值[k]=值[j];
数值[j]=温度;
}
}
}
} 

您很接近,但您的循环不太正确-更改:

for (int k = 0; k < n; k++)
{
    for (int j = 0; j < n; j++)
    {
应该是:

        if (values[k] > values[j])

从目前的情况来看,这并不是不正确的(代码仍然可以工作),但是交换相等的元素是没有意义的,因此编写时效率有点低。

我将您的代码转换成一个完整的程序。它比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;
}

这将显示每次按降序排序的数据,尽管随机输入不同。

尝试使用调试器逐步执行。如果出现“语法问题”,编译器将拒绝代码。如果您在GDB中运行它,那么问题不在于语法,而在于逻辑。它不是特别有效,但是代码在大小为3和5的数组上按降序排序。(为什么不高效?嗯,除其他外,它将数字与自身进行比较,如果数字等于自身,则将值与自身进行交换,这不会对事情产生太大的影响。)我认为您对循环的重写是一个效率问题,而不是技术上的必要性。至少,对于我运行的(还不是非常严格的)测试,问题中的代码按原样工作。类似的比较。@JonathanLeffler:你确定吗?对于原始循环,当jk时,元素将交换,因此最终的排序应该仍然是随机的。这可能只是因为你使用了任何输入数据,你都很幸运?好吧,我在大小为3、5、9的数组上运行了它,大小为5的数组有5个随机排列,大小为9的数组有9个随机排列,每次都对数据进行排序。代码一直在比较已经排序的数据,但除了性能之外,这不是一个问题。我还没有(尚未)在“每次交换”级别进行检测-这并不难,尽管我想升级数组打印代码,以便在调用时使用“标记”字符串来标识,并且我会确保标记标识发生了什么交换。我没有声称这种排序是有效的——事实并非如此。但从经验上看,它似乎最终会起作用。我很想看看你的计数器演示。是的,没有进行不必要的交换,但最终结果仍然正确排序。这里有一个较短的跟踪(使用
SWP
而不是
Swap
在我的屏幕上提供了很好的对齐输出-没有太多的注释):
种子:753593906
-
在5:60521
SWP(0,0):60521-
SWP(0,1):06521
-
SWP(1,0):60521:6 0 5 2 1
-
SWP(2,1):6 5 0 2 1
-
SWP(2,2):6 5 0 2 1
-
SWP(3,2):6 5 2 0 1
-
SWP(4,3):6 5 2 0 1
-
SWP(4,4):6 5 2 1 0
-
。是的,排序是次优的。不过,它确实有效。
        if (values[k] > values[j])
#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;
}
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