交换排序交换排序分为快速排序和冒泡排序,就是根据序列中两个值的比较结果来对换这两个数在序列中的位置,特点就是较大值向尾部移动,较小值向前部移动。
快速排序基本思路为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两个子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值。然后采用分治的思想,把一个问题变成两个同样小问题(用递归去解决)。
//进行找基准值,代码如下面的框栏所示。
//进行递归操作
void _QuickSort(int array[], int left, int right)
{
//分出来的小区间里面有一个值或没有值说明区间内没有数了,递归也就结束了
if (left >= right){
return;
}
//定义一个基准值
int div = Parition(array, left, right);
//进行递归去排序
_QuickSort(array, left, div - 1);
_QuickSort(array, div + 1, right);
}
void QuickSort(int array[], int size)
{
_QuickSort(array, 0, size - 1);
}
找基准值法1:hoare版本:基本思路:先将右边的值作为基准值,用两个指针,第一个开始指向头,第二个指向尾,第一个往右走,第二个往左边走,当第一个遇见比基准值大的停下来,第二个遇见比基准值小的停下来,然后交换两个数。直到两个指针同时指向同一个数,则将其与基准值交换,然后返回这两个指针其中一个即可。
void Swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int Parition_1(int array[], int left, int right)
{
int begin = left;
int end = right;
while (begin < end){
//开始将最右边的值定为基准值
while (begin < end&&array[begin] <=array[right]){
begin++;
}
while (begin < end&&array[end] >= array[right]){
end--;
}
//交换两个数值
Swap(&array[begin], &array[end]);
}
//这是begin和end已经走到同一个元素上面,所有将其和基准值进行交换
Swap(&array[begin], &array[right]);
return begin;
}
找基准值法2:挖坑法:基本思路:将最右边的值作为基准值,然后将其取下来。然后,用两个指针,第一指针从右往左走,遇见比它大的停下来,将这个值去覆盖基准值。第二个指针从左边往右边走,遇见比它小的停下来,用这个值去覆盖刚才那个值。最后,循环结束此时第一个指针和第二个指针指向同一个元素,将其与基准值交换,然后返回这两个指针其中一个即可。
int Parition_2(int array[], int left, int right)
{
int begin = left;
int end = right;
int pivot = array[end];
while (begin < end){
while (begin < end&&array[begin] <= array[right]){
begin++;
}
array[end] = array[begin];//去覆盖
while (begin < end&&array[end] >= array[right]){
end--;
}
array[begin] = array[end];//去覆盖
}
//走到这里说明begin和end指向同一个值了
array[begin] = pivot;
return begin;
}
找基准值法3:前后指针版本:基本思想:用两个指针开始都指向left,然后循环其中一个指针,当它遇见比自己小的就和第二个指针进行交换,第二个指针在这个循环内部进行自加操作。最后循环完毕,交换第二个指针与right的值,然后返回第二个指针。
int Parition_3(int array[], int left, int right)
{
//这里i遇见比他小的停下来,d遇见比他大的停下来
int d = left;
for (int i = 0; i < right; i++){
if (array[i] < array[right]){
Swap(&array[i], &array[d]);
d++;
}
}
Swap(&array[d], &array[right]);
return d;
}
快速排序的特点总结:时间复杂度O(n*logn),空间复杂度O(logn),并且其不稳定。但快排的整体的综合性能和使用场景都比好。