Java 归并排序

2023-12-28

我正在尝试创建一个合并排序方法,但它不断给出错误的排序。我在哪里可以更改以使其真正对数组进行排序?代码的哪一部分必须不同?感谢您的时间。

  public static void mergeSort(int[] array, int left,  int lHigh, int right, int rHigh) {  
        int elements = (rHigh - lHigh +1) ;  
        int[] temp = new int[elements];
        int num = left;
      while ((left <= lHigh) && (right <= rHigh)){
       if (a[left] <= array[right]) {
          temp[num] = array[left];
          left++;
        }
        else {
          temp[num] = array[right];
          right++;
        }
       num++;   
      }
     while (left <= right){
        temp[num] = array[left]; // I'm getting an exception here, and is it because of the num???
        left += 1;
        num += 1;  
     }  
     while (right <= rHigh) {
        temp[num] = array[right];
        right += 1;
        num += 1;  
     }  
     for (int i=0; i < elements; i++){
       array[rHigh] = temp[rHigh];
       rHigh -= 1;   
     }

编辑:现在 mergeSort 并没有真正对数字进行排序,有人可以告诉我它具体在哪里吗?特别是当我打印“测试合并排序”部分时。


首先,我假设这是学术性的而不是实用性的,因为您没有使用内置的排序函数。话虽这么说,这里有一些帮助您朝着正确的方向前进:

通常,可以将合并排序视为两种不同的方法:一种将两个排序列表合并为一个排序列表的 merge() 函数,以及一种递归地将列表分解为单个元素列表的 mergeSort() 函数。由于单个元素列表已经排序,因此您可以将所有列表合并到一个大的排序列表中。

这是一些临时的伪代码:

merge(A, B):
  C = empty list

  While A and B are not empty:
    If the first element of A is smaller than the first element of B:
      Remove first element of A.
      Add it to the end of C.
    Otherwise:
      Remove first element of B.
      Add it to the end of C.

  If A or B still contains elements, add them to the end of C.

mergeSort(A):
  if length of A is 1:
    return A

  Split A into two lists, L and R.

  Q = merge(mergeSort(L), mergeSort(R))

  return Q

也许这会帮助你明确你想去的地方。

如果没有的话,总有归并排序 http://en.wikipedia.org/wiki/Merge_sort在维基百科。

额外的:

为了帮助您,这里有一些代码中内嵌的注释。

  public static void mergeSort(int[] array, int left,  int lHigh, int right, int rHigh) {   
        // what do lHigh and rHigh represent?

        int elements = (rHigh - lHigh +1) ;     
        int[] temp = new int[elements];
        int num = left;

      // what does this while loop do **conceptually**? 
      while ((left <= lHigh) && (right <= rHigh)){
       if (a[left] <= a[right]) {
          // where is 'pos' declared or defined?
          temp[pos] = a[left];
          // where is leftLow declared or defined? Did you mean 'left' instead?
          leftLow ++;
        }
        else {
          temp[num] = a[right];
          right ++;
        }
       num++;   
      }

     // what does this while loop do **conceptually**?
     while (left <= right){
        // At this point, what is the value of 'num'?
        temp[num] = a[left];
        left += 1;
        num += 1;   
     }
     while (right <= rHigh) {
        temp[num] = a[right];
        right += 1;
        num += 1;       
     }
     // Maybe you meant a[i] = temp[i]?
     for (int i=0; i < elements; i++){
       // what happens if rHigh is less than elements at this point? Could
       // rHigh ever become negative? This would be a runtime error if it did
       a[rHigh] = temp[rHigh];
       rHigh -= 1;      
     }

我故意含糊其辞,以便您考虑算法。尝试将您自己的注释插入到代码中。如果你能写出概念上发生的事情,那么你可能不需要 Stack Overflow :)

我的想法是你没有正确实施这一点。这是因为看起来您只接触了数组的元素一次(或接近一次)。这意味着最坏的情况是O(N) http://en.wikipedia.org/wiki/Big_O_notation排序一般至少需要O(N * log N)据我所知,合并排序的更简单版本实际上是O(N^2).

More:

在合并排序的最简单实现中,我希望看到某种递归 http://en.wikipedia.org/wiki/Recursion#Recursion_in_computer_science在 mergeSort() 方法中。这是因为合并排序通常是递归定义的。有多种方法可以使用 for 和 while 循环迭代地完成此操作,但我绝对不推荐将其作为学习工具,除非您递归地获得它。

老实说,我建议采用我的伪代码或您在维基百科文章中找到的伪代码来实现此目的并重新开始您的代码。如果您这样做后仍然无法正常工作,请将其发布在这里,我们将帮助您解决问题。

Cheers!

最后:

  // Precondition: array[left..lHigh] is sorted and array[right...rHigh] is sorted.
  // Postcondition: array[left..rHigh] contains the same elements of the above parts, sorted.
  public static void mergeSort(int[] array, int left,  int lHigh, int right, int rHigh) {   
        // temp[] needs to be as large as the number of elements you're sorting (not half!)
        //int elements = (rHigh - lHigh +1) ;
        int elements = rHigh - left;

        int[] temp = new int[elements];

        // this is your index into the temp array
        int num = left;

        // now you need to create indices into your two lists
        int iL = left;
        int iR = right;

        // Pseudo code... when you code this, make use of iR, iL, and num!
        while( temp is not full ) {
           if( left side is all used up ) {
             copy rest of right side in.
             make sure that at the end of this temp is full so the
               while loop quits.
           }
           else if ( right side is all used up) {
             copy rest of left side in.
             make sure that at the end of this temp is full so the
               while loop quits.
           }
           else if (array[iL] < array[iR]) { ... }
           else if (array[iL] >= array[iR]) { ... }
        }
 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 归并排序 的相关文章

随机推荐

  • Windows 上有类似 autotest-fsevent 的实现吗?

    基本上 它是自动测试的扩展 它侦听来自操作系统的通知 并允许自动测试在仅测试必要的更改时不永久扫描文件更改 它节省了 CPU 和磁盘的使用 Windows 提供了一个名为 FindFirstChangeNotification 的文件更改通
  • 导航控制器上的后退按钮位置

    我目前正在尝试为 iOS 应用程序开发自定义搜索 我已经设法让搜索控制器出现并且搜索栏正确显示 尽管我唯一的问题是我需要后退按钮出现在导航栏的右侧而不是左侧 请参见下文 正如你所看到的 后退按钮位于左侧 但我需要它位于右侧 https i
  • 使用 ssl 和客户端证书上传大文件 (uploadReadAheadSize) 但不希望预读所有数据

    我尝试搜索互联网 堆栈溢出 但找不到任何适合我的相关答案 我有一个 asp net web api2 应用程序 仅使用 ssl 我试图允许大文件上传 最多 36mb 但除非我将 uploadReadAheadSize 更改为预读此大小 否则
  • Pandas:用第二列中出现次数之间的 obs 计数填充一列

    假设我有以下 DataFrame 其中有一个 0 1 条目 具体取决于某个月份内是否发生 未发生某事 Y 0 0 1 1 0 0 0 0 1 1 1 X pd date range start 2010 freq MS periods le
  • 为什么 ErrorCollector 在声明时要求赋值?

    检查许多 XML 字符串时 我经常使用 ErrorCollector 构造 但我仍然不明白它是如何工作的 当我声明 ErrorCollector 时 我必须立即分配它 Rule public ErrorCollector collector
  • 如何判断内存是否对齐?

    我是使用 SSE SSE2 指令优化代码的新手 到目前为止我还没有走得太远 据我所知 常见的 SSE 优化函数如下所示 void sse func const float const ptr int len if ptr is aligne
  • Spring中使用@Valid验证表单不起作用

    我想验证我的表单 但这不起作用 我的实体类 import java io Serializable import java util Set import javax persistence Column import javax pers
  • 在 Dart 编程时如何为 VSCode 中的类型着色并添加样式

    在 Dart 中编程时 我想在 VSCode 中更改声明类型的颜色 并可能添加粗体 斜体和其他样式 这可能吗 我认为这将有助于可读性 例如 我希望 Widget BuildContext 和 Loading Container 采用不同的颜
  • 大 O 包含两个相乘的变量

    如果我采用该功能 def nested multiplier a b returns a b count 0 for i in range a for j in range b count 1 return count 这里相当清楚的是 就
  • 直接继承 Trait 失败,但代理有效

    为什么添加代理特征有效而直接继承失败 我在 github 上创建了一个可运行的项目 https github com leftofnull so inheritance 如果您克隆存储库并运行sbt console其次是com stacko
  • Docker 构建陷入 npm run 构建步骤

    我试图创建一个 docker 映像 但它卡在 npm run build 步骤中 我可以看到构建成功完成的消息 但它没有继续进行下一步 在 docker 文件下面 我使用节点 16 13 1 作为基础图像 RUN mkdir p usr s
  • Python3 从同级目录导入模块

    对于 python 3 10 项目中的新结构 我必须将不同的模块彼此分开 并将它们移动到同一层的不同文件夹中 文件夹结构看起来有点类似于 Root main py init py folder1 init py a py folder2 i
  • WPF自定义DatagridColumn绑定问题

    我试图为数据网格定义一个新的列模板 我可以在我的应用程序中重复使用它 但是当我尝试使用它时 我得到 System Windows Data 错误 2 找不到管理 FrameworkElement 或 FrameworkContentElem
  • 在外部 JavaScript 中使用 django 模板标签

    我在 html 页面中包含了一个 js 文件 例如 application js 但我无法在该 js 文件中使用 django 模板标签 有什么方法可以直接在外部 js 文件中使用 django 模板标签吗 前提是你会像模板一样解析 JS
  • JS setTimeout() 替代方案

    就像我解释的那样here http blog mlefree com 2016 02 settimeout alternative as happy new html 我不能再使用 window setTimeout 和任何窗口经典函数 如
  • 使用使用 Vue-CLI 创建的应用程序提供 404 页面

    我正在使用 Vue CLI 创建 Vue 应用程序 我不喜欢的一种行为是任何不存在的 URL 例如 localhost 8080 nonexistent file html 得到服务 代码为 200 就好像它是根一样 localhost 8
  • 更改 git merge 的相似性索引阈值并涉及重命名(例如 diff 上的 -M[n] --find-renames[=n] )

    我们有一些用于重命名检测启发式的配置选项diff log show and merge diff renameLimit执行复制 重命名检测时要考虑的文件数量 相当于 git diff 选项 l 差异重命名告诉 git 检测重命名 如果设置
  • 如何减少RadioButton绑定代码?

    我正在跟进这个答案关于如何将枚举 在我的例子中是整数 数据绑定到RadioButtons https stackoverflow com a 2908885 171121 但是如果我有几个 TabItems 每个 TabItems 都有 1
  • 如何在代码后面设置DataGrid行的背景颜色?

    我创建一个DataGrid我的代码后面的对象并设置内容obj ItemsSource 现在我想在后面的代码中设置特定行的背景颜色 我怎样才能实现这个目标 Update 我创建了DataGrid后面代码中的对象如下 var dataGrid
  • Java 归并排序

    我正在尝试创建一个合并排序方法 但它不断给出错误的排序 我在哪里可以更改以使其真正对数组进行排序 代码的哪一部分必须不同 感谢您的时间 public static void mergeSort int array int left int