您的位置:首页 > Web前端 > JavaScript

JavaScript实现几种排序算法

2019-04-18 16:46 260 查看

JavaScript实现几种排序算法


图片名词解释:
n: 数据规模
k:“桶”的个数
In-place: 占用常数内存,不占用额外内存
Out-place: 占用额外内存

(图片源自网络,侵删)

1.冒泡排序:

function bubbleSort(arr){
var temp
for(var i = 1; i < arr.length; i++){
for(var j = 0; j < arr.length-1-i; j++){//每一趟都会把最大的放到最后,因此循环-1
if(a[j] > a[j+1]){
temp = a[j]
a[j] = a[j+1]
a[j+1] = temp
}
}
}
return arr
}

2.选择排序

function selectSort(arr){
for(var i = 1; i < arr.length; i++){
let t = arr[i]
for(var j = i - 1; j >= 0; j--){
if(t < arr[j]){
arr[j+1] = arr[j]
arr[j] = t
}
else
break
}
}
return arr
}

3.希尔排序(插排就是将希尔排序中的gap设为1, 因此不再写出)

function shellSort(arr){
for(var gap = 4; gap > 0; gap /= 2){
// 以gap为间隔进行插入排序
for(var i = gap; i < arr.length; i++){
let t = arr[i]
for(var j = i - gap; j >= 0; j -= gap){
if(t < arr[j]){
arr[j + gap] = arr[j]
arr[j] = t
}
else break
}
}
}
return arr

4.归并排序

// 归并排序中的——治
// 解释各参数的意思:
// arrB为待排序列, arrN为临时序列, lHead表示左边起始的排序位置, rHead表示右边起始的排序位置,rEnd表示结束位置
function Merge(arrB, arrN, lHead, rHead, rEnd){
let lEnd = rHead - 1 //假设两个序列紧靠在一起, 这里的指针通通以数组下标来表示
let arrBNum = rEnd - lHead + 1 //确定代排序列的长度
let i
for(i = lHead; lHead <= lEnd && rHead <= rEnd; i++){
if(arrB[lHead] <= arrB[rHead]){
arrN[i] = arrB[lHead]
lHead++
}else{
arrN[i] = arrB[rHead]
rHead++
}
}
while(lHead <= lEnd){
//排完序左边还有多余的直接插入到arrN的后面
arrN[i] = arrB[lHead]
i++
lHead++
}
while(rHead <= rEnd){
//排完序左边还有多余的直接插入到arrN的后面
arrN[i] = arrB[rHead]
i++
rHead++
}
// 将临时数组arrN中的值按照次序复制给arrB对应位置
for(var j = 0; j < arrBNum; j++, rEnd--){
arrB[rEnd] = arrN[rEnd]
}
return arrB

}

// 归并排序中的——分(递归)
function Sort(arrB, arrN, lHead, rEnd){
var mid
if(lHead < rEnd){
mid = parseInt((rEnd + lHead)/2)
// console.log(mid + "==" + rEnd + "==" + lHead)
// 循环调用Sort函数对左右两边进行排序
Sort(arrB, arrN, lHead, mid)  //排左边, 一直递归到 lHead = rEnd (即针对只有1个数据的merge)
Sort(arrB, arrN, mid+1, rEnd)
// 排序方法,递归调用的最后一步就是将他们排序
Merge(arrB, arrN, lHead, mid+1, rEnd)
}
return arrB
}

// 合并
function mergeSort(arr){
var arrN = []
return Sort(arr, arrN, 0, arr.length-1)
}

5.快速排序

function quickSort (arr, start, end){
if(start > end) return
let base = arr[start]
let l = start
let r = end
while(l != r){
while(arr[r] >= base && l < r){
r--
}//从右向左寻找,直到有数比基准数小时,停下
while(arr[l] <= base && l < r){
l++
}//从左向右寻找,直到有数比基准数大时,停下

// 此时交换找到的这两个数
var temp = arr[r]
arr[r] = arr[l]
arr[l] = temp
}
//此时循环被跳出说明此时 l==r 则需要交换其与基准数的位置
// arr[l] = base
// arr[start] = arr[r]  这样赋值是错误的,因为arr[i] 和arr[r] 是指向的同一个数,修改一个则另一个也会改变
arr[start] = arr[l]
arr[l] = base

// 此时位于arr[r]左边的数都比他小,右边的数都比他大
// 对它的左右两边分别进行快排
quickSort(arr, start, l-1)
quickSort(arr, r+1, end)

return arr

}

6.堆排序

//堆排序

function heapify(arr, n, i){
if(i >= n){
return
}
let c1 = 2*i + 1
let c2 = 2*i + 2 //找到左右子节点, 这里一定要记得对左右子节点的存在性进行判断不能越界

var max = i
if(arr[c1] > arr[max] && c1 < n){
max = c1
}
if(arr[c2] > arr[max] && c2 < n){
max = c2
}
if(max != i){
var temp = arr[i]
arr[i] = arr[max]
arr[max] = temp
heapify(arr, n, max) //每次交换后要对被交换的孩子节点进行重新调整
}  //堆顶放上最大元素

return arr
}

function bulid_heap(arr, n){
//构造一个堆一定要从下往上
let last_node = n-1
let parent = parseInt((last_node - 1)/2)

for(var i = parent; i >= 0; i--){
heapify(arr, n, i)
}
return arr
}

function heapSort(arr, n){
bulid_heap(arr, n)
for(var i = n - 1; i >= 0; i--){
var temp = arr[i]
arr[i] = arr[0]
arr[0] = temp
// console.log(i+'--'+arr)
bulid_heap(arr, i)
// console.log(arr)
// console.log(i + "-" + arr[i])
}
return arr
}

以上7种(含插入排序)都是基于选择的简单排序

下面是非比较的排序算法(就叫 桶排序吧~)
1.计数排序

// 计数排序

function countSort (arr, min, max){
let count = []
for(var i = min; i <= max; i++){
count[i] = 0
}//对JS的数组进行初始化,否则会显示未定义而出错
let result = []

for(var i = 0; i < arr.length; i++){
// console.log(arr[i])
count[arr[i]]++
console.log(count[arr[i]])
}
console.log(count)
for(var j = min, index = 0; j<= max; j++){
while(count[j] != 0){
result[index] = j
index++
count[j]--
}
}
return result
}

未完待续……

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: