function BubbleSort(){
const{length}=array
for(let i=0;iarr[j+1]){
swap(arr,j,j+1)
}
}
}
console.log(arry);
}
function swap(arry, a, b) {
const temp = arry[a]
arry[a] = arry[b]
arry[b] = temp
//或者用 [arry[b],arry[a]]=[arry[a],arry[b]]//es6中数组解构
}
var arr= [1,2,3,4,5]
记录并不断更改索引值,找到最小的数后替换
假设数组为 [5, 3, 8, 4, 2]
:
i = 0
):
2
在索引 4
,交换后数组变为 [2, 3, 8, 4, 5]
。i = 1
):
3
在索引 1
(未移动),数组保持不变。i = 2
):
4
在索引 3
,交换后数组变为 [2, 3, 4, 8, 5]
。i = 3
):
5
在索引 4
,交换后数组变为 [2, 3, 4, 5, 8]
。排序完成,最终数组为 [2, 3, 4, 5, 8]
。
记录索引对于元素的值,就是把大的数往后面覆盖,最后肯定右两个重复的大数,直接把当前的temp覆盖到排在前面的大数就行
function insertSort(){
const {length}=arr
let temp
for(let i=1;i0&&arr[j-1]>temp){
arr[j]=arr[j-1]
j--
}
arr[j]=temp
}
console.log(arr);
}
insertSort=[5, 4, 3, 3, 1]
具体用实例说明
第一轮循环(i = 1):
temp = arr[1] = 4
j = 1
arr[j-1] (5)
和 temp (4)
,因为 5 > 4
,所以进入 while 循环。arr[j-1]
(5) 后移一位,数组变为 [5, 5, 3, 3, 1]
j--
,现在 j = 0
j = 0
temp (4)
插入到 arr[j]
,数组变为 [4, 5, 3, 3, 1]
第二轮循环(i = 2):
temp = arr[2] = 3
j = 2
arr[j-1] (5)
和 temp (3)
,因为 5 > 3
,所以进入 while 循环。arr[j-1]
(5) 后移一位,数组变为 [4, 5, 5, 3, 1]
j--
,现在 j = 1
arr[j-1] (4)
和 temp (3)
,因为 4 > 3
,所以继续 while 循环。arr[j-1]
(4) 后移一位,数组变为 [4, 4, 5, 3, 1]
j--
,现在 j = 0
j = 0
temp (3)
插入到 arr[j]
,数组变为 [3, 4, 5, 3, 1]
第三轮循环(i = 3):
temp = arr[3] = 3
j = 3
arr[j-1] (5)
和 temp (3)
,因为 5 > 3
,所以进入 while 循环。arr[j-1]
(5) 后移一位,数组变为 [3, 4, 5, 5, 1]
j--
,现在 j = 2
arr[j-1] (4)
和 temp (3)
,因为 4 > 3
,所以继续 while 循环。arr[j-1]
(4) 后移一位,数组变为 [3, 4, 4, 5, 1]
j--
,现在 j = 1
arr[j-1] (3)
和 temp (3)
,因为 3 == 3
,所以 while 循环结束。temp (3)
插入到 arr[j]
,数组变为 [3, 3, 4, 5, 1]
第四轮循环(i = 4):
temp = arr[4] = 1
j = 4
arr[j-1] (5)
和 temp (1)
,因为 5 > 1
,所以进入 while 循环。arr[j-1]
(5) 后移一位,数组变为 [3, 3, 4, 5, 5]
j--
,现在 j = 3
arr[j-1] (4)
和 temp (1)
,因为 4 > 1
,所以继续 while 循环。arr[j-1]
(4) 后移一位,数组变为 [3, 3, 4, 4, 5]
j--
,现在 j = 2
arr[j-1] (3)
和 temp (1)
,因为 3 > 1
,所以继续 while 循环。arr[j-1]
(3) 后移一位,数组变为 [3, 3, 3, 4, 5]
j--
,现在 j = 1
arr[j-1] (3)
和 temp (1)
,因为 3 > 1
,所以继续 while 循环。arr[j-1]
(3) 后移一位,数组变为 [3, 3, 3, 4, 5]
j--
,现在 j = 0
j = 0
temp (1)
插入到 arr[j]
,数组变为 [1, 3, 3, 4, 5]
火狐浏览器的sort就是基于这种排序,chrome用到快速排序
function mergeSort(array){
if(array.length>1){
const {length}=array
const middle=Math.floor(length/2)
const left=mergeSort(array.slice(0,middle))
const right=mergeSort(array.slice(middle,length))
array=merge(left,right)
}
}
function merge(left,right){
let i=0;
let j=0;
const result=[]
while(i
用具体例子解释一下执行过程
第一次调用 mergeSort
:
middle
是 2。left
是 [5, 4]
,right
是 [3, 2, 1]
。mergeSort
对 left
和 right
进行排序。left[i] (4)
与 right[j] (1)
比较,因为 1 < 4
,所以将 1
添加到 result
中。j
增加 1,现在 j = 1
。left[i] (4)
与 right[j] (2)
比较,因为 2 < 4
,所以将 2
添加到 result
中。j
增加 1,现在 j = 2
。left[i] (4)
与 right[j] (3)
比较,因为 3 < 4
,所以将 3
添加到 result
中。j
增加 1,现在 j = 3
。left[i] (4)
与 right[j] (不存在)
比较,因为 right
数组已经没有更多元素,所以将 left
数组剩余的元素 [4, 5]
添加到 result
中。以一个元素为基准(可以是middle,0,length-1)把比它小的放一堆,比它大的放一堆,在以第一堆的元素中挑一个基准,比它大的挑一堆,比它小的调一堆,分到最后把这几堆和一起。
function quickStore(){
const {length}=arr
if(length<2){
return arr
}
let base=arr[0]
let minArr=arr.slice(1).filter(item=>item>=base)
let maxArr=arr.slick(1).filter(item=>item
但是会占据空间
找到最大值
const maxValue = findMax(arr)
// const maxValue = Math.max(...arr)
findMax
函数来找到数组中的最大值。findMax
函数遍历数组,比较每个元素,找到最大值。:初始化计数数组
const counts = new Array(maxValue + 1)
maxValue + 1
的数组 counts
,用于存储每个元素的出现次数。counts
的长度为 10。 : 计数每个元素的出现次数
例如遍历到数组中数字5出现2次,就把counts计数数组的下标为5的位置计为1,再白能力一遍还有就++计为2。所以count数组中索引值为5的地方数值为2,意思是5出现了两次。
arr.forEach(item => {
if(!counts[item]){
counts[item] = 0
}
counts[item]++
})
构建新的排序数组
let newarr = []
let sortIndex = 0
counts.forEach((item, index) => {
while(item > 0){
newarr[sortIndex++] = index
item--
}
})
newarr
。counts
数组,根据计数构建新的排序数组。counts
中的每个非零元素,将其索引(即原数组中的元素值)添加到 newarr
中相应次数。例如:遍历到5前面数字都没有出现就不会进入while循环,知道索引值index为5时,就将newarr
中sortIndex=0索引值为0的位置计为index5,sortIndex++变为1,迎接下一个元素,counts
数组中索引值5的item减一也就是减少出现次数后再遍历是否还出现,如果还有就把count下标1的位置再计为5.出现次数减一。 var arr=[5,7,5,4,9,1]
function countSort(arr){
if(arr.length<2){
return arr
}
const maxValue=findMax(arr)
// const maxValue=Math.max(...arr)也可以用js内置方法
const counts=new Array(maxValue+1)
arr.forEach(item => {
if(!counts[item]){
counts[item]=0
}
counts[item]++
})
let newarr=[]
let sortIndex=0
counts.forEach((item,index)=>{
while(item>0){
newarr[sortIndex++]=index
item--
}
})
}
countSort(arr)
function findMax(arr){
let max=arr[0]
for(let i=0;imax){
maax=arr[i]
}
}
return newarr
}
function bucketSort(arr, bucketSize=3){
if(arr.length<2){
return arr
}
//创建几个小桶
const buckets=createBucket(arr,buckdetSize)
//小桶排序(插入算法)合并concat
return sortBucket(buckets)
}
function createBucket(arr,buckdetSize){
//找最大值和最小值
let minValue=Math.min(...arr)
let maxValue=Math.max(...arr)
//桶数量
const bucetCount=Math.floor((maxValue-minValue)/ buckdetSize)+1//+1是为了如果最大值正好等于某个桶的边界值,
// 那么按照简单的除法计算,最大值可能会被分配到超出桶的范围之外。
// //创建桶子
// const buckets = []
// for (let i = 0; i < bucketCount; i++) {
// buckets[i] = []
// }
// ES6
const buckets=[...Array(bucetCount)].map(()=>[])
//判断每个元素应该进哪个桶子
for (let i = 0; i < arr.length; i++) {
const index = Marh.floor((arr[i] - minValue) / bucketSize)
buckets[index].push(arr[i])
}
return buckets
}
function sortBucket(){
const sortArr=[]
for(let i=0;i 0 && arr[j - 1] > temp) {
arr[j] = arr[j - 1]
j--
}
arr[j] = temp
}
console.log(arr);
}
bucketSort([5,4,3,2,6,1,7,10,9,8])
缺点是如果最大数为100,中间会创造很多无效桶
填补了计数排序和桶排序的缺点
给定桶子的数量。一般是10,将数组里的数字先按照个位排序,再按十位,再百位~
再掌握这个思想
//Math.floor(x/diveder)%base
//divider*=base
以35举例:x是35,diveder事先定义为1,base为10
得到十位35/1=35%10=5,得到个位35/10=3%10=3
let maxVal=Math.max(...arr)
while(divider<=maxVal){
//构建二维数组
const buckets = [...Array(10)].map(() => [])
for (let val of arr) {
buckets[Math.floor(val / divider) % base].push(val)
//把取得个位数,十位数百位数推到bukets中
}
arr = [].concat(...buckets)
divider *= base
}
去最大值作为循环结束的条件
用array和map的方法创建10个空数组。遍历arr中元素,用Math方法取出个十百位数,推到buckets中,如:bucket[3]=3
arr = [].concat(...buckets)
divider *= base
表示将arr数组中所有个位数取出来排好后,用concat连成数组,再排新数组中每个元素的十位数,divider*10后变成10.....
完整代码
const arr=[35,2,26,2,5,8,34,1,56,99,33]
function radixSort(arr){
const base=10
let divider=1
//Math.floor(x/diveder)%base//得到十位35/1=35%10=5,得到个位35/10=3%10=3
//divider*=base
let maxVal=Math.max(...arr)
while(divider<=maxVal){
//构建二维数组
const buckets = [...Array(10)].map(() => [])
for (let val of arr) {
buckets[Math.floor(val / divider) % base].push(val)//把取得个位数,十位数百位数推到bukets中
}
arr = [].concat(...buckets)
divider *= base
}
return arr
}