当前位置: 首页 > 知识库问答 >
问题:

在合并排序C中使用合并时的随机值

陶超
2023-03-14

对于一个小作业,我应该编写一个简单的合并函数,其原型如下所示:

void merge(int a[], int left_low,  int left_high, int right_low, int right_high)

说明书上说,为了简单起见,我们只取单个数组,a[],并且right\u low=left\u high 1。我们还将最终值存储在传入的原始数组中。本质上,对于值为a[]={1,3,10,4,7,8}的数组,它如下所示:

a = {1, 3,     10 ,         4,    7,      8}
     ^         ^            ^             ^ 
  left_low  left_high    right_low     right_high

对于这个作业,我们必须通过几个测试。第一个是两个数组之间的简单合并。第二个是教师自己的merge_sort函数,他调用一些随机排序的数组。这是我对合并()的实现:

void merge(int a[], int left_low,  int left_high,
                    int right_low, int right_high) {
    int temp[right_high + 1]; // temporary array to store the result
    int left_i = left_low, right_i = right_low, temp_i = 0;

    // while the temporary array is not filled
    while(temp_i != right_high + 1)
    {
        if(left_i == left_high + 1)
            temp[temp_i++] = a[right_i++];
        else if(right_i == right_high + 1)
            temp[temp_i++] = a[left_i++];
        else if(a[left_i] < a[right_i])
            temp[temp_i++] = a[left_i++];
        else
            temp[temp_i++] = a[right_i++];
    } // end while
    for(int i = 0; i < temp_i; ++i)
        a[i] = temp[i];
}

当他调用第一个测试时,他只检查两个数组的合并,我的函数起作用,单个数组现在被排序。然而,当他调用merge\u sort函数时,我最终得到了垃圾值。以下是他的测试功能:

template<class T>
void print (std::string label, T a[], int length, bool report_sorted) {
  bool sorted = true;
  std::cout << label;
  for (int i=0; i<length; ++i) {
    std::cout << a[i];
    if (i == length-1)
      std::cout << std::endl;
    else {
      std::cout << ", ";
      if (a[i] > a[i+1])
        sorted = false;
    }
  }
  if (report_sorted)
    std::cout << (sorted ? "    Sorted" : "    Not Sorted") << std::endl;
}

void shuffle(int values[], int length) {
  std::vector<int> v_values;
  for (int i=0; i<length; ++i)
    v_values.push_back(values[i]);
  std::random_shuffle(v_values.begin(),v_values.end());
  for (int i=0; i<length; ++i)
    values[i] = v_values[i];
}

//Recursive Merge Sort
template<class T>
void merge_sort(T a[], int low, int high) {
  if (high - low < 1)               //Base case: 0 or 1 value to sort -> sorted
    return;
  else {
    int mid = (low + high)/2;       //Split in 1/2
    merge_sort(a, low, mid);        //Recursively sort low to mid
    merge_sort(a, mid+1, high);     //Recursively sort mid+1 to high
    merge(a, low,mid, mid+1,high);  //Merge sorted parts of array
  }
}

//Standard Merge Sort (calls a generalized one, with more parameters)
template<class T>
void merge_sort(T a[], int length) {
  merge_sort(a, 0, length-1);
}

std::cout << "\n\nTesting merge in merge sort" << std::endl;
    int test_merge_sort[10] = {1,2,3,4,5,6,7,8,9,10};
    for (int i=0; i<5; i++) {
      shuffle(test_merge_sort, 10);
      print("\n  Array before sort: ", test_merge_sort, 10, false);
      merge_sort(test_merge_sort, 10);
      print("  Array after  sort: ", test_merge_sort, 10, true);
    }

