【问题标题】:search and sorting in c program?在c程序中搜索和排序?
【发布时间】:2015-08-13 18:21:54
【问题描述】:

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

#include <stdio.h>

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

void main ()
{

    int num, i;
    printf ("Enter Count Number \n");
    scanf ("%d", &num);
    int array[num];
    for (i = 1; i <= num; i++) {
        printf ("Enter Number %d \n", 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:\n");

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

    // return 0;
}

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

    printf ("Enter value to find\n");
    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.\n", 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.\n", search);

    return 0;
}

【问题讨论】:

  • 欢迎来到 StackOverflow。请拨打tour。特别是,您需要更详细地描述您的问题。例如,样本输入、预期输出和实际输出。描述您如何尝试自己调试以及从调试中收集了哪些数据也是一种很好的形式。最后,问一个具体的问题,而不仅仅是一个笼统的“它不起作用,有什么问题?”。

标签: c arrays sorting search bubble-sort


【解决方案1】:

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

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

#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\n");
    scanf("%d", &num);

    int array[num];
    for (i = 1; i <= num; i++) {
        printf("Enter Number %d\n", 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:\n");
    for (c = 0 ; c < num; c++)
        printf("%d\n", array[c]);
}

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

    printf("Enter value to find\n");
    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\n", 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\n", search);
}

【讨论】:

    【解决方案2】:

    问题在于您的冒泡排序功能。您需要用 while 循环替换外部 for 循环,并且在进行交换时,您需要设置一个标志以指示交换发生。此外,您的代码在 main 函数内部定义数组,而不是作为全局变量,因此您还需要将指针传递给数组,因为数组超出了 bobsort 所在的范围(换句话说,bobsort 可以见数组)。更正代码如下:

    //*********************************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;
          }
        }
      }
    

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

    bobsort(num, &array[0]);
    

    这样,排序函数可以访问数组并知道它的大小。这样做,当没有更多交换并且列表已排序时,您将退出排序例程。作为旁注,就排序算法而言,冒泡排序非常缓慢且效率低下。梳状排序是一个更好的例程,并且稍微复杂一些。梳排序例程的伪代码示例如下所示 (from wikipedia):

    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 未初始化。您还需要将数组的大小传递给搜索函数。我重写了如下所示的函数:

    //**** function search
    int searchi (int n, int *array)
    {
        int c, first, last, middle, search;
    
        printf ("Enter value to find\n");
        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.\n", 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.\n", search);
    
        return 0;
    }
    

    然后你用下面的代码调用:

    searchi(num, &array[0]);
    

    这应该使它正常工作。附带说明一下,当您遇到编译器错误时,请注意它告诉您的内容并尝试纠正它们。我不知道您使用的是什么编译器,但 clang 比 gcc 更擅长指出错误并解释问题所在。有一次使用 gcc,我遇到了一些奇怪的错误,但并没有具体说明。 3 小时后,我发现问题是与某个模糊的、遥远的头文件中的定义冲突,该头文件被埋在从 5 层以下被包含的系统中。

    【讨论】:

      【解决方案3】:

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

      int main (void)
       ...
      return 0;
      

      接下来,始终初始化您的变量。尝试从未初始化的值中读取是未定义的行为(不好)。循环遍历数组元素时,循环从 '0' 开始(不是 '1' 调整元素):

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

      您对函数定义和声明有何看法?您不能将函数原型定义为:

      int searchi (int);
      

      然后将你的函数声明为:

      void searchi ();
      

      这是绝对基本的 (apples != apples) 家政服务。除非您将数组元素数量作为参数传递给您的函数,否则您将如何访问数组元素并知道有多少元素。即:

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

      如果您希望其他任何东西都能正常工作,您必须努力编写代码并修复简单的问题。

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

          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;
                  }
              }
          }
      

      我不记得我对searchi 做了什么,除了声明之外,它相当接近。修复上述所有问题会产生如下结果:

      #include <stdio.h>
      
      void bobsort (int*, int);
      void searchi (int*, int);
      
      int main (void)
      {
          int num = 0, i = 0;
          int array[num];
      
          printf ("\n 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 ("\nSorted list in ascending order:\n\n");
      
          for (c = 0; c < n; c++)
              printf ("%d\n", 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.\n", 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.\n", search);
      }
      

      使用/输出

      $ ./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.
      

      如果您在启用 warnings 的情况下进行编译,然后阅读编译器告诉您的内容,那么所有这些问题对您来说应该是非常明显的。当您构建任何东西时,请至少启用警告:

      gcc -Wall -Wextra -o progname progname.c
      

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

      确实,编译器已经进行了多年的开发,以使其能够识别存在问题的位置以及问题所在。它甚至会为您提供发现错误或警告的确切行号。您只需花时间阅读输出并修复错误和警告。如果您不确定警告或错误的含义,只需将其输入搜索引擎(即“C 复制/粘贴警告或错误”)您将获得大量信息,说明什么是错误、什么寻找,以及如何去解决它。祝你好运。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-02
        • 1970-01-01
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 2012-11-27
        • 2015-02-14
        • 2017-01-19
        相关资源
        最近更新 更多