对数组C中的元素进行排序

时间:2016-04-04 04:17:33

标签: c

我正在尝试创建一个程序,它将按4个步骤对元素进行排序(读取元素 - 打印元素 - 对它们进行排序 - 打印已排序的版本)。

我需要排序(第三)部分的帮助。

这是我的代码:

/*
 * A simple program to sort numbers in correct order                               
 */

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
#define SENTINEL -99

int main()
{
    int tableFill(int a[], int max);
    void tableInsert(int a[], int num, int val);
    void tableSort(int a, int n);
    void tablePrint(int a, int n);

    int num;
    int table[MAXSIZE];
    int max;

    num=tableFill(table,MAXSIZE);
    return EXIT_SUCCESS;
}

int tableFill(int a[], int max)
{
    int r;                  // input from scanf
    int next;               // score from user
    int cnt = 0;

    printf("Enter the numbers! \n");

    while ((r=scanf("%i", &next))!= EOF && cnt<max)
    {
        if (r == 0) //invalid input data
        {
            printf("Nonnumeric data entered. Please enter a number. \n");
            while (getchar()!= '\n');  // flush invalid data
        }
        else
            a[cnt++]=next;
    } 

    if(r==1)   //another value was read but the array is full
        printf("Error - too many values. Array size %i.\n", max);

}

void tableInsert (int a[], int num, int val)
{
    int pos;
    for(pos = num; pos>0 && val<a [pos-1]; pos--)
        a [pos] = a [pos -1];
    a[pos] = val;
}

void tableSort(int a, int n)
{

}

void tablePrint(int a, int n)
{
    int i;

    for(i = n -1; i>=0; i++)
    {
        printf("%i\n",a[i]);
    }
}

我使用了David C. Rankin的解决方案并修复了我的代码。这是我的最终版本:

   /*
   * A simple program to sort numbers in the correct order                              
   */

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

     #define MAXSIZE 10 //max elements in array

    int main () {

int tableFill (int a[], int max);
void tableSort (int a[], int n);
void tablePrint (const a[], int n);

int arr[MAXSIZE];   //creating an array
int n = tableFill (arr, MAXSIZE); //declaring variable to work with array
tablePrint (arr, n); //prints unsorted values

printf ("Here is your sorted array:\n");
tableSort (arr, n);  // sorts values in order
tablePrint (arr, n); // prints sorted values

return 0;
 }

 // read values from stdin into array up to 'max' values
  int tableFill(int a[], int max)   {

int r;              // input from scanf
int next;           // score from user
int cnt = 0;        // loop variable 

printf("Enter the numbers! \n");

while ((r=scanf("%i", &next))!= EOF && cnt<max)
{
    if (r == 0) //invalid input data
    {
        printf("Nonnumeric data entered. Please enter a number. \n");
        while (getchar()!= '\n');  // flush invalid data
    }
    else
        a[cnt++]=next;
} 

if(r==1)   //another value was read but the array is full
    printf("Error - too many values. Array size %i.\n", max);

return cnt;
 }

  // swap values at array indexes 'i' and 'j'.
  void tableSwap (int a[], int i, int min_index)
 {
int tmp = a[i];
a[i] = a[min_index];
a[min_index] = tmp;
 }

  //sort array
 void tableSort (int a[], int n)
{
void tableSwap (int a[], int i, int min_index);
int i, j; //loop counters
int min, min_index; //adjusting variables for loops

for (i = 0; i <= n - 2; i++) {
    min = a[i];
    min_index = i;
    for (j = i + 1; j <= n - 1; j++) {
        if (a[j] < min){
            min = a[j];
            min_index = j; 
        }
    }
    tableSwap (a, i, min_index);
}
 }

 //print all elements in array.
 void tablePrint (const a[], int n)
{
int i;  //variable for print
for (i = 0; i < n; i++)
    printf ("%d ", a[i]);
printf ("\n");
 }

2 个答案:

答案 0 :(得分:0)

关于

int tableFill(int a[], int max);
void tableInsert(int a[], int num, int val);
void tableSort(int a, int n);
void tablePrint(int a, int n);

