快速排序(用处最广,面试提问最多)
原理:(以从大到小排列为例)设置一个基准值(默认数组第一个元素),两个哨位,这两个哨位作用就是用来判断当前位置的值和基准值的大小。nLeft为左哨位,nRight为右哨位,第一步先从右哨位出发,寻找到第一个比基准值小的值,记录当前位置,然后再从左哨位出发,找出第一个比基准值大的值,记录位置,再将左右哨位值互换,然后继续前进,直到左右哨位相遇,跳出循环,将相遇位置的值和基准值做互换,就完成了第一轮排序,基准值左侧全部比基准值小,右侧全部比基准值大。
完成第一轮排序之后再对左侧元素递归地进行下一轮排序,直到排序的序列左端大于等于右端(Left >= Right)
//从小到大排序
void quicksort(vector<int>& nums, int Left, int Right)
{
//Left < Right时才需要做比较,若Left = Right则说明只有一个数,不需要做比较
if (Left >= Right)
return;
int nBase = nums[Left], nLeft = Left, nRight = Right; //基准值(默认最左侧值)
while (nLeft < nRight)
{
while (nBase >= nums[nRight] && nLeft < nRight) //从右往左寻找比基准值小的(若从大到小排序则相反)
nRight--;
while (nBase <= nums[nLeft] && nLeft < nRight) //从左往右寻找比基准值大的(若从大到小排序则相反)
nLeft++;
//将上述两个值做交换
int nTemp = nums[nLeft];
nums[nLeft] = nums[nRight];
nums[nRight] = nTemp;
}
//将将相遇位置的值和基准值做互换(此时nLeft == nRight)
nums[Left] = nums[nLeft];
nums[nLeft] = nBase;
quicksort(nums, Left, nLeft - 1);
quicksort(nums, nLeft + 1, Right);
}