题目描述 - 数组排序
给你一个整数数组 nums,请你将该数组升序排列。
思路分析
数组排序应该算是最常见的算法题了,方法也有很多。比如最常用的冒泡排序、二分法等。
- 冒泡排序:实现思路是通过相邻元素之间的比较与交换,使值较小的元素逐步从后面移到前面,值较大的元素从前面移到后面。执行演示如下:
数组arr=[5,3,2,4]进行冒泡排序
第一轮 i = 0;j = 0;j 位置与 j+1 位置比较,j++; j<3(0,1,2)
[3,5,2,4] 0,1 比较
[3,2,5,4] 1,2 比较
[3,2,4,5] 2,3 比较
通过第一轮比较, 已经将最大的数挪至了最右端, 所以第二轮就不需要比较最后一个数了
第二轮 i = 1;j = 0;j 位置与 j+1 位置比较,j++; j<2(0,1)
[2,3,4,5] 0,1 比较
[2,3,4,5] 1,2 比较
第三轮 i = 2;j = 0;j 位置与 j+1 位置比较,j++; j<1(0)
[2,3,4,5] 0,1 比较
根据上面的排序流程分析: 长度为 n 的数组,完成排序,需要 n-1 个循环,我们用外层的变量 i 控制 每次循环,每个元素都需要与数组其他元素进行对比,因此,长度为 n 的数组,需要比较 n-1 次,我们用 j 控制。
代码实现:
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
for(let i=0; i<nums.length-1; i++){
for(let j=0; j<nums.length-i-1; j++){
if(nums[j] > nums[j+1]){
[nums[j], nums[j+1]] = [nums[j+1], nums[j]]
}
}
}
return nums
};
- 快排:通过一次排序将无序的数组分为独立的两个无序数组,第一个数组的值均比第二个数组的值小。然后递归地排列两个子数组,以达到整个数组有序。
数组arr=[5,3,2,4]进行快排
第一轮排序
初始数组 [5,3,2,4] 第一轮分组 i = 0,以 5 为坐标分两组, 分组结果为[3,2,4] 和 []
第二轮排序
对左侧数组 [3,2,4] 和 右侧数组[] 进行二次排序
左侧数组以 3 为坐标进行排序,排序结果为 [2] 和 [4]
右侧为空数组
第三轮排序
对上一轮排序结果生成的三个数组进行排序[2] [4] [], 数组长度为1 或为空时,结束递归。
代码实现:
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
if(nums.length <= 1) return nums
let mid = nums[0]
let left = [], right = []
for(let i=1; i<nums.length; i++){
let item = nums[i]
if(item<mid) left.push(item)
else right.push(item)
}
return sortArray(left).concat([mid]).concat(sortArray(right))
};