你在main中声明原型,这通常不会完成。它们通常在全球范围内声明,以便它们保持到最后。

关于

int tableFill(int a[], int max)  

你没有归还任何东西。由于您正在处理指针,因此可以将int更改为void

关于

 void tableInsert (int a[], int num, int val)

问问自己你在哪里调用这个功能。

关于

void tableSort(int a, int n)
{

}

请参阅解释排序的this指南。

关于:

void tablePrint(int a, int n)
{
    int i;

    for(i = n -1; i>=0; i++)
    {
        printf("%i\n",a[i]);
    }
}

由于你正在打印一个数组,所以这个函数的一个参数应该是一个数组。

答案 1 :(得分:0)

正如评论中所指出的,qsort是C标准库中包含的事实标准排序例程。由于使用针对所排序数据范围优化的排序方法的组合,它非常灵活且速度极快。初级C用户通常难以编写比较函数,因为它涉及使用指针。只需花点时间写一些比较函数就可以了 - 从长远来看,它会为你节省很多麻烦。

也就是说,在查看两种替代排序之前,C风格通常使用小写字母表示变量和函数名称。保留C ++的camelCase名称。参见例如NASA - C Style Guide, 1994

使用旧 - 慢的气泡排序。对于排序超过100个元素的任何东西,bubort陨石坑的效率。对于任何大量元素,它比qsort慢几百倍。话虽如此,将一个包含tableswap要求的气泡放在一起很简单:

/** sort array using slow old bubblesort */
void tablebubblesort (int *a, int n)
{
    int i, j;

    for (i = 0; i < n - 1; i++) {
        for (j = 0; j < n - i - 1; j++) {
            if (a[j] > a[j + 1])            /* For decreasing order use < */
                tableswap (a, n, j, j+1);
        }
    }
}

您的tableswap功能类似于:

/** swap values at array indexes 'i' and 'j'. */
void tableswap (int *a, int n, int i, int j)
{
    if (i >= n || j >= n) return;
    int tmp = a[i];
    a[i] = a[j];
    a[j] = tmp;
}

只需使用tablebubblesort (arr, n);

调用代码中的函数即可

qsort更简单。完整的功能(你真的不需要一个单独的功能)是:

/** qsort the array */
void tablesort (int *a, int n, size_t sz)
{
    qsort (a, n, sz, compare);
}

它需要一个简单的比较函数:

/** qsort compare function */
int compare (const void *a, const void *b)
{
    return (*(int *)a - *(int *)b);
}

不要因为你看到const void *a等而让你的眼睛在你的脑海里滚动。它真的很直接。您的ab指针表示指向数组中各个整数的指针(例如,如果说a[1] = 5,则指针只是&a[1]元素的地址)。因此,将compare函数分开,知道你只是传递一个元素的地址(例如整数指针)进行比较,你可以像下面这样编写它:

int compare (const void *a, const void *b)
{
    int *value1 = (int *)a; /* cast each to int pointer */
    int *value2 = (int *)b;

    if (*value1 > *value2)  /* compare dereferenced values */
        return 1;
    if (*value1 < *value2)
        return -1;

    return 0;
}

或者,如果它让你更快乐,你可以一次转换和取消引用,然后只对整数值进行操作:

int compare (const void *a, const void *b)
{
    int value1 = *(int *)a;
    int value2 = *(int *)b;

    if (value1 > value2)
        return 1;
    if (value1 < value2)
        return -1;

    return 0;
}

无论哪种方式都是一样的。 (可以说,第一个是最合适的,因为它避免了“外观”类型的惩罚指针和derefencing void值,但那是另一天)没有魔法,只需要做足够的时间整数,字符串,结构等等。直到它沉入其中。这不值得花时间。

将其余部分放在一起,您可以通过以下类似的方式满足您的要求:

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

#define MAXI 128

int tablefill (int *a, int max);
void tableinsert (int *a, int *n, int max, int num, int val);
void tableswap (int *a, int n, int i, int j);
void tablesort (int *a, int n, size_t sz);
void tablebubblesort (int *a, int n);
void tableprint (int *a, int n);
int compare (const void *a, const void *b);

