【问题标题】:Insertion Sort Algorithm on JavaScriptJavaScript 上的插入排序算法
【发布时间】:2021-03-30 06:04:28
【问题描述】:

我最近开始根据Data Structures and Algorithms with JavaScript from O'Reilly这本书学习算法。

我停在第 12 章 - 排序算法。

我无法理解插入排序的工作原理。

这是我正在使用的代码:pasteBin - Insertion Sort

下面是让我困惑的部分:

function insertionSort() {
    var temp, inner;
    for (var outer = 1; outer <= this.dataStore.length - 1; ++outer) {
        temp = this.dataStore[outer];
        inner = outer;
        while (inner > 0 && (this.dataStore[inner-1] >= temp)) {
            this.dataStore[inner] = this.dataStore[inner-1];
            --inner;
        }
        this.dataStore[inner] = temp;
    }
    console.log(this.toString());
}

任何人都可以帮助和评论这段代码吗?

【问题讨论】:

  • 您对哪一部分感到困惑?
  • 尝试使用其他插座来理解。也许一个更直观的例子会有所帮助。我发现这些视频有助于理解数据结构和算法等内容,因为它们往往非常直观。 youtu.be/DFG-XuyPYUQ
  • 另外一个有用的网站具有出色的交互式可视化cs.usfca.edu/~galles/visualization/Algorithms.html
  • @TylerDavis 嗨。我阅读了插入排序算法的操作原理。我的问题是我看不懂代码。什么部分负责什么。但是例如,当我学习关于二叉树的章节时,我没有类似的理解问题。
  • @Mikhail,我在答案中添加了一个 jsfiddle sn-p。打开浏览器的控制台并运行代码,可能对你有帮助。

标签: javascript algorithm


【解决方案1】:

这是一种排序算法,从数组的开头开始,一直到结尾。对于每个索引处的项目,它会遍历较早索引处的项目并检查是否应将其放在它们之前。如果是这样,它将用较大的值交换索引,直到它稳定到它应该具有的索引。

这里有一些注释的代码,希望对你有帮助。

function insertionSort() {
    /* Set up local vars */
    var temp, inner;
    /* Start at index 1, execute outer loop once per index from 1 to the last index */
    for (var outer = 1; outer <= this.dataStore.length - 1; ++outer) {
        /* Store the value at the current index */
        temp = this.dataStore[outer];
        /* Set up temporary index to decrement until we find where this value should be */
        inner = outer;
        /* As long as 'inner' is not the first index, and 
        there is an item in our array whose index is less than 
        inner, but whose value is greater than our temp value... */ 
        while (inner > 0 && (this.dataStore[inner-1] >= temp)) {
            /* Swap the value at inner with the larger value */
            this.dataStore[inner] = this.dataStore[inner-1];
            /* Decrement inner to keep moving down the array */
            --inner;
        }
        /* Finish sorting this value */
        this.dataStore[inner] = temp;
    }
    console.log(this.toString());
}

这是一个jsfiddle,其中包含大量控制台打印输出,因此您可以单步执行它并查看每一步会发生什么。

【讨论】:

    【解决方案2】:

    插入排序背后的主要概念是通过比较对元素进行排序。

    在您的情况下,比较发生在 dataStore 数组中,其中包含我们假设的可比较元素,例如数字。

    为了逐个元素进行比较,此插入排序算法从dataStore 数组的开头开始,并将继续运行,直到到达数组的末尾。这是通过for 循环完成的:

    for (var outer = 1; outer <= this.dataStore.length - 1; ++outer)
    

    当算法按顺序遍历每个元素时,它将:

    1. 将我们正在访问的当前元素存储在数组中名为temp 的变量中。
    2. 通过innerouter 变量跟踪我们在数组中的位置,其中:
      • outer 是我们的柜台。
      • inner 是一个标志,用于确定我们是否正在访问数组中的第一个元素。为什么这很重要?因为在第一次尝试时对第一个元素进行比较是没有意义的。
    3. 它将当前元素tempdataStore 数组中的每个元素进行比较。这是通过内部while 循环完成的,如下所示:

      while (inner &gt; 0 &amp;&amp; (this.dataStore[inner-1] &gt;= temp))

    这告诉你,只要dataStore数组中所有之前访问过的元素都大于等于temp,我们的临时变量就用来存储当前元素;我们想交换这些值。

    交换它们将完成以下操作:

    • 假设this.dataStore[inner]之前的所有元素都大于10,则当前访问的元素this.dataStore[inner]等于5。这在逻辑上意味着5需要在数组的开头。在这种情况下,由于 while 循环,我们将继续将 5 一直传递到 this.datastore[0]。从而使 5 成为数组中的第一个元素。

    在这个交换结束时,temp 中的值对应于我们在数组中的当前位置,只是为了提醒你这是哪个位置,它存储了变量outer

    TLDR:我也喜欢贾斯汀鲍威尔的回答,因为它坚持代码,但我认为根据您的理解程度,走一遍会更有用。希望对你有帮助!

    【讨论】:

      【解决方案3】:

      从内部循环开始检查当前元素是否大于前一个,如果是,则退出循环,因为所有内容都已为迭代排序,如果不是,则交换元素,因为当前需要向左​​移动,因为它小于以前的。内部循环确保交换元素,直到您遇到一个排序元素,该元素导致 break 退出循环。

      交换发生后减小外部索引 (i),因为您要向下检查即将到来的元素是否小于前一个,所以不能保持外部索引 (i) 静态。

      最后,memIndex 变量用作重置索引,因为在内部循环结束时,您希望移动到下一个索引。索引 (i) 应始终放在已排序数组的最后一个元素处,以便内部循环可以再次开始比较。

      function insertionSort(arr) {
        let memIndex = 0
        for (let i = 0; i < arr.length; i++) {
          memIndex = i;
          for (let j = i + 1; j >= 0; --j) {
            if (arr[j] >= arr[i]) {
              break;
            }
            if (arr[j] < arr[i]) {
              var temp = arr[i];
              arr[i] = arr[j];
              arr[j] = temp;
              i = i - 1;
            }
          }
          i = memIndex;
        }
        return arr;
      }
      const arr = [5, 1, 6, 2, 4, 9, 9, 3, 1, 1, 1];
      console.log('Unsorted array', arr);
      console.log('Sorted array:', insertionSort(arr));

      【讨论】:

        【解决方案4】:
        const insertionSort = array => {
          const arr = Array.from(array); // avoid side effects
        
          for (let i = 1; i < arr.length; i++) {
            for (let j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
              [arr[j], arr[j - 1]] = [arr[j - 1], arr[j]];
            }
          }
          return arr;
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-03
          • 1970-01-01
          • 1970-01-01
          • 2013-06-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多