简体   繁体   English

在 C 中的合并排序程序中实现冒泡排序时出错

[英]Error in implementing bubble sorting in a merge sort program in C

I am learning data structure and algorithms.我正在学习数据结构和算法。 The program takes a set number of inputs in an array and sorts them out using merge sort.该程序采用数组中的一定数量的输入,并使用归并排序对它们进行排序。 The condition is whenever the size of a sub-array is equal to or smaller than 10, it should sort the elements out using bubble sort and then merge them together.条件是当子数组的大小等于或小于 10 时,它应该使用冒泡排序将元素排序,然后将它们合并在一起。 My problem is with getting the program to bubble sort.我的问题是让程序进行冒泡排序。 So far I have been unable to find out the mistake in my program.到目前为止,我一直无法找出我的程序中的错误。 I am still learning everyday.我还在每天学习。 I would really appreciate it if someone could help me find the error and fix it please.如果有人能帮我找到错误并修复它,我将不胜感激。 Thank you very much and have a g'day.非常感谢你,祝你有个愉快的一天。

Here's the code:这是代码:

#include<stdio.h>
#include<stdlib.h>
#define arrsize 10
void merge_sort(int, int);
void merge_array(int, int, int, int);
int arr_sort[arrsize];
void bubblesort(int a[],int size);
void main()
{
  int a[50],n,i;
   printf("\nEnter %d Elements for Sorting\n", arrsize);
  for (i = 0; i < arrsize; i++)
    scanf("%d", &arr_sort[i]);

  printf("\nYour Data   :");
  for (i = 0; i < arrsize; i++) {
    printf("\t%d", arr_sort[i]);
  }

  merge_sort(0, arrsize - 1);

  printf("\n\nSorted Data :");
  for (i = 0; i < arrsize; i++) {
    printf("\t%d", arr_sort[i]);
  }

}
void bubblesort(int arr_sort[],int size)
{
  int temp,i,j;
  for(i=0;i<size;i++)
  {
   for(j=0;j<size-1;j++)
   {
    if(arr_sort[j]>arr_sort[j+1])
    {
     temp=arr_sort[j];
     arr_sort[j]=arr_sort[j+1];
     arr_sort[j+1]=temp;
    }
  }
 }
}
void merge_sort(int i, int j) {
  int m;
  if (i < j) {
    m = (i + j) / 2;
       if(m<=5)
    {
        for(i=0;i<=m;i++){
            for(j=i+1;j<=m;j++){
        bubblesort(arr_sort[i],m);
        bubblesort(arr_sort[j],m);}}
        merge_array(i,m,m+1,j);
    }
    else
         merge_sort(i, m);
    merge_sort(m + 1, j);
    merge_array(i, m, m + 1, j);
  }
}

void merge_array(int a, int b, int c, int d) {
  int t[50];
  int i = a, j = c, k = 0;

  while (i <= b && j <= d) {
    if (arr_sort[i] < arr_sort[j])
      t[k++] = arr_sort[i++];
    else
      t[k++] = arr_sort[j++];
  }
  while (i <= b)
    t[k++] = arr_sort[i++];

  while (j <= d)
    t[k++] = arr_sort[j++];

  for (i = a, j = 0; i <= d; i++, j++)
    arr_sort[i] = t[j];
}

Among the issues in your code:在您的代码中的问题:

  1. From merge_sort , you should be calling bubble_sort for a given floor magnitude, hard-fixed in your merge_sort , specified globally, or as an argument to your functions.merge_sort ,您应该为给定的楼层大小调用bubble_sort ,在您的merge_sort硬固定,全局指定,或作为函数的参数。 The former of these is easiest to achieve.前者最容易实现。

  2. Your bubble_sort invocation from merge_sort is wrong from inception, as you're passing int values where int* should be present.您从bubble_sort调用的merge_sort从一开始就是错误的,因为您在int*应该存在的地方传递int值。

  3. Your functions should all take the array to sort as an argument, and at least the length as well.你的函数应该以数组排序作为参数,并且至少长度为好。 This makes the functions more robust, and thanks to pointer arithmetic, easier to implement than you may think.这使得函数更加健壮,并且由于指针运算,比您想象的更容易实现。

Fixing this requires major surgery.解决这个问题需要大手术。

Updated merge_array更新了merge_array

First some surgery for the merge_array function.首先对merge_array函数进行一些手术。 This assumes you support variable length arrays (VLAs).这假设您支持可变长度数组 (VLA)。 Notice the function accepts the array base address, the mid point, and the overall length.请注意,该函数接受数组基址、中点和总长度。

