关于数组:在c程序中搜索和排序?

search and sorting in c program?

我正在编写一个程序,它从客户端接收一些数字,然后用气泡排序函数和从客户端接收一个数字的另一个函数对它们进行排序,然后用二进制搜索函数在另一个数字之间搜索。请告诉我这个程序的问题是什么?S?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>

int bobsort (int);
int searchi (int);

void main ()
{

    int num, i;
    printf ("Enter Count Number
"
);
    scanf ("%d", &num);
    int array[num];
    for (i = 1; i <= num; i++) {
        printf ("Enter Number %d
"
, i);
        scanf ("%d", &array[i - 1]);
    }

    bobsort (num);
    searchi (num);

    getch ();

//return 0;
}

//**** function bobsort
void bobsort (int n)
{
    int c, d, swap;
    for (c = 0; c < (n - 1); c++) {
        for (d = 0; d < n - c - 1; d++) {
            if (array[d] > array[d + 1]) {      /* For decreasing order use < */
                swap = array[d];
                array[d] = array[d + 1];
                array[d + 1] = swap;
            }
        }
    }

    printf ("Sorted list in ascending order:
"
);

    for (c = 0; c < n; c++)
        printf ("%d
"
, array[c]);

    // return 0;
}

//**** function search
int searchi ()
{
    int c, first, last, middle, n, search;

    printf ("Enter value to find
"
);
    scanf ("%d", &search);

    first = 0;
    last = n - 1;
    middle = (first + last) / 2;

    while (first <= last) {
        if (array[middle] < search)
            first = middle + 1;
        else if (array[middle] == search) {
            printf ("%d found at location %d.
"
, search, middle + 1);
            break;
        } else
            last = middle - 1;

        middle = (first + last) / 2;
    }
    if (first > last)
        printf ("Not found! %d is not present in the list.
"
, search);

    return 0;
}


这需要一段时间。让我们从基础开始,首先,mainint类型的(不管某些编译器允许您使用什么),它返回一个大于或等于0的整数值(没有返回到shell的负值):

1
2
3
int main (void)
 ...
return 0;

接下来,总是初始化变量。试图读取未初始化的值是未定义的行为(错误)。循环数组元素时,循环从"0"开始(而不是从"1"开始调整元素):

1
2
3
4
    for (i = 0; i < num; i++) {
        printf (" enter array[%d]", i);
        scanf ("%d", &array[i]);
    }

您对函数定义和声明有什么想法?不能将函数原型定义为:

1
int searchi (int);

然后宣布你的职能为:

1
void searchi ();

