题目
给你一个整数数组 nums,请你将该数组升序排列。
示例
示例1
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
示例2
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
题目分析
使用快速排序来解决这道题,借助这道题我帮助自己梳理一下快速排序的过程。
快速排序的大概过程是,选择一个枢纽元素(pivot
),然后从后向前遍历数组,如果遇到比枢纽元素小的,则交换;然后从前向后遍历,如果遇到比枢纽元素大的,则交换。直到数组分划分为两个部分:枢纽元素前的部分都小于枢纽元素,枢纽元素后的部分都大于枢纽元素。上面的过程叫做一趟快速排序。
剩余的部分,与上面类似,递归的完成即可。
下面以num = [46,79,56,38,40,84]
这组数为例,展示一趟快速排序的过程。
- 首先选择一个枢纽,一般是数组首元素,
pivot = 46
,规定前后指针low = 0, high = 5
; - 从后向前遍历,发现
40
小于枢纽元素,令high = 4,num[low] = num[high]
,此时的数组为[40,79,56,38,40,84]
; - 从前向后遍历,发现
79
大于枢纽元素,令low = 1,num[high] = num[low]
,此时的数组为[40,79,56,38,79,84]
; - 从后向前遍历,发现
38
小于枢纽元素,令high = 3,num[low] = num[high]
,此时的数组为[40,38,56,38,79,84]
; - 从前向后遍历,发现
56
大于枢纽元素,令low = 2,num[high] = num[low]
,此时的数组为[40,38,56,56,79,84]
; - 此时的
low = 2,high = 3
,令num[low] = pivot
,一趟快速排序结束,此时的数组为[40,38,46,56,79,84]
。
上面一趟排序的过程代码如下:
int Partition(int* nums, int low, int high){
int pivot = nums[low];
while (low < right){
// 从后向前
while (low < high && nums[high] >= pivot) high--;
nums[high] = nums[low];
// 从前向后
while (low < high && nums[low] <= pivot) low++;
nums[low] = nums[high];
}
nums[low] = pivot;
return low;
}
完成一趟快速排序之后,数组被划分为了两部分,将剩余的部分用分治法递归完成:
void QuickSort(int* nums, int low, int high){
if (low < high){
int pivot = Partition(nums, low, high);
QuickSort(nums, low, pivot - 1);
QuickSort(nums, pivot + 1, high);
}
}
至此,快速排序完成。
题目解答
int Partition(int* nums, int low, int high){
int pivot = nums[low];
while (low < high){
while (nums[high] >= pivot && low < high) high--;
nums[low] = nums[high];
while (nums[low] <= pivot && low < high) low++;
nums[high] = nums[low];
}
nums[low] = pivot;
return low;
}
void QuickSort(int* nums, int low, int high){
if (low < high){
int pivot = Partition(nums, low, high);
QuickSort(nums, low, pivot - 1);
QuickSort(nums, pivot + 1, high);
}
}
int* sortArray(int* nums, int numsSize, int* returnSize){
*returnSize = numsSize;
QuickSort(nums, 0, numsSize - 1);
return nums;
}