手撕排序

/* 手撕排序 + 算法总结 */
//比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。
//非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。

// 1.冒泡排序
//时间复杂度O(n^2) 最好情况O(n),空间O(1) 稳定
//它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。
//走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
var num = [1,2,4,3,5,6,8,7,9]
var bubbleSort = function(num){
    var temp=0;
    var i=num.length;
    while(i--){
        for(let j=0;j<i-1;j++){
            if(num[j]>num[j+1]){
                temp = num[j+1];
                num[j+1]=num[j];
                num[j]=temp;
            }
        }
    }
    return num;
}
var a=bubbleSort(num);
console.log(a);

// 2.选择排序
//时间复杂度O(n^2) 最好情况O(n^2),空间O(1) 不稳定
//首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置;
//然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
var selectionSort = function(num){
    for(let i=0;i<num.length;i++){
        let temp=0;
        for(let j=i+1;j<num.length;j++){
            if(num[i]>num[j]){
                temp=num[j];
                num[j]=num[i];
                num[i]=temp;
            }
        }
    }
    return num;
}
var b=selectionSort(num);
console.log(b);

// 3.插入排序
//时间复杂度O(n^2) 最好情况O(n),空间O(1) 稳定
//通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
var insertionSort = function(num){
    var temp=0;
    for(let i=0;i<num.length;i++){
        for(let j=i;j>0;j--){
            temp = num[j];
            if(num[j]<num[j-1]) num[j] = num[j-1];
            else{
                num[j]=temp;
                break;
            }
        }   
    }
    return num;
}
var c=insertionSort(num);
console.log(c)

// 4.归并排序
//该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
//将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
function mergeSort(arr) {
    var len = arr.length;
    if (len < 2) {
        return arr;
    }
    var middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}
 
function merge(left, right) {
    var result = [];
 
    while (left.length>0 && right.length>0) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }
 
    while (left.length)
        result.push(left.shift());
 
    while (right.length)
        result.push(right.shift());
 
    return result;
}
var d=mergeSort(num);
console.log(d);

// 5.快速排序
//通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,
//则可分别对这两部分记录继续进行排序,以达到整个序列有序。
//steps
//从数列中挑出一个元素,称为 “基准”(pivot);
//重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
//递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
var quickSort = function(nums){
    var len = nums.length;
    if(len<2) return nums;
    var pivot = nums[Math.floor(len/2)];
    var left = 0,right = nums.length-1;
    var temp = 0;
    while(left!=right){
        if(nums[left]<pivot) left++;
        if(nums[right]>pivot) right--;
        temp = nums[right];
        nums[right] = nums[left];
        nums[left] = temp;
    }
    quickSort(nums.slice(0,left));
    quickSort(nums.slice(right,len));
    return nums;
}

var e=quickSort(num);
console.log(e);


全部评论

相关推荐

2 4 评论
分享
牛客网
牛客企业服务