【问题标题】:Sorting an array in a specific way in the c languagec语言中以特定方式对数组进行排序
【发布时间】:2021-01-05 13:42:21
【问题描述】:

我一直在尝试对包含 26 个随机整数输入的数组进行排序,首先对奇数进行排序,然后按升序对偶数进行排序。到目前为止,我尝试的是使用选择排序算法并应用 if 语句。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int arr[26], i, min, j, p;
    srand((unsigned)time(NULL));
    for (i = 0; i < 26; i++) {
        arr[i] = rand() % 100;
    }
    for (i = 0; i < 26; i++) {
        printf("%2d ", i);
    }
    puts("");
    for (i = 0; i < 26; i++) {
        printf("%2d ", arr[i]);
    }

    for (i = 0; i < 26; i++) {
        if (arr[i] % 2 != 0) {
            min = i;
            for (j = i + 1; j < 25; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            p = arr[i];
            arr[i] = arr[min];
            arr[min] = arr[i];
        } else {
            min = i;
            for (j = i + 1; j < 25; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            p = arr[i];
            arr[i] = arr[min];
            arr[min] = arr[i];
        }
    }

    puts("");
    for (i = 0; i < 26; i++) {
        printf("%2d ", arr[i]);
    }

    return 0;
}

这似乎不是正确的做法,我有点迷茫,因为我是初学者。任何人都可以提供任何提示吗?哦,如果我的代码看起来像垃圾,请道歉。谢谢你的回答

【问题讨论】:

  • 我建议您首先对数组进行分区,将奇数放在数组的一端,将偶数放在另一端。然后找出拆分的位置,并使用标准qsort 将它们作为两个不同的数组进行排序。
  • qsort 的比较器函数可以很容易地安排,首先它测试两个项目的“均匀性”,如果相同,则它们的值。只需要一个qsort
  • @Someprogrammerdude 非常感谢您的帮助。我会使用 qsort 函数来测试一下
  • @Someprogrammerdude 我怀疑这比直接将它们排序更有效。您将一遍又一遍地迭代相同的数据。我发布了一个示例作为答案。

标签: arrays c sorting


【解决方案1】:

一种方法是使用比较函数

  • 奇数小于偶数
  • 如果奇数/偶数相同,请比较数字

还有

  • 您交换元素的代码有误。在第三步中应分配p 而不是arr[i]
  • 搜索最小元素的循环是错误的,因为它们忽略了搜索中的最后一个元素。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int cmp(int a, int b)
{
    if (a % 2 != 0 && b % 2 == 0) return -1;
    if (a % 2 == 0 && b % 2 != 0) return 1;
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
}

int main()
{
    int arr[26],i,min,j,p;
    srand((unsigned)time(NULL));
    for(i=0;i<26;i++){
        arr[i] = rand() % 100;
    }
    for(i=0;i<26;i++){
        printf("%2d ", i);
    }
    puts("");
    for(i=0;i<26;i++){
        printf("%2d ", arr[i]);
    }

    for(i=0;i<26;i++){
        min = i;
        for(j = i+1;j<26;j++){
            if(cmp(arr[j],arr[min])<0){
                min = j;
            }
        }
        p = arr[i];
        arr[i] = arr[min];
        arr[min] = p;
    }

    puts("");
    for(i=0;i<26;i++){
        printf("%2d ", arr[i]);
    }

    return 0;
}

【讨论】:

  • 而且...a qsort alternative 也可以。
  • 非常感谢。虽然我在理解该功能的具体工作原理时遇到了一些麻烦,但我认为通过一些时间和练习,我会得到它。再次感谢很多
【解决方案2】:

在经典 C 中执行此操作的规范方法是使用 qsort 函数,然后提供一个回调函数来指定如何排序。

qsort 的升序回调函数可能如下所示:

int ascending (const void* o1, const void* o2)
{
  int a = *(const int*)o1;
  int b = *(const int*)o2;
  return a<b ? -1 : (a>b) ? 1 : 0;
}

然后您可以编写一个更专业的比较函数,如下所示:

int odd_then_even (const void* o1, const void* o2)
{
  int a = *(const int*)o1;
  int b = *(const int*)o2;
  
  if((a^b)&1)            // one is odd and one is even
    return a&1 ? -1 : 1; // if a is the odd return -1, otherwise return 1
  else                   // both odd or both even
    return ascending(o1, o2);
}

使用 10 个独特项目的完整示例:

#include <stdio.h>
#include <stdlib.h>

int ascending (const void* o1, const void* o2)
{
  int a = *(const int*)o1;
  int b = *(const int*)o2;
  return a<b ? -1 : (a>b) ? 1 : 0;
}

int odd_then_even (const void* o1, const void* o2)
{
  int a = *(const int*)o1;
  int b = *(const int*)o2;
  
  if((a^b)&1)            // one is odd and one is even
    return a&1 ? -1 : 1; // if a is the odd return -1, otherwise return 1
  else                   // both odd or both even
    return ascending(o1, o2);
}

void print_array (int array[10]);

int main (void)
{
  int array[10] = { 7,3,2,1,5,4,9,8,0,6 };
   
  qsort(array, 10, sizeof *array, ascending);
  print_array(array);

  qsort(array, 10, sizeof *array, odd_then_even);
  print_array(array);
}

void print_array (int array[10])
{
  for(int i=0; i<10; i++)
    printf("%d ", array[i]);
  puts("");
}

输出:

0 1 2 3 4 5 6 7 8 9
1 3 5 7 9 0 2 4 6 8

【讨论】:

  • 如果a == b 不应该ascending 返回0?按照编码,似乎违反了比较函数的约束:数组的内容按照compar指向的比较函数升序排序,该函数使用两个指向对象的参数调用被比较。如果第一个参数分别被认为小于、等于或大于第二个参数,则该函数应返回一个小于、等于或大于零的整数。 我想知道这是否会破坏qsort()使用精心挑选的数据集。
  • @chqrlie 并不重要,因为 qsort 会将它们按未指定的顺序排列,以防它们相等。不要与bsearch 混淆。
  • 应该没关系,但你能证明吗?稳定性论点似乎只是部分相关。
  • 7.22.5.2 "如果两个元素比较相等,则它们在结果排序数组中的顺序是未指定的。"此外,这些函数假装没有找到相同的对象。我知道没有排序算法会以某种方式要求项目比较相等。 qsort 可能会被实现为快速排序或合并排序。
  • Pedantic: if((a^b)&amp;1) 对 2 的补码 int 来说是一个 OK 测试,但对于带有 1 的补码的那个垃圾场恐龙来说却失败了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-02
  • 1970-01-01
  • 2021-03-18
  • 2020-02-28
  • 1970-01-01
相关资源
最近更新 更多