八大常用排序算法----JavaScript版实现

常用八大排序算法

前言

  • 此篇来介绍常用的排序算法JavaScript版实现,Java版请戳这里【含简略讲解】。其实网上的介绍讲解汗牛充栋,并且有很多优秀的文章,写此篇的目的是为了加深下自己的印象,还有融入点自己的想法。当笔记使啦~
  • 注:排序元素顺序以从小到大排序为主;
var arr = [7,4,5,3,6,2,1,9,0];
var arr1 = new Array(100000);
for(let i=0;i<100000;i++){
    arr1[i] = Math.floor((Math.random()*100000));
}
/**
 * @see 冒泡排序,每次循环确定一个大的数/小的数放在数组的两端
 * 
*/
function bobbleSort(arr){
    for(let i=0;i<arr.length;i++){ //控制循环次数
        for(let j=0;j<arr.length-i-1;j++){
            if(arr[j]>arr[j+1]) {
                let temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    //console.log(arr);
}
/**
 * @see 选择排序
 * 注重索引的选择,每次选择最小/最大的那个数的索引,
 * 然后再和数组的两端交换位置
 * 
*/
function selectSort(arr){
    for(let i=0;i<arr.length-1;i++){
        let minIndex = i;
        for(let j=i+1;j<arr.length;j++){
            if(arr[j]<arr[minIndex]){
                minIndex = j;
            }
        }
        let temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}
/**
 * 
 * @see 插入排序
*/
let arrIns = arr1.slice(0,arr1.length);
function insertSort(arr){
    for(let i = 0;i<arr.length-1;i++){
        //定义插入索引
        let j = i+1;
        //暂存需要插入的数字
        let insertNum = arr[j];
        while(j>=1 && insertNum < arr[j-1]){
            arr[j] = arr[j-1];
            j--;
        }
        arr[j] = insertNum;
    }
}
/**
 * @see 希尔排序,缩小增量的排序
 * 
*/
let arrShl = arr1.slice(0,arr1.length);
function ShellSort(arr){
    //步长循环
    for(let gep = parseInt(arr.length/2);gep > 0;gep=parseInt(gep/2)){

        //分组式插入排序
        for(let i = gep;i < arr.length;i++){
            //定义插入索引
            let j = i;
            let insertNum = arr[j];
            while(j >= 0 && insertNum < arr[j-gep]){
                arr[j]  = arr[j-gep];
                j -= gep;
            }
            arr[j] = insertNum;
        }
        
    }
}
/**
 * @see 此类用于演示归并排序
 * 
 * */ 
class MergeSort{
    //分治合并总方法
    mergeSort(arr,left,right,temp){
        if(left<right){
            let mid = parseInt((left+right)/2);
            this.mergeSort(arr,left,mid,temp); //向左递归分解
            this.mergeSort(arr,mid+1,right,temp); //向右递归分解
            this.merge(arr,left,mid,right,temp);
        }
    }
    /**
     * @param arr 需要排序的目标数组
     * @param left 左边有序序列的初始索引
     * @param mid 中间索引
     * @param right 右边索引
     * @param temp 中间临时数组
     * */ 
    merge(arr,left,mid,right,temp) {
       //左边有序数组起始索引 
       let i = left;
       //右边数组起始索引
       let j = mid+1;
       //临时数组起始索引
       let t = 0;
       //循环进行归并
       while(i <= mid && j <= right){
           if(arr[i]<=arr[j]) {  
               temp[t] = arr[i];
               i++;
               t++;
           }else{
               temp[t] = arr[j];
               j++;
               t++;
           }
       }
       //左边数组剩余元素
       while(i<=mid){
           temp[t] = arr[i];
           i++;
           t++;
       }
       //右边数组剩余元素
       while(j<=right){
        temp[t] = arr[j];
        j++;
        t++;
    }
    //将临时数组copy到原数组
    //注意不是每次都copy所有元素到元素组
    t = 0;
    let tempLeft = left;
    while(tempLeft <= right){
        arr[tempLeft] = temp[t];
        t+=1;
        tempLeft+=1;
    }
   }
}
/**
 * @see 快速排序
 * @param arrQ 目标数组
 * @param left 逻辑数组的起始索引
 * @param right 逻辑数组的终止索引
*/
function quickSort(arrQ,left,right){
    if(left>=right){
        return;
    }
    //寻找一个基数
    let key = arr[left];
    //构造两个指针
    let i = left,j=right;
    while(i<j){
        while(arr[j]>=key && i<j){
            j--;
        }
        while(arr[i]<=key && i<j){
            i++;
        }
        //交换位置
        let temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    arr[left] = arr[i];
    arr[i] = key;
    quickSort(arrQ,left,i-1);
    quickSort(arrQ,i+1,right);
}
/**
 * @param arr 目标数组
 * @param i 逻辑二叉树的头节点
 * @param length 数组的长度
*/
function adjustHeap(arr,i,length){
    //取出当前节点值
    let temp = arr[i];
    //调整2*k+1,是i的左子节点
    for(let k = 2*i+1;k<length;k=k*2+1){
        if(k+1 < length && arr[k] < arr[k+1]){ //说明右子节点的数大于左子节点的数字
            k++;
        }
        //赋值给头节点
        if(arr[k] > temp){
            arr[i] = arr[k];
            i = k;
        }else{

            break;
        }
    }
    //当for循环结束后,我们已经将以 i 为父节点的树最大值,放在了最顶(局部)
    arr[i] = temp;
}
/**
 * @see 堆排序
 * @param arr 目标数组
*/
function heapSort(arr){
    let temp = 0;
    //构建堆顶结构
    for(let i = parseInt(arr.length/2)-1;i>=0;i--){
        adjustHeap(arr,i,arr.length);
    }
    //将最大元素“沉底”
    for(let j = arr.length-1;j>0;j--){
        //交换
        temp = arr[j];
        arr[j] = arr[0];
        arr[0] = temp;
        adjustHeap(arr,0,j);
    }
}



//测试冒泡排序
// console.time("bobble");
// bobbleSort(arr);
// console.timeEnd("bobble");
//测试选择排序
//let arrSel = arr1.slice(0,arr1.length);
//console.time("selectSort");
//selectSort(arrSel);
//console.timeEnd("selectSort");
//测试插入排序
//let arrIns = arr1.slice(0,arr1.length);
//console.time("insertSort");
//insertSort(arrIns);
//console.timeEnd("insertSort");
//测试希尔排序
//let arrShell = arr1.slice(0,arr1.length);
//console.time("shellSort");
//ShellSort(arrShell);
//console.timeEnd("shellSort");
//测试归并排序
// function mergeSortTest(arr) {
//     let right = arr.length-1;
//     let temp = new Array(right+1).fill(0);
//     let test = new MergeSort();
//     test.mergeSort(arr,0,right,temp);
// }
// mergeSortTest(arr);
//测试快速排序
//quickSort(arr,0,arr.length-1);
//console.log(arr);
//测试堆排序
// heapSort(arr);
// console.log(arr);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值