冒泡:
var arr = [29,45,51,68,72,97];
//外层循环,控制趟数,每一次找到一个最大值
for (var i = 0; i < arr.length - 1; i++) {
// 内层循环,控制比较的次数,并且判断两个数的大小
for (var j = 0; j < arr.length - 1 - i; j++) {
// 白话解释:如果前面的数大,放到后面(当然是从小到大的冒泡排序)
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);//[2, 4, 5, 12, 31, 32, 45, 52, 78, 89]
插入:
function loop(arr) {
for (let i = 1; i < arr.length; i++) {
let comp = arr[i]
let j = i - 1
while (arr[j] > comp && j > 0) {
arr[j + 1] = arr[j]
j--
}
arr[j + 1] = comp
}
return arr
}
let test = [1, 9, 8, 6, 7, 6]
let newx = loop(test)
console.log(newx)
选择:
概念:选择排序大致的思路是找到数据结构中的最小值并将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推。
复杂度: O(n^2)
var swap = function (array, index1, index2){
var aux = array[index1];
array[index1] = array[index2];
array[index2] = aux;
}
var selectionSort = function(array) {
var length = array.length, indexMin;// {1}声明一些将在算法内使用的变量
for (var i = 0;i < length -1;i++) {// {2}外循环
indexMin = i;// {3}假设本迭代轮次的第一个值为数组最小值
for (var j = i;j < length;j++) {// {4}从当前i的值开始至数组结束
if (array[indexMin] > array[j]) {// {5}我们比较是否位置j的值比当前最小值小
indexMin = j; // {6};如果是,则改变最小值至新最小值
}
}
if (i !== indexMin) {
swap(array, i, indexMin); // {7}最后,如果该最小值和原最小值不同(行{7}),则交换其值。
}
} // 复杂度是O(n^2)
return array;
}
快排:
原理:从数组中取一个值为基准值,并将剩下的值与之比较,小于基准值的放到左边,大于基准值的放到右边,并再次对左右两边进行快速排序,直至左右两边只剩一个元素。
最坏时间复杂度:O(n^2) 当选择的基准值为最大值或最小值时
平均时间复杂度:O(n*log2n)
function jsQuickSort(array) {
if (array.length <= 1) {
return array;
}
const pivotIndex = Math.floor(array.length / 2);
const pivot = array.splice(pivotIndex, 1)[0]; //从数组中取出我们的"基准"元素
const left = [], right = [];
array.forEach(item => {
if (item < pivot) { //left 存放比 pivot 小的元素
left.push(item);
} else { //right 存放大于或等于 pivot 的元素
right.push(item);
}
});
//至此,我们将数组分成了left和right两个部分
return jsQuickSort(left).concat(pivot, jsQuickSort(right)); //分而治之
}
const arr = [98, 42, 25, 54, 15, 3, 25, 72, 41, 10, 121];
console.log(jsQuickSort(arr)); //输出:[ 3, 10, 15, 25, 25, 41, 42, 54, 72, 98, 121 ]
归并:
function mergeSort(arr) {
const length = arr.length;
if (length === 1) { //递归算法的停止条件,即为判断数组长度是否为1
return arr;
}
const mid = Math.floor(length / 2);
const left = arr.slice(0, mid);
const right = arr.slice(mid, length);
return merge(mergeSort(left), mergeSort(right)); //要将原始数组分割直至只有一个元素时,才开始归并
}
function merge(left, right) {
const result = [];
let il = 0;
let ir = 0;
//left, right本身肯定都是从小到大排好序的
while( il < left.length && ir < right.length) {
if (left[il] < right[ir]) {
result.push(left[il]);
il++;
} else {
result.push(right[ir]);
ir++;
}
}
//不可能同时存在left和right都有剩余项的情况, 要么left要么right有剩余项, 把剩余项加进来即可
while (il < left.length) {
result.push(left[il]);
il++;
}
while(ir < right.length) {
result.push(right[ir]);
ir++;
}
return result;
}
console.log(mergeSort([2,9,1,8,3,]))