目录
快速排序(我们说的都是升序,降序就把符号反过来)
填坑法!
假如说我现在有数组{ 5,1,4,7,8,2,3,6,9,0 },将begin指向5的索引(数组中第一个索引),end指向0的索引(数组中最后一个位置),先挖了第一个数当坑,然后被挖的数我们当作关键数
我们通过控制begin和end的移动,让begin往右走,left往左走来进行一系列的交换,让关键数放到begin=end的位置
最后我们想要的结果是这样的
关键数的左边都是比5要小,关键数右边都比5要大,那经过怎么个流程才能达到这种效果呢?
流程:因为我们先挖的最左边的数,我们就先动右边的end,让end往左边走,找比5要小的数,放到坑中
放进去之后,我们发现end的地方就会出现坑,那我们就动begin,让begin往左边走找比关键数大的数放到坑中
放进去begin的位置就会出现坑,那就让end往前走去找比关键数小的数去填坑,总之如果begin出现坑那就让end找比key小的数填,end出现坑那就让begin找比关键数大的数去填
最后begin会和end重合,把key放到begin和end重合的位置
我们看代码
void QuickSort(int* a, int n)
{
int begin = 0;
int end = n - 1;
int key = a[begin];
int privot = begin;
while (begin < end)
{
while (begin<end&&a[end] > key)
{
end--;
}
privot = end;
a[begin] = a[end];
begin++;
while (begin < end && a[begin] < key)
{
begin++;
}
privot = begin;
a[end] = a[begin];
end--;
}
a[begin] = key;
}
我们用递归来实现两边的
#include<iostream>
using namespace std;
void QuickSort(int* a, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right - 1;
int key = a[begin];
int privot = begin;
while (begin < end)
{
while (begin<end && a[end] > key)
{
end--;
}
a[begin] = a[end];
privot = end;
//begin++;
while (begin < end && a[begin] < key)
{
begin++;
}
a[end] = a[begin];
privot = begin;
//end--;
}
a[begin] = key;
privot = begin;
QuickSort(a, left, privot);
QuickSort(a, privot + 1, right);
}
int main()
{
int a[] = { 5,1,4,7,8,2,3,6,9,0 };
int n = sizeof(a) / sizeof(int);
QuickSort(a, 0, n);
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
return 0;
}
key的官方给值的方法是三数取中(左边,右边,中间排好序之后取中间的数)
前后指针法
假如说我们有一个数组{4,5,9,8,7,6,3,0,1,2},我们进行排序,先说一下什么是前后指针排序,顾名思义就是设置一个快指针和一个慢指针
我们设置cur为快指针,prev为慢指针,cur每回往前走一步,如果找到比key小的数,就让prev+1之后和cur交换位置,知道cur超出数组范围之后就结束,然后让key和prev指向元素互换位置
我们来模拟一遍这个过程
cur往前找到了比key小的数了
prev+1,然后进行元素互换
交换完位置后
然后接着让cur往前走,找下一个比key小的数,重复上面的操作,下面是我们cur走到数组末尾的图
然后让prev和key交换位置
这就是前后指针来进行第一趟排序
然后我们看代码
#include<iostream>
using namespace std;
void Swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void QuickSort(int* a, int n)
{
int begin = 0;
int cur = begin;
int prev = begin;
int key = a[begin];
cur += 1;
while (cur < n-1)
{
while (a[cur] > key)
{
cur++;
}
prev++;
Swap(&a[prev], &a[cur]);
}
Swap(&a[prev], &a[begin]);
}
int main()
{
int a[] = { 4,5,9,8,7,6,3,0,1,2 };
int n = sizeof(a) / sizeof(int);
QuickSort(a, n);
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
return 0;
}
单向扫描排序
#include<iostream>
#include<stdlib.h>
#include<stdbool.h>
#include<string>
#include<vector>
using namespace std;
//快排:单向扫描
void Swap(int* a, int* b)//交换两个值的函数
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition(int* a, int p, int r)//一次扫描函数
{
int key = a[p];
int pivot = p;
int scanner = p + 1;
int bigger = r;
while (scanner <= bigger)//让一个scanner往前扫描
{
if (a[scanner] <= key)//如果扫描的值小于key值,
//我们让scanner指针向后走一个
{
scanner++;
}
else if (a[scanner] > key)//如果扫描的值大于key值
{
Swap(&a[scanner], &a[bigger]);//交换元素
//我们把比key大的元素放到右边
bigger--; //bigger向前移动一位
}
}
Swap(&a[p], &a[bigger]);
return bigger;
}
void QuickSort(int* a, int p, int r)
{
if (p < r)
{
int q = partition(a, p, r);
QuickSort(a, q + 1,r);
QuickSort(a, p, q - 1);
}
}
int main()
{
int a[] = { 7,8,5,4,1,3,6,2,9,0 };
int n = sizeof(a) / sizeof(int);
QuickSort(a, 0, n - 1);
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
return 0;
}