十种排序算法
1.冒泡
时间复杂度 n*n, 并且大量移动, 最慢,不过稳定
function sort(arr){
let len = arr.length
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - 1 - i; j++) {
// console.log(i + '===' + j);
if(arr[j] > arr[j+1]){
[arr[j], arr[j+1]] = [arr[j+1], arr[j]]
}
}
}
return arr
}
// var arr = [3,3,4,3,5,2,6,8,8,7,1,9,4]
var arr = []
for (let i = 0; i < 100000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort")
sort(arr)
console.timeEnd("sort") // 14505 ms (这个是十万级,百万级卡死了)
2.选择
function sort(arr){
let minIndex;
let len = arr.length
for (let i = 0; i < len; i++) {
minIndex = i
for (let j = i+1; j < len; j++) {
if(arr[minIndex] > arr[j]){
minIndex = j
}
}
if(minIndex != i){
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]
}
}
return arr
}
// var arr = [3,3,4,3,5,2,6,8,8,7,1,9,4]
let arr = []
for (let i = 0; i < 100000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort")
sort(arr)
console.timeEnd("sort") // 2957 ms (这个是十万级,百万级卡死了)
3.插入
function sort(arr){
for (let i = 1; i < arr.length; i++) {
let curValue = arr[i]
let j = i
while(j > 0 && arr[j-1] > curValue){
arr[j] = arr[j-1]
j--
}
arr[j] = curValue
}
return arr
}
// var arr = [3,3,4,3,5,2,6,8,8,7,1,9,4]
let arr = []
for (let i = 0; i < 100000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort")
sort(arr)
console.timeEnd("sort") // 1739 ms (这个是十万级,百万级卡死了)
4.希尔
// 希尔 增量-插入
function sort(arr){
let len = arr.length
let gap = Math.floor(len/2)
while(gap > 0){
for (let i = gap; i < len; i++) {
let curValue = arr[i]
let j = i
while(j > 0 && arr[j-gap] > curValue){
arr[j] = arr[j-gap]
j -= gap
}
arr[j] = curValue
}
gap = Math.floor(gap/2)
}
return arr
}
// var arr = [3,3,4,3,5,2,6,8,8,7,1,9,4]
let arr = []
for (let i = 0; i < 1000000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort")
sort(arr)
console.timeEnd("sort") // 450 ms
5.归并
递归 + 合并有序数组
// 归并
function sort(arr){
if(arr.length < 2){
return arr
}
let mid = Math.floor(arr.length / 2)
let left = arr.slice(0, mid)
let right = arr.slice(mid)
return merge(sort(left), sort(right))
}
function merge(left, right){
let i = 0, j = 0
let result = []
while(i < left.length && j < right.length){
if(left[i] < right[j]){
result.push(left[i++])
} else {
result.push(right[j++])
}
}
return result.concat(left.slice(i)).concat(right.slice(j))
}
// var arr = [3,3,4,3,5,2,6,8,8,7,1,9,4]
let arr = []
for (let i = 0; i < 1000000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort")
sort(arr)
console.timeEnd("sort") // 350 ms
6.快排
- push简单版
// 快排, push简单版,三路快排,中间位置数,左 中 右
function sort(arr){
if(arr.length < 2){
return arr
}
let midIndex = Math.floor(arr.length / 2)
let mid = arr.splice(midIndex, 1)[0]
let left = []
let right = []
for (let i = 0; i < arr.length; i++) {
if(arr[i] < mid) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return sort(left).concat(mid).concat(sort(right))
}
// var arr = [3,3,4,3,5,2,6,8,8,7,1,9,4]
let arr = []
for (let i = 0; i < 1000000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort_push")
sort(arr)
console.timeEnd("sort_push") // 2354 ms
- 快排 move版
// 快排 move版(内存和速度更优先)
function sort(arr, left=0, right=arr.length){
if (left < right) {
let pivotIndex = move(arr, left, right);
sort(arr, left, pivotIndex - 1);
sort(arr, pivotIndex + 1, right);
}
return arr;
}
function move(arr, leftIndex, rightIndex){
let midValue = arr[Math.floor((leftIndex + rightIndex) / 2)]
let i =leftIndex
let j = rightIndex
while (i <= j) {
while (arr[i] < midValue) {
i++
}
while (arr[j] > midValue) {
j--
}
if(i<=j){
[arr[i],arr[j]] = [arr[j], arr[i]]
i++;
j--;
}
}
return i;
}
// var arr = [3,3,4,3,5,2,6,8,8,7,1,9,4]
let arr = []
for (let i = 0; i < 1000000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort_move")
sort(arr)
console.timeEnd("sort_move") // 115 ms
7.堆排序
完全二叉树,优先队列,数组存储,
大堆,父节点大于子节点,
8.桶排序
function sort(arr, size=1){
let max = arr[0]
let min = arr[0]
for (let i = 0; i < arr.length; i++) {
max = Math.max(arr[i], max)
min = Math.min(arr[i], min)
}
let tmp = new Array(max - min + 1).fill(0).map(() => [])
for (let i = 0; i < arr.length; i++) {
tmp[arr[i] - min].push(arr[i])
}
// 桶大小1时,里面不用再排序了
return tmp.flat()
}
// let arr = [65,76,66,65,71,66,74,71,69,68,71,72,74,64];
let arr = []
for (let i = 0; i < 1000000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort")
sort(arr)
console.timeEnd("sort") // 30ms
9.计数排序
● 每个数字, 累加次数,
● 取次数-- = i+min
// 计数排序- 重复数字较多
function sort(arr){
let max = arr[0]
let min = arr[0]
for (let i = 0; i < arr.length; i++) {
max = Math.max(arr[i], max)
min = Math.min(arr[i], min)
}
let tmp = new Array(max - min + 1).fill(0)
for (let i = 0; i < arr.length; i++) {
tmp[arr[i] - min] += 1 // 计数
}
// console.log(tmp);
let result = []
for (let i = 0; i < tmp.length; i++) {
let j = tmp[i]
while (j-- > 0) {
result.push(i+min)
}
}
// console.log(result);
}
// let arr = [65,76,66,65,71,66,74,71,69,68,71,72,74,64];
let arr = []
for (let i = 0; i < 1000000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort")
sort(arr)
console.timeEnd("sort") // 14 ms
10.基数排序
● 最大数位数
● 10桶,个位分桶有序 > 十位分桶有序 > .. 最大位有序
// 基数排序 手机号
function sort(arr){
let max = arr[0]
for (let i = 0; i < arr.length; i++) {
max = Math.max(arr[i], max)
}
maxLen = max.toString().length // 最大数位数,决定几次分桶
for (let i = 0; i < maxLen; i++) {
// 桶
let tmp = new Array(10).fill(0).map(() => []) // 0-9
for (let j = 0; j < arr.length; j++) {
let v = Math.floor(arr[j] / Math.pow(10, i)) % 10
tmp[v].push(arr[j])
}
// console.log(tmp)
arr = tmp.flat()
// console.log(arr);
}
return arr
}
// let arr = [32, 645, 3, 230, 40, 99, 3, 999, 9, 0, 66, 48, 273, 69, 63];
let arr = []
for (let i = 0; i < 1000000; i++) {
arr.push(Math.floor(Math.random()*1000))
}
console.time("sort")
sort(arr)
console.timeEnd("sort") // 90ms
let arr1 = [32, 645, 3, 230, 40, 99, 3, 999, 9, 0, 66, 48, 273, 69, 63];
sort(arr1);
// 按位,排序过程
// [230, 40, 0, 32, 3, 3, 273, 63, 645, 66, 48, 99, 999, 9, 69]
// [0, 3, 3, 9, 230, 32, 40, 645, 48, 63, 66, 69, 273, 99, 999]
// [0, 3, 3, 9, 32, 40, 48, 63, 66, 69, 99, 230, 273, 645, 999]