JavaScript中的简单排序算法

    技术2022-07-12  67

    交换助手方法 所有这些算法都涉及交换数组中的元素。为了更好地理解算法的工作原理,我们将抽象出一个称为“交换”的可重用函数。“交换”接收一个数组,并交换该数组的两个索引。这是JS和Ruby中的实现:

    function swap (arr, index1, index2){ let temp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = temp; }

    冒泡排序 这些简单的排序算法中的每一个都从定义要排序的部分开始,然后从该排序的部分向外移动。冒泡排序是从找到数组中的最大值并将其移到最后一个元素(已排序的部分)开始的。然后重复执行,直到排序的部分封装了整个数组。 在上方,我们看到了冒泡排序的名称-通过不断比较两个元素并将它们交换来将最高元素冒到顶部。当数字在上面的GIF中变为橙色时,将被视为“已排序”,并且排序从头开始。然后,它将继续该过程,直到对整个数组进行排序为止。 在下面的实现中,我将跟踪两个变量-currentIndex(排序比较的对象)和endIndex(已排序的部分)。

    function bubbleSort(arr){ //在数组的最后一个索引处开始endIndex let endIndex = arr.length - 1; //运行循环,直到endIndex(排序部分)为0(完整数组) while(endIndex > 0){ // 如果已经排好序,则计算掉掉的次数来缩短循环 let swaps = 0; //每次对新元素进行排序时,将currentIndex重置为数组的开头 let currentIndex = 0; // 循环数组,比较每对元素,直到比较元素到达数组的排序部分 while(currentIndex < endIndex){ // 取消这一行的注释,以查看操作中的比较 // console.log(arr, arr[currentIndex], arr[currentIndex + 1]) // 如果当前元素大于它前面的元素 if(arr[currentIndex] > arr[currentIndex + 1]){ //使用助手函数交换这两个元素 swap(arr, currentIndex, currentIndex + 1); // swaps计数器添加1 swaps++; } //增加currentIndex以继续遍历数组 currentIndex++; } //如果没有交换,则停止循环,因为数组必须已经排序 if(swaps === 0) break; // 减去endIndex号以考虑添加到数组中的新元素 endIndex--; } return arr; }

    选择排序 选择排序基本上与冒泡排序相反。排序不是查找最大的元素并将其冒泡到顶部,而是查找数组中的最小元素并将其移动到数组的开头- 新的sorted section。然后重复执行,直到排序的部分包含整个数组。 选择排序之所以得到它的名称,是因为它遍历数组并选择最低的元素,只有在完成遍历整个数组后才交换它。 在下面的实现中,我这次将跟踪3个变量-最小的元素,要与之比较的当前元素以及已排序部分的开头。

    function selectionSort(arr){ let smallestIndex = 0; let currentIndex = 1; let beginningIndex = 0; //循环,直到排序的部分成为完整的数组 while(beginningIndex < arr.length){ //循环数组,直到currentIndex到达最后一个元素 while(currentIndex < arr.length){ //通过将最小索引与当前索引进行比较来跟踪最小索引 if(arr[smallestIndex] > arr[currentIndex]){ smallestIndex = currentIndex; } //添加到当前索引以遍历数组 currentIndex++; } // 遍历数组一次后,如果最小的数字不在已排序的部分,则交换两者 if(smallestIndex !== beginningIndex){ swap(arr, smallestIndex, beginningIndex) } // 添加到开始索引,以合并新的已排序部分 beginningIndex++; // 在已排序部分上方的1处开始当前索引 currentIndex = beginningIndex + 1; // 将最小索引重置为beginningIndex smallestIndex = beginningIndex; } return arr; }

    插入排序 最后,我们到达插入排序。插入排序与我们前面讨论的前两种排序略有不同,因为它不会首先找到最高或最低的数字-它将数组中的第一个数字视为已排序,然后将数字插入到排序中。 在上面的GIF中,我们发现交换在这种情况下有点不同-我们正在交换元素的下一个索引,以便为我们要比较的当前值腾出空间-以便找到正确的位置来插入它。 在实现中,我们要跟踪三个变量-我们正在排序的部分的beginIndex,我们要检查的currentIndex和我们要比较的currentVal。

    function insertionSort(arr){ let beginningIndex = 0; let currentIndex = 1; //而未排序部分的开始并不从数组的末尾开始 while(currentIndex < arr.length){ //而currentIndex没有到达已排序部分或数组的末尾(索引值为-1) while(currentIndex > 0){ //获取currentValue(要排序的值) currentVal = arr[currentIndex]; //如果它小于最后一个值,则交换两个值,否则退出循环 if(currentVal <= arr[currentIndex - 1]){ swap(arr, currentIndex, currentIndex - 1); currentIndex--; } else{ break; } } //添加1到beginningIndex,以说明新排序的节 beginningIndex++; //开始后从索引开始排序 currentIndex = beginningIndex + 1; } return arr; }
    Processed: 0.016, SQL: 9