冒泡排序
冒泡排序(Bubble Sort)是最易懂的排序算法,但是效率较低,生产环境中很少使用。
它的基本思想:依次比较相邻的两个数,如果不符合排序规则,则调换两个数的位置。这样一遍比较下来,能够保证最大(或最小)的数排在最后一位。然后,再对最后一位以外的数组,重复前面的过程,直至全部排序完成。由于每进行一遍这个过程,在最后一个位置上,正确的数会自己冒出来,就好像“冒泡”一样,这种算法因此得名。
实现:
//冒泡排序
function bubbleSort(arr) {
for(let i = 0; i < arr.length - 1; i++){
let flag = false;
for(let j = 0; j<arr.length- 1-i; j++){
if(arr[j] > arr[j+1]){
[arr[j], arr[j+1]] = [arr[j+1], arr[j]];
flag = true;
}
if(!flag){
break;
}
}
}
return arr;
}
选择排序(Selection Sort)
先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
实现:
function selectSort(arr) { for (let i = 0; i < arr.length - 1; i++) { let minIndex = i, flag = true; for (let j = i + 1; j < arr.length; j++) { if (arr[minIndex] > arr[j]) { minIndex = j; flag = false; } } if (!flag) { [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; } console.log("第" + i + "轮:", arr, minIndex); } return arr;}console.log(selectSort([4, 3, 5, 2, 1]))
插入排序(Insertion Sort)
工作原理:
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
实现1:
function insertionSort(myArray) { var len = myArray.length, // 数组的长度 value, // 当前比较的值 i, // 未排序部分的当前位置 j; // 已排序部分的当前位置 for (i = 0; i < len; i++) { // 储存当前位置的值 value = myArray[i]; /** * 当已排序部分的当前元素大于value, * 就将当前元素向后移一位,再将前一位与value比较 * */ for (j = i - 1; j > -1 && myArray[j] > value; j--) { myArray[j + 1] = myArray[j]; } myArray[j + 1] = value; } return myArray;}console.log(insertSort2([4, 3, 5, 2, 1]))
实现2:
function insertSort(arr) { if (!arr || arr.length == 0) { return; } let sortArr = [arr[0]]; for (let i = 1; i < arr.length; i++) { let replaceIndex = sortArr.length - 1, flag = true; for (let j = sortArr.length - 1; j >= 0; j--) { if (arr[i] < sortArr[j]) { replaceIndex = j; flag = false; } else { break; } } if (!flag) { sortArr.splice(replaceIndex, 0, arr[i]); } else { sortArr.push(arr[i]); } console.log("第" + i + "轮:", sortArr, replaceIndex); } return sortArr;}console.log(insertSort([4, 3, 5, 2, 1]))
归并排序
归并排序是用分治思想,分治模式在每一层递归上有三个步骤:
- 分解(Divide):将n个元素分成个含n/2个元素的子序列。
- 解决(Conquer):用合并排序法对两个子序列递归的排序。
- 合并(Combine):合并两个已排序的子序列已得到排序结果。
基本思想:**将两个已经排序的数组合并**,要比从头开始排序所有元素来得快。因此,可以将数组拆开,分成n个只有一个元素的数组,然后不断地两两合并,直到全部排序完成。
以对数组[6, 5, 3, 1, 8 , 7, 2, 4] 进行从小到大排序为例,步骤如下:
- 将数组分成[6, 5, 3, 1]和[8 , 7, 2, 4]两部分。
- 将[6, 5, 3, 1]分成[6, 5]和[3, 1]两部分。
- 将 [8 , 7, 2, 4]分成[8,7]和[2,4]两部分
- 将[6, 5]分成[6]和[5]两部分,将[3, 1]分成[3]和[1]两部分,将[8, 7]分成[8]和[7]两部分, 将[2, 4]分成[2]和[4]两部分
- 然后将[6]和[5]合并成[5, 6]。然后[3]和[1]合并成[1, 3]。然后[8]和[7]合并成[7, 8]。然后[2]和[4]合并成[2, 4]。
- 将[5, 6]和[1, 3]合并成[1,3,5,6]。将[7, 8]和[2, 4]合并成[2, 4,7,8]。
- 将[1,3,5,6]和[2, 4,7,8]合并成,然后合并成[1,2,3,4,5,6,7,8]。

function merge(left, right){
var result = [],
il = 0,
ir = 0;
while (il < left.length && ir < right.length){
if (left[il] < right[ir]){
result.push(left[il++]);
} else {
result.push(right[ir++]);
}
}
return result.concat(left.slice(il)).concat(right.slice(ir));
}
function mergeSort(arr) { //采用自上而下的递归方法
var len = arr.length;
if(len < 2) {
return arr;
}
var middle = Math.floor(len / 2),
left = arr.slice(0, middle),
right = arr.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
快速排序(Selection Sort)
基本思想:先确定一个“支点”(pivot),将所有小于“支点”的值都放在该点的左侧,大于“支点”的值都放在该点的右侧,然后对左右两侧不断重复这个过程,直到所有排序完成。
具体做法是:
- 确定“支点”(pivot)。虽然数组中任意一个值都能作为“支点”,但通常是取数组的中间值。
- 建立两端的指针。左侧的指针指向数组的第一个元素,右侧的指针指向数组的最后一个元素。
- 左侧指针的当前值与“支点”进行比较,如果小于“支点”则指针向后移动一位,否则指针停在原地。
- 右侧指针的当前值与“支点”进行比较,如果大于“支点”则指针向前移动一位,否则指针停在原地。
- 左侧指针的位置与右侧指针的位置进行比较,如果前者大于等于后者,则本次排序结束;否则,左侧指针的值与右侧指针的值相交换。
- 对左右两侧重复第2至5步。
实现:
function quickSort(arr){
//如果arr.length<=1,则直接返回arr
if(arr.length<=1){return arr}
// arr的元素个数/2,再下去整,将值保存在pivotIndex中
var pivotIndex=Math.floor(arr.length/2);
// 将arr中pivotIndex位置的元素,保存在变量pivot中
var pivot=arr[pivotIndex];
//声明空数组left和right
var left=[];
var right=[];
for(var i=0;i<arr.length;i++){ // 遍历arr中每个元素
if(i !== pivotIndex){ // 如果i !== pivotIndex
if(arr[i]<=pivot){ // 如果当前元素值<pivot
left.push(arr[i]); // 就将当前值压入left
}else{
right.push(arr[i]); // 就将当前值压入right
}
}
}
//递归
return quickSort(left).concat(pivot, quickSort(right)); // 链接多个数组到 left 从小到大
}