JavaScript实现几种排序算法

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
}

未完待续……

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值