Day5-排序

107 阅读1分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

记录一下常用的排序

名称时间复杂度
冒泡排序O(n^2)
快速排序O(nlgn)

冒泡排序

const bubbleSort = arr => {
    const len = arr.length - 1;
    for (let j = 0; j < len; j++) {
        // 已经有j个最大值在最后面了,所以遍历的长度为len - j
        for (let i = 0; i < len - j; i++) {
            if (arr[i] > arr[i+1]) {
                [arr[i], arr[i+1]] = [arr[i+1], arr[i]]
            }
            console.log(arr)
        }
    }
    return arr
}

动图: 849589-20171015223238449-2146169197.gif

快速排序

思路:找第一个元素作为基准值,比我大的放在右边,比我小的放在左边,然后递归的进行调用。

const quickSort = arr => {
    if (arr.length < 2) {
        return arr
    }
    let flag = arr[0];
    let left = [];
    let right = []
    for (let i = 1; i < arr.length; i++) {
        if (arr[i] > flag) {
            right.push(arr[i])
        } else {
            left.push(arr[i])
        }
    }
    return quickSort(left).concat(flag,quickSort(right))
}

双指针法快速排序(原地快排)

这个方法的解释掘金里面很多,直接引用

juejin.cn/post/707971…

function quick(arr,start,end){
    let init = start
    let flag = arr[init]
    start++
    while(start<=end){
        while(arr[end]>flag){
            end--
        }
        while(arr[start]<flag){
            start++ 
        }
        // 引用的代码里面有bug,少了边界条件,部分数据不过
        // [5,1,1,2,0,0] [3,1]
        if (start==end){
            break
        }
        if(start<end){
            [arr[start],arr[end]] = [arr[end],arr[start]]
            start++
            end--
        }
    };
    [arr[init],arr[start-1]] = [arr[start-1],arr[init]]
    return start
}
function quickSort(arr,start,end,from){
    if(start<end){
        let index = quick(arr,start,end,from);
        // quickSort(arr,start,index-1);也是同样的效果
        // index-1包含了标志位,index-2不包含
        quickSort(arr,start,index-2);
        quickSort(arr,index,end);
    }
    return arr
}

另外一个方法写的也很好,容易理解,也引用上

juejin.cn/post/699630…

var sortArray = function(nums) {
    function quickSort(arr, begin, end) {
        if (begin >= end) {
            // 引用中这里有bug,如果[3]则不过
            return arr
        }
        let temp = arr[begin];
        let left = begin;
        let right = end;
        while(right > left) {
            while(right > left && arr[right] >= temp) {
                right--;
            }
            while(right > left && arr[left] <= temp) {
                left++;
            }
            [arr[left], arr[right]] = [arr[right], arr[left]];
        }

        [arr[begin], arr[right]] = [arr[right], arr[begin]];
        quickSort(arr, begin, right - 1);
        quickSort(arr, right + 1, end);
        return arr;
    }
    return quickSort(nums, 0, nums.length - 1)
};

力扣912-排序数组可验证各种情况

力扣15-三数之和

image.png

var threeSum = function(nums) {
    // 0.直接返回
    if (nums.length < 3) {
        return []
    }
    nums.sort((a,b) => a - b)
    let list = []
    for (let i = 0; i < nums.length; i++) {
        // 4.跳过重复的数据,否则结果数组里面会有重复
        if(nums[i]===nums[i-1]){
            continue
        }
        // 1.以i为基准,左侧指针和右侧指针都向中间移动
        let left = i + 1;
        let right = nums.length - 1;
        // 2.判断三个数相加为0的情况
        while(left < right) {
            if(right === i) {
                right-- 
            }else if (nums[left] + nums[right] + nums[i] === 0) {
                list.push([nums[left],nums[right],nums[i]])
                // 3.继续找是否有其他符合情况
                while(nums[left] === nums[left+1]) {
                    left++
                }
                left++
                while(nums[right] === nums[right-1]) {
                    right--
                }
                right--
            } else if (nums[left] + nums[right] + nums[i] > 0) {
                right--
            } else {
                left++
            }
        }
    }
    return list;
};

const nums = [-1,0,1,2,-1,-4]
console.log(threeSum(nums))

参考:github.com/course-dash…