在大一的时候跟着啊哈算法写过,可惜后来忙着写力扣,就给忘了,最近面试频繁被问道,自己也不会了,现在来回忆一波
假设现在对一个数组进行排序数组定义如下
vector<int> vec = {6,1,2,7,9,3,4,5,10,8};这是个数进行排序
1.首先在这个序列中随便找一个数字作为基准数,就选择数字6作为基准数吧。
2.接下来需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似于下面这种情况
vec = {3,1,2,5,4,6,9,7,10,8};
在初始状态下,数字6在序列的第一位。当前的目标是将6移动到序列的中间某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数字都小于6,右边的数字都大于6。
冒泡排序是通过相邻位置的元素的交换来实现让每个数字进行归位操作的
那么该如何做到这点呢?
分别从初始序列[6,1,2,7,9,3,4,5,10,8]开始进行探测。先从右往左找第一个大于6的数字,再从左往右找第一个小于6的数字,然后交换它们。这里可以使用两个变量i和j,分别指向最左边和最右边。刚开始的时候让i指向6,让j指向8
首先让j进行递减操作,知道找到第一个小于6的数字停下来。接下来让i++直到找到第一个大于6的数字停下来然后进行交换操作此时的序列为
6,1,2,*5*,9,3,4,*7*,10,8
到此,第一次交换结束,接下来i--,j++然后再次进行交换
6,1,2,5,4,3,8,7,10,8
第二次交换结束之后继续i--,j++操作
3,1,2,5,4,6,9,7,10,8
此时第一轮结束,以6为基准左边的数字都小于6,右边的数字都大于6,但是是乱序的
所以以6为基准将其拆分成两个序列
左边的序列是3,1,2,5,4 右边的序列是9,7,10,8。接下来要对两组序列进行分别的排序处理操作
3,1,2,5,4的处理方法和上面一致,以3为基准,将小于3的数字放到左边,将大于3的数字放到右边处理后的结果是 2,1,3,5,4
然后再以三为基准进行拆分,然后再进行排序操作
快速排序代码如下
void quickSort(int left,int right, vector<int>& arr)
{
if (left >= right)
return;
int i,j,base,temp;
i = left,j = right;
base = arr[left];
while (i < j) {
while (arr[j] >= base && i < j) j--;
while (arr[i] <= base && i < j) i++;
if (i < j)
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
arr[left] = arr[i];
arr[i] = base;
quickSort(left, i - 1, arr);
quickSort(right, i + 1, arr);
}
}
润去干饭 回来面试