бесконечное l oop в реализации сортировки оболочки в JavaScript - PullRequest
1 голос
/ 23 апреля 2020

Я сейчас читаю четвертое издание Algorithms, 4th Edition by Robert Sedgewick, где у автора есть реализация сортировки оболочки. Я пытаюсь понять, почему эта реализация не работает в JavaScript. Хотя я могу console.log отсортированный массив, кажется, что программа никогда не останавливается и становится бесконечной l oop.

 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. Обратите внимание, что первый l oop 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]))

Когда я записываю вывод, я получаю отсортированный массив, но я не знаю, откуда исходит бесконечный l oop. Когда вы запускаете код, это вывод на терминал:

  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, но без удачи. Что я не так понял?

1 Ответ

1 голос
/ 23 апреля 2020

В 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]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...