int main (void) {

    int arr[MAXI] = {0};
    int n = 0;

    printf ("enter array values ([ctrl+d] to end)\n");
    n = tablefill (arr, MAXI);
    tableprint (arr, n);

    printf ("\ninsert '5' as the '2nd' element of array\n");
    tableinsert (arr, &n, MAXI, 2, 5);
    tableprint (arr, n);

    printf ("\nswap indexes '1' and '3'\n");
    tableswap (arr, n, 1, 3);
    tableprint (arr, n);

    printf ("\nsorted array\n");
#ifdef WQSORT
    tablesort (arr, n, sizeof *arr);  /* gcc -DWQSORT to use tablesort */
#else
    tablebubblesort (arr, n);
#endif
    tableprint (arr, n);

    return 0;
}

/** read values from stdin into array up to 'max' values. */
int tablefill (int *a, int max)
{
    int idx = 0, tmp;
    while (idx + 1 < max && scanf ("%d", &tmp) == 1)
        a[idx++] = tmp;

    return idx;
}

/** insert 'val' as the 'num' element in 'a' ('num - 1' index),
*  update 'n' to current number of elements.
*/
void tableinsert (int *a, int *n, int max, int num, int val)
{
    if (num >= max || *n + 1 == max) return;
    if (num >= *n) { a[num] = val; (*n)++; return; }
    int i;

    for (i = *n; i >= num; i--)
        a[i] = a[i-1];
    a[i] = val;

    (*n)++;
}

/** swap values at array indexes 'i' and 'j'. */
void tableswap (int *a, int n, int i, int j)
{
    if (i >= n || j >= n) return;
    int tmp = a[i];
    a[i] = a[j];
    a[j] = tmp;
}

/** qsort the array */
void tablesort (int *a, int n, size_t sz)
{
    qsort (a, n, sz, compare);
}

/** sort array using slow old bubblesort */
void tablebubblesort (int *a, int n)
{
    int i, j;

    for (i = 0; i < n - 1; i++) {
        for (j = 0; j < n - i - 1; j++) {
            if (a[j] > a[j + 1])            /* For decreasing order use < */
                tableswap (a, n, j, j+1);
        }
    }
}

/** print all elements in array. */
void tableprint (int *a, int n)
{
    if (!a) return;
    int i;
    for (i = 0; i < n; i++)
        printf (" a[%2d] : %d\n", i, a[i]);
}

/** qsort compare function */
int compare (const void *a, const void *b)
{
    return (*(int *)a - *(int *)b);
}

代码包含排序的bubblesortqsort版本。您只需传递define -DWQSORT以使用qsort代码进行编译,或者在没有bubblesort的情况下进行编译。 e.g。

编译两个版本

$ gcc -Wall -Wextra -Ofast -o bin/array_fill array_fill.c

$ gcc -Wall -Wextra -Ofast -DWQSORT -o bin/array_fill_qsort array_fill.c

示例使用/输出

$ echo "1 4 2 3" | ./bin/array_fill
enter array values ([ctrl+d] to end)
 a[ 0] : 1
 a[ 1] : 4
 a[ 2] : 2
 a[ 3] : 3

insert '5' as the '2nd' element of array
 a[ 0] : 1
 a[ 1] : 5
 a[ 2] : 4
 a[ 3] : 2
 a[ 4] : 3

swap indexes '1' and '3'
 a[ 0] : 1
 a[ 1] : 2
 a[ 2] : 4
 a[ 3] : 5
 a[ 4] : 3

sorted array
 a[ 0] : 1
 a[ 1] : 2
 a[ 2] : 3
 a[ 3] : 4
 a[ 4] : 5

$ echo "1 4 2 3" | ./bin/array_fill_qsort
<same outoput>

查看所有代码,如果您有任何疑问,请与我们联系。这是基本的肉和土豆 C,您需要确保理解每一行以及每行中的每个字符。慢慢来。