基于六大基本排序的学习:
快速排序
废话不多说直接上代码
void quick_sort(int left,int right,int* arr)
{
if(left >= right)
return;
int i = left;
int j = right;
int base = arr[left];
while(i < j)
{
while(arr[j] >= base && i < j)
j--;
while(arr[i] <= base && i < j)
i++;
if(i < j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
arr[left] = arr[i];
arr[i] = base;
quick_sort(left,i-1,arr);
quick_sort(i+1,right,arr);
}
然后我们一步一步解析理解:
首先是形参,形参内我们运用left,right来指向数组的开始与结束端。
然后是函数体内:
由于快排应用的是递归算法,所以要有一个递归的出口,即当最左端大于等于最右端时,函数就从此截止,然后依次结束之前的递归。
然后找一个i和j使其分别等于left与right,再找一个“准基数”,这里我们常用的准基数就是arr[left],然后就是进行最主要的算法。
首先的大循环条件是当 i < j,这里的意思最左端不能等于或超过最右端,其实是为了i == j作铺垫,然后小循环中***一定要先进行 j-- 的操作***。
j–的操作条件就是从这个数组的right开始,从后向前遍历找到一个小于等于准基数base的数值***并且要求此时的 j >= i***,然后停留在此;
i++的操作条件与其类似,不过是找到一个大于等于准基数base的数,并且要求此时的 i <= j ,然后停留在此。然后判断此时的 i 是否真的小于 j,如果判断为真的话,将位于 i 和位于 j 位置上的数值交换。重复上述步骤,直到 i == j,然后进行数组起始端数值的改变,将arr[i](或arr[j],因为此时i == j) 赋值给arr[left],再将base赋值给当前的aa[i]。然后进行向左和向右的递归操作。
给个例题
#include<iostream>
using namespace std;
void quick_sort(int left,int right,int* arr)
{
if(left >= right)
return;
int i = left;
int j = right;
int base = arr[left];
while(i < j)
{
while(arr[j] >= base && i < j)
j--;
while(arr[i] <= base && i < j)
i++;
if(i < j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
arr[left] = arr[i];
arr[i] = base;
quick_sort(left,i-1,arr);
quick_sort(i+1,right,arr);
}
int main()
{
const int n = 10;
int a[n];
for(int i = n-1;i>=0;i--)
{
a[i] = i*i - 3*i + 3;
}
for(int i = 0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
quick_sort(0,n-1,a);
for(int i = 0;i<n;i++)
cout<<a[i]<<" ";
}
得出的结果是
我现在只解释一下第一次循环
首先base = arr[left] = 3;
然后i = 0,j = n - 1 = 9;
从j开始从后往前遍历
j一直减到了2
然后i开始从前往后遍历,当i等于2时虽然没找到大于等于base的数,但由于i再增加导致了i > j,所以i只停留在了2处。然后此时不满足了i < j,所以直接进行arr[left] = a[i]; a[i] = base;的操作,然后进行左右递归,最后发现(也是巧合原因)这个数组只需要进行一次排序即可。