归并排序C实现

发布于 2024-10-06 04:10:26 字数 1599 浏览 8 评论 0原文

我按照归并排序算法在 Xcode 上用 C 语言编写了这段代码。 问题是有时我会收到 EXC_BAD_ACCESS 并且无法管理错误所在! 合并算法应该可以工作(我在合并排序函数之外尝试过并且可以工作!)。感谢您的帮助和耐心!

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DIM 6

void mymerge (int v[], int i1,int i2, int last); //mergesort core: merge two ordinated arrays in one bigger ordinated array
void mymergesort (int v[], int lower, int upper);//mergesort
void printv (int v[],int lower, int upper);

int main () {
    int i;
    srand((unsigned int)time(NULL));
    int v[DIM];
    for (i=0; i<DIM; i++)
        v[i]=rand()%15;
    printv(v, 0, DIM-1);
    getc(stdin);
    mymergesort(v, 0, DIM-1);
    printv(v, 0, DIM-1);
}
void printv (int v[],int lower, int upper){
    int i;
    for (i=lower; i<=upper; i++)
    printf("%d\t",v[i]);
}
void mymergesort (int v[], int lower, int upper){
    int mid=(upper+lower)/2;
    if (upper<lower) {
        mymergesort(v, lower, mid);
        mymergesort(v, mid+1, upper);
        mymerge(v,lower,mid+1,upper);
    }
}
void mymerge (int v[], int i1,int i2, int last){
    int i=i1,j=i2,k=i1,*vout;
    vout=(int*)malloc((last-i1+1)*sizeof(int));
    while (i<i2 && j<=last) {
        if (v[i]<=v[j]) {
            vout[k++]=v[i++];
        }else {
            vout[k++]=v[j++];
        }
    }
    for (;i<i2;i++) vout[k++]=v[i];
    for (;j<=last;j++) vout[k++]=v[j];
    for (k=i1; k<=last; k++) v[k]=vout[k];
free(vout);
}

编辑: 非常感谢!但我认为还有另一个问题,当我尝试对更大的数组(200 个元素)进行排序时,程序不起作用(我收到 malloc 错误:已释放对象的校验和不正确 - 对象可能在释放后被修改)。但如果我从 xCode 调试器运行它,一切正常

i wrote this code in C language on Xcode following the algorithm of mergesort.
The problem is that sometimes i get EXC_BAD_ACCESS and i can't manage where the error is!
The merge algorithm should work (i tried it outside the mergesort function and works!). Thank you for your help and patience!

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DIM 6

void mymerge (int v[], int i1,int i2, int last); //mergesort core: merge two ordinated arrays in one bigger ordinated array
void mymergesort (int v[], int lower, int upper);//mergesort
void printv (int v[],int lower, int upper);

int main () {
    int i;
    srand((unsigned int)time(NULL));
    int v[DIM];
    for (i=0; i<DIM; i++)
        v[i]=rand()%15;
    printv(v, 0, DIM-1);
    getc(stdin);
    mymergesort(v, 0, DIM-1);
    printv(v, 0, DIM-1);
}
void printv (int v[],int lower, int upper){
    int i;
    for (i=lower; i<=upper; i++)
    printf("%d\t",v[i]);
}
void mymergesort (int v[], int lower, int upper){
    int mid=(upper+lower)/2;
    if (upper<lower) {
        mymergesort(v, lower, mid);
        mymergesort(v, mid+1, upper);
        mymerge(v,lower,mid+1,upper);
    }
}
void mymerge (int v[], int i1,int i2, int last){
    int i=i1,j=i2,k=i1,*vout;
    vout=(int*)malloc((last-i1+1)*sizeof(int));
    while (i<i2 && j<=last) {
        if (v[i]<=v[j]) {
            vout[k++]=v[i++];
        }else {
            vout[k++]=v[j++];
        }
    }
    for (;i<i2;i++) vout[k++]=v[i];
    for (;j<=last;j++) vout[k++]=v[j];
    for (k=i1; k<=last; k++) v[k]=vout[k];
free(vout);
}

EDIT:
thank you very much! but i think think there is another problem, when I try to sort a bigger array (200 elements), the program doesn't work (i get a malloc error: incorrect checksum for freed object - object was probably modified after being freed). But if I run it from the xCode debugger everything works fine

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心房的律动 2024-10-13 04:10:26

