冒泡排序:两两比较,遍历一趟会挑出最大的值放在最后。
function bubbleSort(arr) {
var len = arr.length;
for (let i = 0; i < len-1; i++) {
for (let j = 0; j < len-1-i; j++) {
if (arr[j] > arr[j+1]) {
var temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
选择排序:从头至尾扫描序列,每次找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列。
function selectSort(arr) {
var len = arr.length;
var minIndex, tmp;
for(let i = 0; i < len-1; i++) {
minIndex = i;
for(let j = i+1; j < len; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
tmp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = tmp;
}
return arr;
}
插入排序:将数组的第一个数认为是有序数组,从后往前扫描该有序数组,把数组中其余n-1个数,根据数值的大小,插入到有序数组中,直至数组中的所有数有序排列为止。这样的话,n个元素需要进行n-1趟排序!!
function insertionSort(arr) {
var len = arr.length;
var current, preIndex;
for(let i = 1; i < len; i++) {
current = arr[i];
preIndex = i - 1;
while (preIndex >= 0 && arr[preIndex] > current) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex+1] = current;
}
return arr;
}
归并排序: 该算法是采用分治法。将已有序 的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。
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));
}
function merge(left, right) {
var result = [];
while (left.length && right.length) {
if(left[0] <= right[0]) {
result.push(left.shift());
}else {
result.push(right.shift());
}
}
if(left.length) {
result = result.concat(left)
}
if(right.length) {
result = result.concat(right)
}
return result;
}
快速排序: ①先从队尾开始向前扫描且当left < right 时,如果arr[right] > pivot ,则right–,但如果arr[right] < pivot,则将right的值赋值给left,同时要转换数组扫描的方式,即需要从队首开始向队尾进行扫描了 ②同理,当从队首开始向队尾进行扫描时,如果arr[right] < pivot,则left++,但如,即arr[low] = arr[high],同时将数组扫描方式换为由队尾向队首进行扫描. ③重复①和②,直到 left>=right时(其实是left=right),left或right的位置就是该哨兵在数组中的正确索引位置。
function quickSort(arr, left, right) {
if(left < right) {
var index = partition(arr, left, right);
quickSort(arr, 0, index-1);
quickSort(arr, index+1, right);
return arr;
}
}
function partition(arr, left, right) {
var pivot = arr[left];
while(left < right) {
// 这里需要考虑数组中有两个数相等的情况,如果没有考虑的话,会出现死循环。
while (left < right && arr[right] >= pivot) {
right--;
}
arr[left] = arr[right];
while (left < right && arr[left] <= pivot) {
left++;
}
arr[right] = arr[left];
}
arr[left] = pivot;
return left;
}
var arr = [2, 10, 4, 1, 0, 9, 5, 2];
console.log(quickSort(arr, 0, arr.length - 1));
希尔排序:插入排序的一种更高效的实现。
function shellSort(arr) {
var preIndex, val;
var len = arr.length;
var gap = Math.floor(len/2),
val;
for(gap; gap > 0; gap = Math.floor(gap/2)) {
for(let i = gap; i < len; i++) {
val = arr[i];
for(var j = i-gap; j>=0 && arr[j] > val; j-=gap) {
arr[j+gap] = arr[j];
}
arr[j+gap] = val;
}
}
return arr;
}