代码之家  ›  专栏  ›  技术社区  ›  Steven Aguilar

JavaScript中shell排序的无限循环实现

  •  0
  • Steven Aguilar  · 技术社区  · 6 年前

    我目前正在阅读 Algorithms, 4th Edition by Robert Sedgewick 其中作者实现了shell排序。我试图理解为什么这个实现不能在JavaScript中工作。虽然我能 console.log 排序后的数组,程序似乎从未停止运行,它变成了一个无限循环。

     public class Shell
      {
         public static void sort(Comparable[] a)
         {  // Sort a[] into increasing order.
            int N = a.length;
            int h = 1;
            while (h < N/3) h = 3*h + 1; // 1, 4, 13, 40, 121, 364, 1093, ...
            while (h >= 1)
            {  // h-sort the array.
               for (int i = h; i < N; i++)
               {  // Insert a[i] among a[i-h], a[i-2*h], a[i-3*h]... .
                  for (int j = i; j >= h && less(a[j], a[j-h]); j -= h)
                     exch(a, j, j-h);
               }
               h = h/3; }
             }
         // See page 245 for less(), exch(), isSorted(), and main().
    }
    

    以上是Java中的实现。注意第一个循环 while (h < N/3) h = 3*h + 1; 没有 {} 打开或关闭大括号,是否意味着它会一直持续到最后?

    下面是我在JavaScript中的实现:

    function shellSort(a) {
      let N = a.length;
      let h = 1;
    
      while (h < N/3) {
        h = 3 * h + 1
    
        while (h >= 1) 
        {
          for (let i = h; i < N; i++) 
          {
            for (let j = i; j >= h && a[j] < a[j - h]; j -= h){
            let temp = a[j - h]
              a[j - h] = a[j]
              a[j] = temp
            }
          }
          console.log(a)
          h = h/3
        }
      }
    }
    
    console.log(shellSort([7,11,3,6,2,5,9,8,1,10]))
    

    当我记录输出时,我得到了排序的数组,但我不知道无限循环来自哪里。运行代码时,这是终端的输出:

      7, 8, 9, 10, 11
    ]
    [
      1, 2, 3,  5,  6,
      7, 8, 9, 10, 11
    ]
    [
      1, 2, 3,  5,  6,
      7, 8, 9, 10, 11
    ]
    [
      1, 2, 3,  5,  6,
      7, 8, 9, 10, 11
    ]
    
    

    有什么问题?我尝试添加 Math.floor h/3 但是没有运气。 我做错了什么?

    0 回复  |  直到 6 年前
        1
  •  2
  •   iluxa    6 年前

    在Java中,整数除以整数仍然是整数:

    int x = 5;
    int y = x / 3;
    // prints "1"
    System.out.println(y);
    

    然而,在Javascript中,没有整数,一切都是数字。然后

    let x = 5;
    let y = x / 3;
    // prints "1.6666666666666"
    console.log(y);
    

    您的算法需要 h ,否则很难将其用作数组索引。必须将其显式转换为整数。已修复Javascript实现:

    function shellSort(a) {
      let N = a.length;
      let h = 1;
    
      while (h < N / 3) {
        h = 3 * h + 1;
      }
    
    
      while (h >= 1) {
        for (let i = h; i < N; i++) {
          for (let j = i; j >= h && a[j] < a[j - h]; j -= h) {
            let temp = a[j - h]
            a[j - h] = a[j]
            a[j] = temp
          }
        }
        // parseInt here is key
        h = parseInt(h / 3)
      }
    
    }
    console.log(shellSort([7, 11, 3, 6, 2, 5, 9, 8, 1, 10]))