【面试刷题】两种排序算法
一、快速排序
1、思路步骤
- 选取中心轴pivot。
- 将小于Pivot,大于pivot的两个值进行交换。
- 对pivot左半部分,pivot右半部分再次进行上述步骤。
2、LeetCode-912.排序数组
3、代码实现
class Solution {
public int[] sortArray(int[] nums) {
//进行异常处理
if (nums == null || nums.length == 0)
return nums;
quickSort(nums, 0, nums.length-1);
return nums;
}
private void quickSort(int[] nums, int start, int end) {
//处理输入
if (start >= end) return;
//初始化
int left = start;
int right = end;
//选取pivot
int pivot = nums[(start + end) / 2];
//循环处理
while (left <= right) {
while (left <= right && nums[left] < pivot)
left++;
while (left <= right && nums[right] > pivot)
right--;
//找到了一个left和right需要调换
if (left <= right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
//处理左和右,由于此时left已经大于了right,所以如下
quickSort(nums, start, right);
quickSort(nums, left, end);
}
}
此处要注意,循环处理时候的left<=right是小于等于,如果是小于,可能会发生栈溢出的情况(会产生交集)如:3、2、1、4、5。
二、归并排序
1、思路详解
归并排序,递归分治。
2、代码实现
class Solution {
public int[] sortArray(int[] nums) {
//进行异常处理
if (nums == null || nums.length == 0)
return nums;
int[] temp = new int[nums.length];
mergeSort(nums, 0, nums.length-1, temp);
return nums;
}
private void mergeSort(int[] nums, int start, int end, int[] temp) {
if (start >= end)
return;
//先把数组拆分,分治的分。
mergeSort(nums, start, (start + end) / 2, temp);
mergeSort(nums, (start + end) / 2 + 1, end, temp);
merge(nums, start, end, temp);
}
private void merge(int[] nums, int start, int end, int[] temp) {
int mid = (start + end) / 2;
int leftIndex = start;
int rightIndex = mid + 1;
int index = leftIndex;
//将左边部分和右边部分放入temp
while (leftIndex <= mid && rightIndex <= end) {
if (nums[leftIndex] < nums[rightIndex]){
temp[index++] = nums[leftIndex++];
} else {
temp[index++] = nums[rightIndex++];
}
}
//存在左边和右边部分还有剩余的情况
while (leftIndex <= mid) {
temp[index++] = nums[leftIndex++];
}
while (rightIndex <= end) {
temp[index++] = nums[rightIndex++];
}
//这一步很关键,注意是start和end,而不是0和nums.length,因为这是分治,是最小的两个单元。
for (int i = start; i <= end; i++){
nums[i] = temp[i];
}
}
}