出于某种原因,我的输出结果如下:

 Array before sort: 3, 9, 2, 5, 8, 4, 6, 10, 1, 7
  Array after  sort: -944749486, 4, 5439488, 0, 5443192, 5443196, 1975317641, -944749486, 4, 1995111146
    Not Sorted

  Array before sort: 1995111146, 1975317641, 4, 0, -944749486, 5443192, 5443196, 5439488, 4, -944749486
  Array after  sort: -944749486, 4, 5439488, 0, 5443192, 5443196, 1975317641, -944749486, 4, 1995111146
    Not Sorted

  Array before sort: -944749486, -944749486, 5443196, 4, 5439488, 1995111146, 5443192, 1975317641, 0, 4
  Array after  sort: -944749486, 4, 5439488, 0, 5443192, 5443196, 1975317641, -944749486, 4, 1995111146
    Not Sorted

  Array before sort: 1975317641, -944749486, 4, 4, 5439488, 5443192, 5443196, -944749486, 0, 1995111146
  Array after  sort: -944749486, 4, 5439488, 0, 5443192, 5443196, 1975317641, -944749486, 4, 1995111146
    Not Sorted

  Array before sort: -944749486, 5443192, 5443196, 1975317641, 4, 0, -944749486, 5439488, 1995111146, 4
  Array after  sort: -944749486, 4, 5439488, 0, 5443192, 5443196, 1975317641, -944749486, 4, 1995111146
    Not Sorted

我的合并代码出了什么问题,可能导致这种情况?

共有1个答案

西门磊
2023-03-14

问题是,您计算的temp中的条目数不正确:您的代码认为它是右高1,但正确的公式是右高-左低1。

例如,当调用给您索引10、15、16、26时,您的代码尝试合并27个值,而它应该只合并17个值(即索引10到26,包括10到26)。

当左低为零时,这没有什么区别,所以测试用例运行良好。但是,一旦左低变为非零,例如,当数组的右半部分被排序时,您的代码就会“超调”两个数组,将垃圾值放入tmp中,并覆盖数组a中的值。

此外,最后一个for循环中的赋值也需要位于偏移量left_low处:

for(int i = 0; i < temp_i; ++i)
    a[i+left_low] = temp[i];
 类似资料:
  • 我知道合并排序算法的基本概念,但是当涉及到通过递归实现它时,我很难理解它是如何工作的。据我所知,合并排序函数将我们当前的数组分成两半,并使用递归我们一直这样做,直到每边只剩下一个元素。 如果我们的数组是{38、27、43、3、9、82、10},那么我们的递归将从使用子数组(原始数组的左侧)调用自身开始,并每次重复该过程,将数组减半并存储最左侧,直到达到1个元素: 然后在我们的第二个子例程中,我们继

  • 合并排序通常是对链表排序的首选方式。链表缓慢的随机访问性能使得一些其他算法(如quicksort)表现不佳,而另一些算法(如heapsort)则完全不可能。我一直在努力在链表上做归并排序。它不断返回一个错误。我正在提供我试图执行的代码。请一定要帮我。它不断给出运行时错误。

  • 双向合并排序与递归合并排序有何不同? 假设在合并排序中有5个数字需要排序8,9,1,6,4,我们按如下步骤1进行划分:{8,9,1}{6,4} 步骤2:{8,9}{1}{6}{4} 步骤3:{8}{9}{1}{6}{4} 现在合并 步骤4:{8,9}{1}{4,6} 步骤5:{1,8,9}{4,6} 第六步:{1,4,6,8,9} 但在双向合并排序中,我们将数组分为两个元素(但根据维基百科,在合并

  • 如果在这个程序中,我正在输入一个大小7.so的数组从main()merge_sort(arr,0,6)被传递到相应的函数后,条件被检查,如果(0 但我能够理解合并排序(arr,mid1,high);有人打电话吗?但这个程序运行良好。请解释编译器如何调用merge_sort(arr、mid 1、high)

  • 因此,我理解了使用合并排序对数组中的反转进行计数的一般思路。在合并过程中,您可以递归地计算左子数组和右子数组中的倒数。 这是我为此编写的一些代码。 我很难理解的是为什么在向其附加元素之前必须清除函数中的数组?有没有其他方法可以不清除数组?我问是因为我习惯于用编写合并排序

  • 本文向大家介绍合并排序,包括了合并排序的使用技巧和注意事项,需要的朋友参考一下 合并排序技术基于分而治之。我们将整个数据集分成较小的部分,然后按排序顺序将它们合并成较大的部分。在最坏情况下它也非常有效,因为该算法在最坏情况下的时间复杂度也较低。 合并排序技术的复杂性 时间复杂度: 所有情况下为O(n log n) 空间复杂度:  O(n) 输入输出 算法 合并(数组,左,中,右) 输入- 数据集数