我正在尝试创建一个程序,它将按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");
}
答案 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
等而让你的眼睛在你的脑海里滚动。它真的很直接。您的a
和b
指针表示指向数组中各个整数的指针(例如,如果说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);
}
代码包含排序的bubblesort
和qsort
版本。您只需传递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,您需要确保理解每一行以及每行中的每个字符。慢慢来。