void merge_array(int a[], int mid, int len)
{
    // change to int tmp[arrsize], or use dynamic allocation, if your
    // platform doesn't support VLAs
    int tmp[len];

    int i = 0, j = mid, k = 0;
    while (i < mid && j < len)
        tmp[k++] = ((a[i] < a[j]) ? a[i++] : a[j++]);

    while (i < mid)
        tmp[k++] = a[i++];

    for (i = 0; i < k; ++i)
        a[i] = tmp[i];
}

Updated merge_sort更新了merge_sort

Now the merge_sort function as described in the problem analysis.现在merge_sort函数如问题分析中所述。 Like the above, it should take an array base address and a length, but that's all it needs.像上面一样,它应该接受一个数组基地址和一个长度,但这就是它所需要的。 Pointer arithmetic will let us partition on recursed calls.指针算术将让我们对递归调用进行分区。

void merge_sort(int a[], int len)
{
    if (len < 5)
    {
        // bubblesort short partitions (less than length:5)
        bubble_sort(a, len);
    }
    else
    {
        int mid = len / 2;
        merge_sort(a, mid);
        merge_sort(a + mid, len - mid); // note pointer arithmetic here
        merge_array(a, mid, len);
    }
}

Updated bubble_sort更新bubble_sort

This simple bubble sort uses forward swap detection to leave early on already-sorted detection.这个简单的冒泡排序使用前向交换检测提前离开已经排序的检测。 Like the prior functions, we have the base address of some array and a specified length.像前面的函数一样,我们有一些数组的基地址和指定的长度。

void bubble_sort(int a[], int size)
{
    int swapped = 1;
    while (swapped && size-- > 0)
    {
        swapped = 0;
        for (int i = 0; i < size; ++i)
        {
            if (a[i + 1] < a[i])
            {
                int tmp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = tmp;
                swapped = 1;
            }
        }
    }
}

Putting It All Together把它放在一起

Below is the complete program, which includes a print helper to dump an array to the console, and a random-generator to avoid lengthy keyboard input.下面是完整的程序,其中包括将数组转储到控制台的打印助手,以及避免冗长的键盘输入的随机生成器。 The provided main() creates a random-filled array, prints it, sorts it, then prints the result.提供的main()创建一个随机填充的数组,打印它,排序它,然后打印结果。 Obviously the output will vary with each run, but you hopefully get the idea of how the above functions are called.显然,每次运行的输出都会有所不同,但您希望了解上述函数的调用方式。

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

#define arrsize 40

void merge_sort(int a[], int len);
void merge_array(int a[], int mid, int len);
void bubble_sort(int a[], int size);

void merge_array(int a[], int mid, int len)
{
    // change to int tmp[arrsize], or use dynamic allocation, if your
    // platform doesn't support VLAs
    int tmp[len];

    int i = 0, j = mid, k = 0;
    while (i < mid && j < len)
        tmp[k++] = ((a[i] < a[j]) ? a[i++] : a[j++]);

    while (i < mid)
        tmp[k++] = a[i++];

    for (i = 0; i < k; ++i)
        a[i] = tmp[i];
}

void merge_sort(int a[], int len)
{
    if (len < 5)
    {
        // bubblesort short partitions (less than length:5)
        bubble_sort(a, len);
    }
    else
    {
        int mid = len / 2;
        merge_sort(a, mid);
        merge_sort(a + mid, len - mid); // note pointer arithmetic here
        merge_array(a, mid, len);
    }
}

void bubble_sort(int a[], int size)
{
    int swapped = 1;
    while (swapped && size-- > 0)
    {
        swapped = 0;
        for (int i = 0; i < size; ++i)
        {
            if (a[i + 1] < a[i])
            {
                int tmp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = tmp;
                swapped = 1;
            }
        }
    }
}

void print_arr(int const arr[], int len)
{
    while (len-- > 0)
        printf("%d ", *arr++);
    fputc('\n', stdout);
}

int main()
{
    srand((unsigned)time(NULL));

    int arr_sort[arrsize];

    // generate random array
    for (int i = 0; i < arrsize; ++i)
        arr_sort[i] = 1 + rand() % 99;
    print_arr(arr_sort, arrsize);

    // sort the array
    merge_sort(arr_sort, arrsize);
    print_arr(arr_sort, arrsize);
}

Sample Output样本输出

16 81 73 86 87 66 14 93 19 13 62 32 70 56 29 88 20 21 7 27 70 46 72 42 95 83 24 2 5 43 67 79 8 18 82 39 81 56 56 45
2 5 7 8 13 14 16 18 19 20 21 24 27 29 32 39 42 43 45 46 56 56 56 62 66 67 70 70 72 73 79 81 81 82 83 86 87 88 93 95

Hope it helps.希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM