快速排序复习
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序复习相关的知识,希望对你有一定的参考价值。
基本思想;类似于归并排序的分治思想,
但是 在快速排序中会将数组中的元素 小的放一边,大的放一边;排序即完成;
找切分点,假设数组的第一个元素作为切分点,然后和后面的元素进行比较,
只要比当前这个切分点元素小的,就向前交换, 直到数组末尾;再将切分点放到它的指针指向的合适位置;
此时得到一个基于切分点分开的两块区域, 左侧元素普遍小于切分点元素值;右侧元素普遍大于切分点元素值;
此时按照第一个切分,逐次向左向右进行递归;最终在一个一个切分点的作用下,其实就完成了排序;
在912. 排序数组题目中测试
class Solution
public int[] sortArray(int[] nums)
int n = nums.length;
if(n < 2) return nums;
quickSort(nums,0,n-1);
return nums;
private void quickSort(int[] nums,int left,int right)
//递归结束条件;
if(right - left <= 7)
//使用插入排序;
useInsertSort(nums,left,right);
return;
//找到合适的分隔点;
int segIndex = getSegIndex(nums,left,right);
//递归;
quickSort(nums,left,segIndex - 1);
quickSort(nums,segIndex+1, right);
//使用分隔点将左右两边的元素 完成一轮区分;
private int getSegIndex(int[] nums,int left,int right)
//一般用首节点;
int segVal = nums[left];
//指针j,用来在比较时的元素交换;
int j = left;
for(int i = left+1;i<=right;i++)
//仅将小元素向前换;
if(segVal > nums[i])
j++;
swap(nums,i,j);
//最后将首节点的元素放到合适的位置;
swap(nums,left,j);
return j;
//插入排序;
private void useInsertSort(int[] nums,int left,int right)
//插入排序由第2个元素开始;
for(int i=left+1;i<=right;i++)
//使用临时变量;
int temp = nums[i];
int j = i;
for(;j>left;j--)
if(nums[j-1]>temp)
nums[j] = nums[j-1];
else
break;
nums[j] = temp;
//交换元素;
private void swap(int[] nums,int a,int b)
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
优化;如果一直用数组的头一个元素作为切分点时,可能出现某些测试用例的特殊情况,影响执行效率;
那么可以每次找一个随机的节点作为切分点;
class Solution
public int[] sortArray(int[] nums)
int n = nums.length;
if(n < 2) return nums;
quickSort(nums,0,n-1);
return nums;
private void quickSort(int[] nums,int left,int right)
//递归结束条件;
if(right - left <= 7)
//使用插入排序;
useInsertSort(nums,left,right);
return;
//找到合适的分隔点;
int segIndex = getSegIndex(nums,left,right);
//递归;
quickSort(nums,left,segIndex - 1);
quickSort(nums,segIndex+1, right);
//使用一个规定的随机数对象;
private final Random R = new Random();
//使用分隔点将左右两边的元素 完成一轮区分;
private int getSegIndex(int[] nums,int left,int right)
//找一个随机的节点作为切分点;
int ran =left + R.nextInt(right - left +1);
swap(nums,left,ran);
//这里的切分点实际就是交换后的随机节点的值;
int segVal = nums[left];
//指针j,用来在比较时的元素交换;
int j = left;
for(int i = left+1;i<=right;i++)
//仅将小元素向前换;
if(segVal > nums[i])
j++;
swap(nums,i,j);
//最后将首节点的元素放到合适的位置;
swap(nums,left,j);
return j;
//插入排序;
private void useInsertSort(int[] nums,int left,int right)
//插入排序由第2个元素开始;
for(int i=left+1;i<=right;i++)
//使用临时变量;
int temp = nums[i];
int j = i;
for(;j>left;j--)
if(nums[j-1]>temp)
nums[j] = nums[j-1];
else
break;
nums[j] = temp;
//交换元素;
private void swap(int[] nums,int a,int b)
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
用时直接缩减好多;
之前学习的双指针法快排,在这道题中运算,效率不太行;
学习数据结构笔记(6)====>八大排序算法(Sort Algorithm)[冒泡,选择,插入,快速,希尔,基数,归并,堆排序]
class Solution
public int[] sortArray(int[] nums)
int n = nums.length;
if(n < 2) return nums;
//定义临时数组;
return quickSort(nums,0,n-1);
/**
* 快速排序
* @param array 需要排序的数组
* @param left 左指针
* @param right 右指针
* @return 排序后的数组
*/
public static int[] quickSort(int[] array,int left,int right)
//先把左右指针提前存起来;
int l = left;
int r = right;
//找到中心点;
int bottom = array[(left +right)/2];
System.out.println("当前中心轴值-->"+bottom);
//左指针 和 右指针向中心移动;
while (l < r)
//左右指针移动;
while (array[l] < bottom)
l+=1;
while (array[r] > bottom)
r-=1;
//跳出循环的条件;
if(l>=r)
break;
//先进行交换;
int temp =array[l];
array[l] = array[r];
array[r] = temp;
//考虑接近到达中心点的情况;
if(array[l] == bottom)
r-=1;
if(array[r] == bottom)
l+=1;
//还需考虑两指针相遇的情况;
if(l == r)
l+=1;
r-=1;
//向左递归;
if(left<r)
quickSort(array,left,r);
//向右递归;
if(right>l)
quickSort(array,l,right);
return array;
以上是关于快速排序复习的主要内容,如果未能解决你的问题,请参考以下文章