排序
冒泡排序
每冒泡一次有序度加1,逆序度减1
const bubbleSort = (arr) => {
for(let i = 0; i < arr.length; i++){
let isChange = false;
for(let j = 0; j < arr.length - i - 1; j++){
if(arr[j] > arr[j+1]){
[arr[j],arr[j + 1]] = [arr[j + 1],arr[j]]
isChange = true
}
}
if(!isChange)break
}
console.log(test)
}
const test = [4, 5, 6, 3, 2, 1]
bubbleSort(test)
插入排序
无序数组中取一个要插入的元素和有序数组中要插入的元素进行比较,找到要插入的位置
const insertionSort = (arr) => {
if(arr.length <= 1)return
for(let i = 1; i < arr.length; i++){
let insertVal = arr[i]
let j = i - 1
for(j; j >= 0; j--){
if(insertVal < arr[j]){
arr[j + 1] = arr[j]
}else{
break
}
}
arr[j + 1] = insertVal
}
console.log(arr)
}
const testSort = [4, 1, 6, 3, 2, 1]
insertionSort(testSort)
选择排序
每次按顺序找到最小的数排在有序组里,有序组里的数据不再比较
const selectionSort = (arr) => {
if (arr.length <= 1) return
for(let i = 0; i < arr.length - 1; i++){
let minIndex = i
for(let j = i + 1; j < arr.length; j++){
if(arr[minIndex] > arr[j]){
minIndex = j
}
}
[arr[i],arr[minIndex]] = [arr[minIndex],arr[i]]
}
console.log(arr)
}
const testSelect = [4, 8, 6, 3, 2, 1, 0, 12]
selectionSort(testSelect)
归并排序
- 递推式,Left:mergerSort(0,mid),Right:mergerSort(mid)
- 终至条件:分裂到一个为止
- 合并的时候因为已经是有序的了,比较的时候找出一个相对的较大值,如这个值小的统统优先加入队列合并,因为2个数组都是有序的,2个数组只要有一个已经全部比完说明已经排序完成,后面的就不要陪你过比了,直接合并到后面即可
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))
}
function merge(l,r){
let res = []
let li = 0;
let ri = 0;
while(li < l.length && ri < r.length){
if(l[li] < r[ri]){
res.push(l[li++])
}else{
res.push(r[ri++])
}
}
while(li < l.length){
res.push(l[li++])
}
while(ri < r.length){
res.push(r[ri++])
}
return res
}
堆排序
- N - 1/2 获取任意节点的父节点
- left:l * 2 + 1 获取左子节点
- right: r * 2 + 2 获取右子节点
- N/2 -1 获取非叶子节点
- 构建大顶堆后对每次的heap的最后一个元素进行位置进行交换就可以实现升序排序
const heapSort = (arr) => {
if(arr.length <= 0) return arr
let heapSize = arr.length
heapBuild(arr,heapSize)
while(heapSize > 1){
heapSize --
[arr[0],arr[heapSize]] = [arr[heapSize],arr[0]]
heapIfy(arr,heapSize,0)
}
return arr
}
function heapBuild(arr,size){
for(let i = Math.floor(size/2-1); i >= 0; i --){
heapIfy(arr,size,i)
}
}
function heapIfy(arr,size,i){
let left = i * 2 + 1
let right = i * 2 + 2
let largest = i
if(left < size && arr[left] > arr[largest]){
largest = left
}
if(right < size && arr[right] > arr[largest]){
largest = right
}
if(largest !== i){
[arr[i],arr[largest]] = [arr[largest],arr[i]]
heapIfy(arr,size,largest)
}
}
const test = [3,5,1,6,4,7,2]
console.log(heapSort(test))
快速排序
- 选出主元,定义左右指针,找到大于或小于主元的元素时进行位置互换
- 递归执行1条件,直到左右指针交叉为止
const quickSort = (arr) => {
quick(arr,0,arr.length -1)
console.log(arr)
}
const quick = (arr,left,right) => {
let index
if(arr.length > 1){
index = partition(arr,left,right)
if(left < index - 1){
quick(arr,left,index - 1)
}
if(right > index){
quick(arr,index,right)
}
}
}
function partition(arr,left,right){
let pivot = arr[Math.floor((left + right)/2)]
let i = left
let j = right
while(i <= j){
while(arr[i] < pivot){
i++
}
while(arr[j] > pivot){
j--
}
if(i <= j){
[arr[i],arr[j]] = [arr[j],arr[i]]
i++
j--
}
}
return i
}
const test = [3,5,1,6,4,7,2]
quickSort(test)