这是绝对基本的(apples != apples内务管理。如何访问数组元素并知道有多少个元素,除非将数组和元素数作为参数传递给函数。即.:

1
2
void bobsort (int *array, int n)
void searchi (int *array, int n)

如果您希望有其他工作可以做,那么您必须在代码中投入精力并修复简单的事情。

接下来,您的bobsort代码索引错误,必须使用:

1
2
3
4
5
6
7
8
9
10
    for (c = 0; c < n; c++) {
        for (d = 0; d < n - 1; d++) {
            /* For decreasing order use < */
            if (array[d] > array[d + 1]) {
                swap = array[d + 1];
                array[d + 1] = array[d];
                array[d] = swap;
            }
        }
    }

我想不起来我对江户做了什么,除了声明外,一切都差不多了。解决上述所有问题的结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>

void bobsort (int*, int);
void searchi (int*, int);

int main (void)
{
    int num = 0, i = 0;
    int array[num];

    printf ("
 no. of array elements:"
);
    scanf ("%d", &num);

    for (i = 0; i < num; i++) {
        printf (" enter array[%d]", i);
        scanf ("%d", &array[i]);
    }

    bobsort (array, num);
    searchi (array, num);
    // getch ();

    return 0;
}

/* function bobsort */
void bobsort (int *array, int n)
{
    int c, d, swap;
    c = d = swap = 0;

    for (c = 0; c < n; c++) {
        for (d = 0; d < n - 1; d++) {
            /* For decreasing order use < */
            if (array[d] > array[d + 1]) {
                swap = array[d + 1];
                array[d + 1] = array[d];
                array[d] = swap;
            }
        }
    }

    printf ("
Sorted list in ascending order:

"
);

    for (c = 0; c < n; c++)
        printf ("%d
"
, array[c]);
}

/* function search */
void searchi (int *array, int n)
{
    int first, last, middle, search;
    first = last = middle = search = 0;

    printf (" enter value to find:");
    scanf ("%d", &search);

    first = 0;
    last = n - 1;
    middle = (first + last) / 2;

    while (first <= last) {
        if (array[middle] < search)
            first = middle + 1;
        else if (array[middle] == search) {
            printf ("%d found at location %d.
"
, search, middle + 1);
            break;
        } else
            last = middle - 1;

        middle = (first + last) / 2;
    }
    if (first > last)
        printf ("Not found! %d is not present in the list.
"
, search);
}

使用/输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ./bin/array_bsort_srch

 no. of array elements: 5
 enter array[0] 9
 enter array[1] 3
 enter array[2] 5
 enter array[3] 8
 enter array[4] 4

Sorted list in ascending order:

3
4
5
8
9
 enter value to find: 8
8 found at location 4.

如果您在编译时启用了警告,然后阅读编译器告诉您的内容,那么所有这些问题对您来说都应该是非常明显的。生成任何内容时,请至少启用警告:

1
gcc -Wall -Wextra -o progname progname.c

(只需将编译器的exe名称替换为gcc)如果使用某个IDE,则每个IDE都提供一个配置来指定编译器选项,确保启用警告。它们可以帮助您识别代码中可能导致不可靠操作的问题。除非你花时间去修正这些警告,否则你要冒自己的风险。

实际上,多年的开发已经进入编译器,让它识别出问题存在的地方和问题是什么。它甚至提供了错误或警告所在的确切行号。您只需花时间阅读输出并修复错误和警告。如果您不确定警告或错误的含义,只需在搜索引擎中键入它(即"C copy/paste warning or error"),您将获得关于错误、查找内容以及如何修复错误的大量信息。祝你好运。


您有几个编译错误,下面我用注释重写了您的代码,以便它可以编译。实际的功能似乎工作得很好

最重要的变化是将array传递给这两个函数。它作为int*传递,以便函数可以在main的上下文中修改array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>

// Neither one of these need to return a value, both are now void
// Both need to have array passed, added int*
void bobsort(int, int*);
void searchi(int, int*);

int main() {
    int num, i;

    printf("Enter Count Number
"
);
    scanf("%d", &num);

    int array[num];
    for (i = 1; i <= num; i++) {
        printf("Enter Number %d
"
, i);
        scanf("%d", &array[i-1]);
    }

    // Pass array to both functions
    bobsort(num, array);
    searchi(num, array);

    // Don't know what this was supposed to be, commented out
    //getch();

    return 0;
}

// Receives array from main
void bobsort(int num, int* array) {
    int c, d, swap;
    for (c = 0; c < num-1; c++) {
        for (d = 0; d < num-c-1; d++) {
            if (array[d] > array[d+1]) {
                swap = array[d];
                array[d] = array[d+1];
                array[d+1] = swap;
            }
        }
    }

    printf("Sorted list in ascending order:
"
);
    for (c = 0 ; c < num; c++)
        printf("%d
"
, array[c]);
}

// Receives array from main
void searchi(int num, int* array) {
    int c, first, last, middle, search;

    printf("Enter value to find
"
);
    scanf("%d", &search);

    first = 0;
    last = num-1;
    middle = (first+last)/2;

    while (first <= last) {
        if (array[middle] < search)
            first = middle+1;
        else if (array[middle] == search) {
            printf("%d found at location %d
"
, search, middle+1);
            break;
        }
        else
            last = middle-1;

        middle = (first+last)/2;
    }
    if (first > last)
        printf("Not found! %d is not present in the list
"
, search);
}


问题是你的气泡排序函数。您需要用while循环替换外部for循环,当您进行交换时,需要设置一个标志来指示交换发生了。此外,您的代码在主函数内部定义数组,而不是将其定义为全局变量,因此您还需要向数组传递指针,因为数组不在bobsort所在的范围内(换句话说,bobsort看不到数组)。更正代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//*********************************function bobsort
void bobsort(int n, int *array)
{
 int   d, swap, flag;  

  flag = 1;
  while (flag != 0)
  {
    flag = 0;
    for (d = 0; d < n - 1; d++)
    {
      if (array[d] > array[d+1]) /* For decreasing order use < */
      {
        swap       = array[d];
        array[d]   = array[d+1];
        array[d+1] = swap;
        flag = 1;
      }
    }
  }

在主函数中,将调用更改为:

1
bobsort(num, &array[0]);

这样,排序函数就可以访问数组并知道它的大小。这样做,当没有更多的交换并且列表被排序时,就退出排序例程。附带说明的是,就排序算法而言,气泡排序非常慢且效率很低。梳子分类是一个更好的程序,而且稍微复杂一些。下面显示了一个梳状排序程序的伪代码示例(来自维基百科):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function combsort(array input)
    gap := input.size //initialize gap size
    shrink := 1.3 //set the gap shrink factor

    loop until gap = 1 and swapped = false
        //update the gap value for a next comb. Below is an example
        gap := int(gap / shrink)
        if gap < 1
          //minimum gap is 1
          gap := 1
        end if

        i := 0
        swapped := false //see bubblesort for an explanation

        //a single"comb" over the input list
        loop until i + gap > input.size //see shellsort for similar idea
            if input[i] > input[i+gap]
                swap(input[i], input[i+gap])
                swapped := true // Flag a swap has occurred, so the
                                // list is not guaranteed sorted
            end if
            i := i + 1
        end loop

    end loop
end function

我个人用这个程序进行排序,效果很好。至于你的二进制搜索函数,我看不出有什么明显的问题。

编辑:我刚刚看到您的搜索函数也在参数列表中缺少数组。就像我使用冒泡排序函数一样添加它,并使用&;运算符以相同的方式调用它。您还使用了未初始化的n。您还需要将数组的大小传递给搜索函数。我重写了功能,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//**** function search
int searchi (int n, int *array)
{
    int c, first, last, middle, search;

    printf ("Enter value to find
"
);
    scanf ("%d", &search);

    first = 0;
    last = n - 1;
    middle = (first + last) / 2;

    while (first <= last) {
        if (array[middle] < search)
            first = middle + 1;
        else if (array[middle] == search) {
            printf ("%d found at location %d.
"
, search, middle + 1);
            break;
        } else
            last = middle - 1;

        middle = (first + last) / 2;
    }
    if (first > last)
        printf ("Not found! %d is not present in the list.
"
, search);

    return 0;
}

然后用以下代码调用:

1
searchi(num, &array[0]);

这应该能使它正常工作。作为补充说明,当您遇到编译器错误时,请注意它告诉您的内容,并尝试纠正它们。我不知道您使用的是什么编译器,但是clang比gcc更擅长指出错误和解释问题所在。有一次使用gcc时,我犯了一个奇怪的错误,它并不是很具体。3小时后,我发现问题与某个模糊的、范围很广的头文件中的定义冲突,该头文件隐藏在系统中,该系统从5个级别向下包含。