[路飞]_快排、希尔

200 阅读2分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

快速排序

实用性强, 二分的插入排序, 平均时间复杂度O(nlogn) 快速排序是采用了分治,先取了一个标志位,然后通过和标志位上的数字进行对比,小的放左边,大的放右边。 分好的左右两边各自再取标志位进行比较,直到分到数组长度为1.

function partition(arr ,left ,right){
    // 使用left索引位作为参考元素 如果right对应的元素比temp小或者left对应的元素比temp大做位置交换
    // 否则 left指针向右移 right指针向左移
    let temp = arr[left];
    // 取得左边索引第一个存储 
    while(left < right){
        while(left < right && arr[right] > temp){
            right --
        }
        arr[left] = arr[right] //temp值比right小 就与left对应索引值交换位置
        while(left < right && arr[left] < temp){
            left ++
        }
        arr[right] = arr[left] // temp值比left大, 就与right对应索引值交换位置
    }
    //循环结束 left right 相遇  temp 的左边都是比temp小的元素 右边都是比temp大的元素
 	arr[left] = temp // 最后将参考元素放到left的位置 
    return left
}
function quickSort(arr, left , right){
   let len = arr.length;
   left = typeof left != 'number' ? 0 : left
   right = typeof right != 'number' ? len -1: right
   if(left < right){
       //  找到二分的索引位置
       index = partition(arr, left, right)
       // 将二分的区域 重复之前操作
       quickSort(arr, left ,index-1)
       quickSort(arr, index+1, right)
   }
   return arr
}

希尔排序

快速排序是分区内元素进行比较, 希尔是分区之间的元素 进行比较, 分区的方式有平均分希尔增量(n/2分) , n/3分 (按长度均分的情况时间复杂度比较高, 如果分区内元素较多 比较的次数相应增多,适当的增量对提高排序效率很有帮助)

function shellSort(arr){
    let gap = 1,len = arr.length;  // gap表示每几个元素分一组
    while(gap < len /3){ // 按N/3分区
        gap = gap * 3 +1
    }
    for(; gap > 0; gap = Math.floor(gap /3)){
        for(let i = gap; i< len; i++){ // [ 5,4,3,2 | 1(i) ]
            let j = i - gap; // [5(j),4,3,2 | 1(i)]
			let temp = arr[i]
            for(;j>=0 && arr[j]> temp; j-=gap){ // [5(j),4,3,2 | 1(i)] 1 和 5 比较
                arr[j+gap] = arr[j]  // [5(j),4,3,2 | 5(j+gap)}]
            }
            arr[j+gap] = temp //比较完成 将temp放到 j+gap上 [1(j),4,3,2, | 5(j+gap)]
        }
    }
    return arr
}

结束语

如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~