这个:vout=(int*)malloc((last-i1)*sizeof(int));是错误的。

首先,您想要的元素数量是 last-i1+1,而不是 last-i1 - 经典的 off-by-1。这种错误是 C 代码中的约定是使下限包含在内而上限不包含的原因之一 - 需要减少 +1-1 ,搞砸的机会更少。

更严重的错误是您从 i1 开始索引 vout。如果您这样做,则需要为 vout 分配 last+1 元素,并且您永远不会使用第一个 i1 (索引 0 . .i1-1)。

修复:首先,分配 last-i1+1 元素。其次,一开始将k初始化为0,而不是i1。第三,将最终副本更改为

for (k=i1; k<=last; k++) v[k] = vout[k-i1];

This: vout=(int*)malloc((last-i1)*sizeof(int)); is wrong.

First, the number of elements you want is last-i1+1, not last-i1 - classic off-by-1. This kind of error is one of the reasons why the convention in C code is to make lower bounds inclusive and upper bounds exclusive - less +1 and -1 you need to do, less opportunity to screw up.

The more serious error is that you index vout starting from i1. If you do it this way, you need to allocate last+1 element for vout, and you never use the first i1 (index 0 .. i1-1).

Fix: First, allocate last-i1+1 elements. Second, initialize k to 0 at the beginning, not i1. Third, change the final copy to be

for (k=i1; k<=last; k++) v[k] = vout[k-i1];
涫野音 2024-10-13 04:10:26

你有两个问题。首先,您对中点的计算不正确 - 您使用 (upper - lower)/ 2,但这不能保证位于 lowerupper 之间。您真正想要的是 lower + (upper - lower) / 2。如果要排序的区间中只有 1 个数字,也无需执行任何操作 - 因此 mymergesort() 函数应如下所示:

void mymergesort (int v[], int lower, int upper)
{
    if (upper > lower) {
        int mid = lower + (upper - lower)/2;

        mymergesort(v, lower, mid);
        mymergesort(v, mid+1, upper);
        mymerge(v,lower,mid+1,upper);
    }
}

第二个问题是 mymerge( ) 函数已经由 Fabian Giesen 指出。

You have two problems. The first is that your calculation of the midpoint is incorrect - you use (upper - lower)/ 2, but this is not guaranteed to lie between lower and upper. What you actually want is lower + (upper - lower) / 2. It's also not necessary to do any work if there's only 1 number in the interval to be sorted - so the mymergesort() function should look like:

void mymergesort (int v[], int lower, int upper)
{
    if (upper > lower) {
        int mid = lower + (upper - lower)/2;

        mymergesort(v, lower, mid);
        mymergesort(v, mid+1, upper);
        mymerge(v,lower,mid+1,upper);
    }
}

The second problem is the one in the mymerge() function already pointed out by Fabian Giesen.

谁对谁错谁最难过 2024-10-13 04:10:26
#include<stdio.h>
#include<stdlib.h>

void merge(int *a, int n1, int *b, int n2, int *arr)
{
  int i=0, j=0, n=0;
  while(i<n1 && j<n2)
  {
    if (a[i] < b[j])
    {
      arr[n++] = a[i];
      i++;
    }
    else
    {
      arr[n++] = b[j];
      j++;
    }
  }
  while( i < n1)
    arr[n++] = a[i++]; 
  while( j < n2)
    arr[n++] = b[j++];
}
void merge_sort(int *a, int n)
{
  int left[n/2], right[n-n/2],i=0;
  if (n<=1)
    return ;
  while(i<n/2)
    left[i] = a[i++];
  while(i<n)
    right[i - n/2] = a[i++];
  merge_sort( left, n/2 );
  merge_sort( right, n-n/2);
  merge(left, n/2, right, n-n/2, a);
}  
void main()
{
  int a[] = { 6, 5, 3, 1,9, 8, 7, 2, 4},i;
  merge_sort(a,sizeof(a)/sizeof(a[0]));
  for(i=0;i<9;i++)
    printf("--%d",a[i]);
  printf("\n");
}


-- s.k
#include<stdio.h>
#include<stdlib.h>

