Arrays 对数组中大于n的元素按升序排序,其余元素按降序排序

Arrays 对数组中大于n的元素按升序排序,其余元素按降序排序,arrays,c,sorting,Arrays,C,Sorting,我需要对C中的数组进行升序和降序排序 大于n的值需要放在第一位,并按升序排列,小于n的值将放在最后,并按降序排列。输入数量未知,下面的代码不反映实际输入,仅作为示例 #include <stdio.h> void main(){ int n = 4; int arr[] = {5, 6, 2, 8, 3} #包括 void main(){ int n=4; int arr[]={5,6,2,8,3} 结果输出为5,6,8,3,2 我的解决方案: if (arr[0] >

我需要对C中的数组进行升序和降序排序

大于n的值需要放在第一位,并按升序排列,小于n的值将放在最后,并按降序排列。输入数量未知,下面的代码不反映实际输入,仅作为示例

#include <stdio.h>

void main(){

int n = 4;
int arr[] = {5, 6, 2, 8, 3}
#包括
void main(){
int n=4;
int arr[]={5,6,2,8,3}
结果输出为5,6,8,3,2

我的解决方案:

if (arr[0] >n){
  for (i = 0; i < arrSize; i++){
     for (j = 0; i < arrSize; j++){
     if ( arr[j] < arr[i] && arr[i] < n){
       int temp = arr[i];
       arr[i] = arr[j];
       arr[j] = temp;
     }
     else if(arr[i] < n){
      int temp2 = arr[n-1];
      arr[n-1] = arr[i];
      arr[i] = temp2;
     }
     
if(arr[0]>n){
对于(i=0;i
这一部分在第一部分(数组元素>n)可以正常工作。我在后面的部分遇到了问题。从前面的代码继续我的解决方案:

if (arr[0] >n){
  for (i = 0; i < arrSize; i++){
     for (j = 0; i < arrSize; j++){
     if ( arr[j] < arr[i] && arr[i] < n){
       int temp = arr[i];
       arr[i] = arr[j];
       arr[j] = temp;
     }
     else if(arr[i] < n){
      int temp2 = arr[n-1];
      arr[n-1] = arr[i];
      arr[i] = temp2;
     }
     
else if(arr[i]
不幸的是,这只适用于n以下的元素,如果它们连续放置在输入中,否则排序失败


非常感谢您对我能阅读的有关此排序的主题的任何帮助或参考。如果有人问我,我表示歉意。我在stackoverflow搜索中没有找到任何类似的内容

您可以通过3个步骤解决您的问题:

  • 首先将数组划分为大于
    n
    的元素和小于或等于
    n
    的元素
  • 然后按升序对前半部分进行排序
  • 然后按降序对后半部分进行排序
void交换(int*array,int i,int j){
int temp=数组[i];
数组[i]=数组[j];
数组[j]=温度;
}
void split_排序(int*数组、int大小、int n){
inti,j,中间;
/*使用n作为轴值对数组进行分区*/
对于(i=0,j=size;in)
i++;
而(j>i&&array[j-1]=j)
打破
交换(数组,i++,--j);
}
中间=i;
/*使用简化算法按升序对左半部分进行排序*/
对于(i=1;i数组[i]){
交换(数组,i,j);
}
}
}
/*使用简化算法按降序对右半部分进行排序*/
对于(i=middle+1;i
尝试以下操作-

  • 在单个迭代中使用快速排序透视技术(可能需要自定义实现)将给定数组拆分为两个数组(一个需要升序,另一个需要降序)。此透视与问题陈述中的透视相同
  • 使用快速排序或等效方法对左半部分进行升序排序,右半部分进行降序排序
  • 排序算法具有“稳定”(保留元素顺序)和“在位”(不使用额外内存/RAM)方面/行为。您在问题中没有指出这一点,因此我假设不需要“稳定”行为。如果需要,您可能必须修改第一步并使用合并排序技术(一次迭代),然后使用合并排序按升序和降序对数组进行排序
  • 注意-对于降序排序,您只需先按升序对数组排序,然后将其反转即可
  • 更新#1:如评论中所述,在反转时需要小心,以保持元件的“稳定”行为(特别是,不要对相等元件应用反转)

  • 您可以将标准的
    qsort()
    函数与适当的比较函数一起使用。因为您还需要
    N
    ,所以它必须是一个全局变量。下面是一个这样的比较器(带有测试线束)-但请注意第三个程序中更简单的比较器(总是有改进的余地):

    在Linux和Mac系统上,还有一个
    qsort_r()
    ,允许您将
    N
    作为值传递给比较器函数-但不幸的是,这两个系统上的签名不同:

    MacOS(BSD):

    Linux:

    void qsort_r(void *base, size_t nmemb, size_t size,
                 int (*compar)(const void *, const void *, void *), void *arg);
    
    比较函数有一个额外的参数,一个指针被传递到转发到比较器的
    qsort()
    。但是,调用序列不同。下面是使用MacOS变体的代码-Linux变体的更改很简单

    /*
    ** Sort values greater than N first in ascending order, and values less
    ** than N last in descending order, with values equal to N in the middle.
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    static int comparator(void *v0, const void *v1, const void *v2)
    {
        int N = *(int *)v0;
        int a = *(int *)v1;
        int b = *(int *)v2;
    
        if (a < N && b < N)
            return (a < b) - (a > b);   /* Descending */
        else if (a > N && b > N)
            return (a > b) - (a < b);   /* Ascending */
        else if (a > N && b < N)
            return -1;
        else if (a < N && b > N)
            return +1;
        else if (a == N && b > N)
            return +1;
        else if (b == N && a < N)
            return +1;
        else if (a == N && b < N)
            return -1;
        else if (b == N && a > N)
            return -1;
        else
            return 0;
    }
    
    static void dump_array(const char *tag, size_t n, int *data)
    {
        printf("%s (%zu):\n", tag, n);
        const char *pad = "";
        size_t i;
        for (i = 0; i < n; i++)
        {
            if (i > 0 && i % 10 == 0)
            {
                putchar('\n');
                pad = "";
            }
            printf("%s%3d", pad, data[i]);
            pad = ",";
        }
        if (i % 10 != 0)
            putchar('\n');
        putchar('\n');
    }
    
    int main(void)
    {
        int N = 56;
        // random -n 100 0 99 | commalist -B 8 -n 10 -W 2
        static int data[] =
        {
            22, 90, 87, 54, 81, 72, 68, 44, 82, 56,
            45, 66, 97, 69, 84,  7, 47, 27, 77, 11,
            99, 57, 95, 61, 90, 10, 98, 17, 29, 26,
             5, 39,  8, 61, 38, 90, 92, 85, 19, 39,
            76, 34, 97,  7, 23, 19, 27, 71,  8, 59,
            64, 25, 78, 28,  6, 65, 32, 47, 96,  3,
            55,  9, 75, 59,  5, 71, 83,  0, 95,  2,
            38, 61, 96, 94, 75, 40, 87, 75, 58, 49,
             4, 48, 58,  8, 99, 60, 91, 91, 46, 27,
            90, 85, 53, 60, 85, 46, 51, 33, 71, 92,
            13, 14, 60,  3, 94, 38,  2, 62, 33, 27,
            69, 33, 36, 66, 40, 63, 53, 34, 11,  4,
            56, 66, 86,  5, 95, 84, 69, 49, 49, 39,
            48, 91, 22, 35, 50, 64, 94, 35, 44, 97,
            70, 14, 28, 36, 68, 52, 69,  2, 54, 80,
        };
        enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
    
        dump_array("Before", NUM_DATA, data);
        qsort_r(data, NUM_DATA, sizeof(data[0]), &N, comparator);
        dump_array("After", NUM_DATA, data);
        return 0;
    }
    
    代码有一个带有
    RETURN
    宏的粗略调试功能。当
    print\u RETURN
    变量设置为
    1
    时,它会打印诊断信息。比较器中的所有返回语句都可以使用宏。在检查比较器函数中哪些比较可以省略时,它非常有用


    代码可以做得更彻底。它可以检查守恒特性(输出中的每个值都出现在输入中;输入中的每个值都出现在输出中)。它可以使用比
    srand()
    /
    rand()
    组合更好的随机数生成器。它可以从标准输入中读取数字(或命名文件),或由命令行参数控制-以便可以在命令行上指定种子,或打印种子以获得再现性。所有这些修改都留给读者作为练习。

    将问题分开:1.编写一个比较两个元素的函数(这是这里的关键部分).2.使用任何排序算法(例如预定义的
    qsort
    )使用自定义比较器对数组进行排序(而不是
    该问题是否在某个位置在线?“大于n的值需要首先递增,小于n的值将以降序排列在末尾。”任何值应该在哪里
    
    /*
    ** Sort values greater than N first in ascending order, and values less
    ** than N last in descending order, with values equal to N in the middle.
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    static int comparator(void *v0, const void *v1, const void *v2)
    {
        int N = *(int *)v0;
        int a = *(int *)v1;
        int b = *(int *)v2;
    
        if (a < N && b < N)
            return (a < b) - (a > b);   /* Descending */
        else if (a > N && b > N)
            return (a > b) - (a < b);   /* Ascending */
        else if (a > N && b < N)
            return -1;
        else if (a < N && b > N)
            return +1;
        else if (a == N && b > N)
            return +1;
        else if (b == N && a < N)
            return +1;
        else if (a == N && b < N)
            return -1;
        else if (b == N && a > N)
            return -1;
        else
            return 0;
    }
    
    static void dump_array(const char *tag, size_t n, int *data)
    {
        printf("%s (%zu):\n", tag, n);
        const char *pad = "";
        size_t i;
        for (i = 0; i < n; i++)
        {
            if (i > 0 && i % 10 == 0)
            {
                putchar('\n');
                pad = "";
            }
            printf("%s%3d", pad, data[i]);
            pad = ",";
        }
        if (i % 10 != 0)
            putchar('\n');
        putchar('\n');
    }
    
    int main(void)
    {
        int N = 56;
        // random -n 100 0 99 | commalist -B 8 -n 10 -W 2
        static int data[] =
        {
            22, 90, 87, 54, 81, 72, 68, 44, 82, 56,
            45, 66, 97, 69, 84,  7, 47, 27, 77, 11,
            99, 57, 95, 61, 90, 10, 98, 17, 29, 26,
             5, 39,  8, 61, 38, 90, 92, 85, 19, 39,
            76, 34, 97,  7, 23, 19, 27, 71,  8, 59,
            64, 25, 78, 28,  6, 65, 32, 47, 96,  3,
            55,  9, 75, 59,  5, 71, 83,  0, 95,  2,
            38, 61, 96, 94, 75, 40, 87, 75, 58, 49,
             4, 48, 58,  8, 99, 60, 91, 91, 46, 27,
            90, 85, 53, 60, 85, 46, 51, 33, 71, 92,
            13, 14, 60,  3, 94, 38,  2, 62, 33, 27,
            69, 33, 36, 66, 40, 63, 53, 34, 11,  4,
            56, 66, 86,  5, 95, 84, 69, 49, 49, 39,
            48, 91, 22, 35, 50, 64, 94, 35, 44, 97,
            70, 14, 28, 36, 68, 52, 69,  2, 54, 80,
        };
        enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
    
        dump_array("Before", NUM_DATA, data);
        qsort_r(data, NUM_DATA, sizeof(data[0]), &N, comparator);
        dump_array("After", NUM_DATA, data);
        return 0;
    }
    
    /* SO 6366-2914 */
    /*
    ** Sort values greater than N first in ascending order, and values less
    ** than or equal to N last in descending order.
    */
    
    #include <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define RETURN(v) \
        do { \
            if (print_return) \
                printf("%2d: %2d <=> %2d --> %+d\n", __LINE__, a, b, (v)); \
            return(v); \
        } while (0)
    
    static int print_return = 0;
    static int N;
    
    static int comparator(const void *v1, const void *v2)
    {
        int a = *(int *)v1;
        int b = *(int *)v2;
    
        if (a <= N && b <= N)
            return((a < b) - (a > b));   /* Descending */
        else if (a > N && b > N)
            return((a > b) - (a < b));   /* Ascending */
        else if (a > N)
        {
            assert(b <= N);
            RETURN(-1);
        }
        else
        {
            assert(a <= N && b > N);
            RETURN(+1);
        }
    }
    
    static void dump_array(const char *tag, size_t n, const int *data)
    {
        printf("%s (%zu) N = %2d:", tag, n, N);
        const char *pad = "";
        size_t i;
        for (i = 0; i < n; i++)
        {
            if (i % 10 == 0)
                pad = "\n";
            printf("%s%3d", pad, data[i]);
            pad = ",";
        }
        putchar('\n');
        putchar('\n');
    }
    
    static void check_order(size_t n, const int *data, int breakpoint)
    {
        size_t i = 0;
        for (i = 1; i < n && data[i] > breakpoint; i++)
        {
            if (data[i-1] > data[i])
                fprintf(stderr, "FAIL: A[%zu] = %2d out of ascending sequence with A[%zu] = %2d\n",
                        i-1, data[i-1], i, data[i]);
        }
        for ( ; i < n; i++)
        {
            if (data[i-1] < data[i])
                fprintf(stderr, "FAIL: A[%zu] = %2d out of descending sequence with A[%zu] = %2d\n",
                        i-1, data[i-1], i, data[i]);
        }
    }
    
    int main(void)
    {
        // random -n 100 0 99 | commalist -B 8 -n 10 -W 2
        static int data[] =
        {
            22, 90, 87, 54, 81, 72, 68, 44, 82, 56,
            45, 66, 97, 69, 84,  7, 47, 27, 77, 11,
            99, 57, 95, 61, 90, 10, 98, 17, 29, 26,
             5, 39,  8, 61, 38, 90, 92, 85, 19, 39,
            76, 34, 97,  7, 23, 19, 27, 71,  8, 59,
            64, 25, 78, 28,  6, 65, 32, 47, 96,  3,
            55,  9, 75, 59,  5, 71, 83,  0, 95,  2,
            38, 61, 96, 94, 75, 40, 87, 75, 58, 49,
             4, 48, 58,  8, 99, 60, 91, 91, 46, 27,
            90, 85, 53, 60, 85, 46, 51, 33, 71, 92,
            13, 14, 60,  3, 94, 38,  2, 62, 33, 27,
            69, 33, 36, 66, 40, 63, 53, 34, 11,  4,
            56, 66, 86,  5, 95, 84, 69, 49, 49, 39,
            48, 91, 22, 35, 50, 64, 94, 35, 44, 97,
            70, 14, 28, 36, 68, 52, 69,  2, 54, 80,
        };
        enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
    
        N = 56;
        dump_array("Before", NUM_DATA, data);
        qsort(data, NUM_DATA, sizeof(data[0]), comparator);
        dump_array("After", NUM_DATA, data);
        check_order(NUM_DATA, data, N);
    
        srand(time(0));
    
        for (size_t j = 0; j < 10; j++)
        {
            size_t n = rand() % 120 + 30;
            N = rand() % 60 + 20;
            for (size_t i = 0; i < n; i++)
                data[i] = rand() % 100;
            dump_array("Before", n, data);
            qsort(data, n, sizeof(data[0]), comparator);
            dump_array("After", n, data);
            check_order(n, data, N);
        }
    
        return 0;
    }