leetcode 912 排序树组 JavaScript

leetcode 912 排序树组 JavaScript
在这里插入图片描述
快速排序思路:
首先定义left和right分别指向要遍历数组的头和尾,并设置基数pivot作为参照,把所有比pivot大的数放在pivot的右边,把所有比pivot小的数放pivot左边。
假设基数均为当前遍历数组的最左边left的值(nums[left])
如果想设置其他值为pivot,需要把该值移到最左边。
①首先从right开始向左遍历,当找到比pivot小的数之后,将right的值放到left中,之后right暂停遍历,轮到left
②左边从left+1开始遍历,当找到比pivot大的数之后,将left的值放到right中,之后left暂停遍历,轮到right
③重复 ①②,直到left>=right,本轮遍历结束 之后就会形成左边:比pivot小的数,pivot,右边:比pivot大的数 接下来将左边、右边的数组继续进行相同的操作,直到排序完成。
举例:
5 2 3 1 初始left == 0,right == 3,pivot == 5
从1开始向左遍历,发现1<5,此时将1放到下标left的位置,形成1 2 3 1,right暂停遍历
下一步left++,从2开始遍历,2<5,继续遍历,3<5,继续遍历,此时left和right重合了,将pivot放到重合位置,本次遍历完成,结果为1 2 3 5
之后是对基数位置的左边数组、右边数组分别执行相同的操作,发现右边没数组了,右边完成,左边为1 2 3 ,继续按上述步骤执行…直到左边完成遍历。
代码如下:

var sortArray = function(nums) {
    if(nums.length==0||nums.length==1) return nums;
    return quickSort(nums,0,nums.length-1);
};
function quickSort(nums,L,R){
    if(L>=R) return nums;
    let left = L;
    let right = R;
    let pivot = nums[left];//基准
    while(left<right){
        while(left<right&&nums[right]>pivot){
            right--;
        }
        if(left<right){
            nums[left++]=nums[right];
        }
        while(left<right&&nums[left]<pivot){
            left++;
        }
        if(left<right){
            nums[right--]=nums[left];
        }
    }
    nums[left] = pivot;
   
   quickSort(nums,L,left-1);
   quickSort(nums,left+1,R);
   return nums;
}

上述代码是完全按照快速排序的图解实现的,也就是当right动的时候,left不动,操作完之后,left才动。left动的时候right不动。

接下来还有一种(partition),left和right分别进行移动直到两边都停住,然后交换left和right的值,同样是直到left和right擦肩而过时遍历结束(耗时较长,不贴了)

还有一种实现思路,就是设基准之后,直接给它进行对应的左右放置,大的丢到基准右边,小的丢到基准左边。然后分别对两边执行相同的操作,详情见阮一峰JavaScript实现快速排序。

归并排序思路:
首先是递归分解,每次拆一半,直到拆分到长度1停止,之后将拆分的元素合并,合并完成后完成排序

var sortArray = function(nums) {
    if(nums.length==0||nums.length==1) return nums;
    let left = 0;
    let right = nums.length-1;
    let temp = [];
    mergeSort(nums,left,right,temp);
    return nums;
};
function mergeSort(nums,left,right,temp){
    if(left<right){
        let mid = Math.floor(left+(right-left)/2);
        mergeSort(nums,left,mid,temp);//左递归分解
        mergeSort(nums,mid+1,right,temp);//右递归分解
        merge(nums,left,mid,right,temp);//合并
    }
}
function merge(nums,left,mid,right,temp){
    let i = left;
    let j = mid+1;
    let t = 0;//temp数组的索引
    while(i<=mid&&j<=right){//这里比较两边指针的大小,一个个放入temp中,哪边先遍历完成则结束
        if(nums[i]>=nums[j]){
            temp[t++] = nums[j++]
        }
        else temp[t++] = nums[i++]
    }
    //下面两个while是确保刚刚结束后剩余的另外一个有序数组也遍历完放入temp中
    while(i<=mid){
        temp[t++] = nums[i++]
    }
    while(j<=right){
        temp[t++] = nums[j++]
    }
    t = 0;//重新置0
    let tempLeft = left;//拷贝left到right的内容到nums
    while(tempLeft<=right)//将temp内容拷贝到nums
     nums[tempLeft++] = temp[t++]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值