1、冒泡排序
核心思想:数组当前项和后一项进行比较;如果当前项比后一项大,就交换位置(大的在后面,小的在前面)
时间复杂度:最差:O(n^2);最优O(n)
let a = [1, 7, 2, 4, 6, 6, 3, 5]
function bubbleSort(arr) {
for(let i = 0; i < arr.length - 1; i++) {
for(let j = i + 1; j < arr.length; j++) {
let curr = arr[i]
if(curr > arr[j]) {
let temp = arr[j]
arr[j] = curr
arr[i] = temp
}
}
}
return arr
}
console.log(bubbleSort(a))
2、快速排序
分治法:将原本的问题分解为若干个规模更小但解构与原来的问题相似的子问题,递归解决子问题,然后将这些子问题进行合并;
1)选择一个元素做为基准‘
所有小于基准的元素,都移动到基准左边,所有大于基准的元素都移动基准右边,分区操作结束完毕后,基准元素所处的问题就是最终排序的位置;
2)对基准左边和右边的两个子集,不断重复第一步和第二步的操作;
时间复杂度:平均O( nlog2(n) );最坏O( n^2);最好O( nlog2(n) )
let a = [1, 7, 2, 4, 6, 6, 3, 5]
function fastSort(arr) {
if(arr.length <= 1) return arr // 必须有
let len = Math.floor(arr.length / 2)
let curr = arr.splice(len, 1)
let left = []; let right = []
for(let i = 0; i < arr.length; i++) {
if(arr[i] < curr) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return fastSort(left).concat(curr, fastSort(right))
}
console.log(fastSort(a))
3、归并排序
采用分治的思想;首先是“分”,讲一个数组反复分为两个小数组,直到每个数组只有一个元素;其次是治,从最小数组开始,两两按大小顺序合并,直到并为原始数组大小。
const merge = (left, right) => {
let temp = []
while(left.length > 0 && right.length > 0) {
if(left[0] <= right[0]) {
temp.push(left.shift())
} else {
temp.push(right.shift())
}
}
return temp.concat(left, right)
}
const arr = [12, 8, 24, 16, 1, 167, 7]
const mergeSort = arr => {
if(arr.length === 1) return arr
let mid = Math.floor(arr.length / 2)
let left = arr.slice(0, mid)
let right = arr.slice(mid)
return merge(mergeSort(left), mergeSort(right))
}
console.log(mergeSort(arr))
4、选择排序
核心思想:选定第一个索引的位置,然后和后面的元素进行比较,如果后面的元素小于第一个元素的索引,就交换位置;经过一轮比较,可以确定第一个位置是最小的;之后,从剩下的元素,选择第二小的元素…如此循环;
时间复杂度: O(n^2) ; 最坏O(n^2) ;最好O(n^2)
let a = [1, 7, 2, 4, 6, 6, 3, 5]
function selectSort(arr) {
let min, temp;
for(let i = 0; i < arr.length - 1; i++) {
min = i
for(let j = i + 1; j < arr.length; j++) {
if(arr[j] < arr[min]) {
min = j
}
}
temp = arr[i]
arr[i] = arr[min]
arr[min] = temp
}
return arr
}
console.log(selectSort(a))
5、插入排序
核心思想:从第一个元素开始,这个元素可以认为已经被排序;取出下一个元素,已经排序的元素,从后面向前遍历;如果排好序的某个元素大于取出来的新元素,就将新元素插入到这个元素之前;重复上一个步骤,直到找到已经排序的元素小于或者等于新元素的位置;将新元素插入到这个位置后,重复以上的步骤;
时间复杂度: O(n^2) 最坏O(n^2) 最好O(n)
let a = [1, 7, 2, 4, 6, 6, 3, 5]
function insertSort(arr) {
const handle = []
handle.push(arr[0])
for(let i = 1; i < arr.length; i++) {
let A = arr[i]
for(let j = handle.length - 1; j >= 0; j--) {
let B = handle[j]
if(A > B) {
handle.splice(j + 1, 0, A)
break
}
if(j == 0) { handle.unshift(A) }
}
}
return handle
}
console.log(insertSort(a))
6、希尔排序
希尔排序的本质是一种插入排序,但是它对数组进行了等间隔的分组处理,在每一组中做插入排序;
希尔排序是按一定的间隔对数组进行分组,然后在每一个分组中做插入排序;随后逐次缩小间隔,在每一分组进行插入排序,直到间隔等于1,做一次插入排序后结束。
第一次排序的时候,每一组较小的元素都移动到了相对靠前的位置;
const arr =[12, 8, 24, 16, 1, 167]
const shellSort = arr => {
let gap = Math.floor(arr.length / 2)
while(gap > 0) {
// 插入排序,实现插入排序
for(let i = 0; i < arr.length; i++) {
// 记录选出的元素,放在temp中
let j = i
temp = arr[i]
while(j > 0 && arr[j - gap] > temp) {
arr[j] = arr[j - gap]
j -= gap
}
arr[j] = temp
}
gap = Math.floor(gap / 2)
}
return arr
}
console.log(shellSort(arr))