【问题标题】:Recursive merge sort that just takes length of the array as parameter仅将数组长度作为参数的递归合并排序
【发布时间】:2021-09-20 18:45:14
【问题描述】:

我主要了解递归合并排序函数,它接受一个数组、一个低整数和一个高整数。但是,我好奇地尝试编写一个递归合并排序函数,它只接受数组的长度。签名是:void merge_sort(int *array, int n); 这比我想象的要困难得多。

我将在下面发布代码,但我的函数(我认为)只是在每次调用 merge_sort() 时拆分数组的前半部分,基本上不会触及数组的后半部分(再次,我认为)。

我遇到的另一个问题是,当将辅助数组中的所有内容复制回原始数组(使用 for 循环)时,我不确定将什么用作循环的初始条件。下面是我写的递归合并排序,它接受一个低值和一个高值,然后下面是只接受长度的merge_sort。

// Takes in low and high value
void merge_sort(int *array, int lo, int hi)
{
  int mid = lo + (hi - lo) / 2, i = lo, j = mid + 1, k = 0;

  // Auxiliary to store sorted values.
  int *aux = NULL;

  // Base case.
  if (lo >= hi)
    return;

  // Recursive calls.
  merge_sort(array, lo, mid);
  merge_sort(array, mid + 1, hi);

  // Mergy merge.
  aux = malloc(sizeof(int) * (hi - lo + 1));

  if (aux == NULL)
    return;

  while (i <= mid || j <= hi)
  {
    if (i > mid || j <= hi && array[j] < array[i])
      aux[k++] = array[j++];
    else
      aux[k++] = array[i++];
  }

  // Copy everything from the auxiliary array back into the original array.
  for (i = lo; i <=hi; i++)
    array[i] = aux[i - lo];

  free(aux);
}
// Takes in length of the array.
// This is very wrong, but I quickly tried to rewrite
// how I originally tried to tackle this problem
// when I first attempted it for this post.
void merge_sort(int *array, int n)
{
  // Auxiliary to store sorted values.
  int *aux = NULL;

  // Base case. Single element left in the array.
  if (n/2 < 1)
    return;

  // Recursive calls.
  // First call should take in the first half of the array.
  merge_sort(array, n/2);
  // This call should set the base address of the array 
  // to the midpoint of the array.
  merge_sort(array + n/2, n/2);

  // Mergy merge.
  aux = malloc(sizeof(int) * (n + 1));

  if (aux == NULL)
    return;

  while (i <= n/2 || j <= n)
  {
    if (i > n/2 || j <= n && array[j] < array[i])
      aux[k++] = array[j++];
    else
      aux[k++] = array[i++];
  }

  // Not sure how to write this part of the function correctly. 
  // Low is changing with each call to 
  // merge_sort(array, lo, hi), but in this function there is 
  // no lo variable
  //for (i = *lo*; i <= n; i++)
  //  array[i] = aux[i - lo];

  free(aux);
}

编辑:我的目标是在调用合并排序时尝试消除所有错误。

【问题讨论】:

  • 顺便说一句,我喜欢你的这部分代码! if (i &gt;= n/2 || j &lt; n &amp;&amp; array[j] &lt; array[i]) aux[k++] = array[j++]; else aux[k++] = array[i++];
  • @MohamedAkram 谢谢!不久前从我的cs教授那里学到的。

标签: c recursion mergesort


【解决方案1】:

这是我的更改 //@

#include<stdlib.h>
#include<stdio.h>
void printArr(int*arr,int n,char c){
  printf("array of size %d: ",n);
  for (int i = 0; i < n; i++)
  {
    printf("%d ",arr[i]);
  }
  printf("%c",c);
}
void merge_sort(int *array, int n)
{
  // Auxiliary to store sorted values.
  int *aux = NULL;

  // Base case. Single element left in the array.
  if (n/2 < 1)
    return;

  // Recursive calls.
  // First call should take in the first half of the array.
  merge_sort(array, n/2);
  // This call should set the base address of the array 
  // to the midpoint of the array.

  //@ till the end of the array: n - n / 2 (for odd initial size of array)
  merge_sort(array + n/2, n -n/2);

  // Mergy merge.
  //@ n is enough not n+1
  aux = malloc(sizeof(int) * (n));

  if (aux == NULL)
    return;
  
  //@start i from 0, j from n / 2 and k from 0
  int i = 0;
  int j = n/2;
  int k = 0;
  // while (i <= n/2 || j <= n)  
  //@ till k fills the whole array from 0 to n
  while(k<n)
  {
    //@ i condition i>=n/2 not i>n/2 also, j condition j<n not j<=n
    if (i >= n/2 || j < n && array[j] < array[i])
      aux[k++] = array[j++];
    else
      aux[k++] = array[i++];
  }

  //@ now aux has the true values for array, from 0 to n so just loop and copy
  for (i = 0; i < n; i++)
   array[i] = aux[i];

  free(aux);
}
int main(){
  int arr[] = {3,2,6,1,8,9,4,7,5};
  merge_sort(arr,9);
  
  printArr(arr,9,'\n');
  
  return 0;
}

【讨论】:

    猜你喜欢
    • 2019-09-09
    • 2019-07-13
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2019-01-09
    • 2012-07-08
    • 2011-09-30
    • 1970-01-01
    相关资源
    最近更新 更多