void merge(int *a, int n1, int *b, int n2, int *arr)
{
  int i=0, j=0, n=0;
  while(i<n1 && j<n2)
  {
    if (a[i] < b[j])
    {
      arr[n++] = a[i];
      i++;
    }
    else
    {
      arr[n++] = b[j];
      j++;
    }
  }
  while( i < n1)
    arr[n++] = a[i++]; 
  while( j < n2)
    arr[n++] = b[j++];
}
void merge_sort(int *a, int n)
{
  int left[n/2], right[n-n/2],i=0;
  if (n<=1)
    return ;
  while(i<n/2)
    left[i] = a[i++];
  while(i<n)
    right[i - n/2] = a[i++];
  merge_sort( left, n/2 );
  merge_sort( right, n-n/2);
  merge(left, n/2, right, n-n/2, a);
}  
void main()
{
  int a[] = { 6, 5, 3, 1,9, 8, 7, 2, 4},i;
  merge_sort(a,sizeof(a)/sizeof(a[0]));
  for(i=0;i<9;i++)
    printf("--%d",a[i]);
  printf("\n");
}


-- s.k
陌路终见情 2024-10-13 04:10:26
#include<stdio.h>
#include<conio.h>
#define max 20
/*** function  for merging the adjecent subarrays in sorted order ***/
void merge(int A[max],int n,int low,int high, int mid)
{
     int i=low,j=mid+1,k,temp;
     while((i<=j)&&(j<=high))     
     {
        if(A[i]>A[j])          /** if element of the second half is greater then exchg and shift **/
        {
           temp=A[j];
          for(k=j;k>i;k--)    /** shifting the elements **/
           {
             A[k]=A[k-1]; 
           }
           A[i]=temp;
           j++;
        }
        i++;
     }
}
/******* iterative function for merge sort ********/
void merge_sort(int A[max],int n,int low,int high)
{
     int mid;
     if(low<high)                     /** terminating condition  **/
     {
        mid=(high+low)/2;            /** calculating the mid point ***/
        merge_sort(A,n,low,mid);     /*** recursive call for left half of the array ***/
        merge_sort(A,n,mid+1,high);  /*** recursive call for right half of the array ***/
        merge(A,n,low,high,mid);    /** merging the both parts of the array **/
     }
}
/******* begening of the main function **********/
int main()
{
    int A[max],n,i;
    /** reading the inputs fro  users **/
    printf("\n enter the size of the array\n");
    scanf("%d",&n);
    printf("\n enter the array \n");
    for(i=0;i<n;i++)
    {
       scanf("%d",&A[i]);                 
    }
    /*** calling merge sort ***/
    merge_sort(A,n,0,n-1);
    /** printing the sorted array **/
    for(i=0;i<10;i++)
    {
       printf("\n\t%d",A[i]);                 
    }
    getch();
    return 0;
}
#include<stdio.h>
#include<conio.h>
#define max 20
/*** function  for merging the adjecent subarrays in sorted order ***/
void merge(int A[max],int n,int low,int high, int mid)
{
     int i=low,j=mid+1,k,temp;
     while((i<=j)&&(j<=high))     
     {
        if(A[i]>A[j])          /** if element of the second half is greater then exchg and shift **/
        {
           temp=A[j];
          for(k=j;k>i;k--)    /** shifting the elements **/
           {
             A[k]=A[k-1]; 
           }
           A[i]=temp;
           j++;
        }
        i++;
     }
}
/******* iterative function for merge sort ********/
void merge_sort(int A[max],int n,int low,int high)
{
     int mid;
     if(low<high)                     /** terminating condition  **/
     {
        mid=(high+low)/2;            /** calculating the mid point ***/
        merge_sort(A,n,low,mid);     /*** recursive call for left half of the array ***/
        merge_sort(A,n,mid+1,high);  /*** recursive call for right half of the array ***/
        merge(A,n,low,high,mid);    /** merging the both parts of the array **/
     }
}
/******* begening of the main function **********/
int main()
{
    int A[max],n,i;
    /** reading the inputs fro  users **/
    printf("\n enter the size of the array\n");
    scanf("%d",&n);
    printf("\n enter the array \n");
    for(i=0;i<n;i++)
    {
       scanf("%d",&A[i]);                 
    }
    /*** calling merge sort ***/
    merge_sort(A,n,0,n-1);
    /** printing the sorted array **/
    for(i=0;i<10;i++)
    {
       printf("\n\t%d",A[i]);                 
    }
    getch();
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文