快速排序是一种分区间交换排序的方法,基本思路是,在数组中确定一个对比值,一般为区间中的第一个,然后初始定义first=0和 last=n-1,将大于对比值的数放在右边,小于的放在左边,然后可以利用递归把左右区间再次进行上面的操作。
如下图:
开始以第一个数28为关键字,那么:
第二行;在第一行中,50大于28,–last; 然后20小于28,将20移到第一行中first的位置,即arr[first]=arr[last](这里可以把红字部分所在的位置看成是空的,因为28已经被事先记录了),注意,赋值后last没有变化。然后由first所在的循环继续。
第三行;在第二行中,左边19小于28,然后27小于28,此时first的值为3(first从1开始),然后48大于28,在第二行中红字部分为空,且last的值正好是红字的下标相同,arr[last]=arr[first],此时48原来的位置空了出来。然后有last所在的循环继续。
第四第五行同理。
注意,每当执行一次arr[first]=arr[last]或者arr[last]=arr[first]后,对应的while(first < last && arr[last] >= key)或fwhile(first < last && arr[first] <= key)循环都会至少执行一次,first或者last的值一定会发生变化,除了最后一次first=last。
最后一行中,参考倒数第二行,12小于28, ++first,于是key的位置=first=last,这样就确定了28的位置,再把28赋值给first或者last.
下面是代码:
#include <iostream>
#include <stdio.h>
const int maxn = 1000+10;
int arr[maxn];
using namespace std;
void Qsort(int arr[], int low, int high)
{
if(low >= high) return; /*递归停止条件*/
int first = low;
int last = high;
int key = arr[first]; /*用当前区间的第一个数作为比较值*/
while(first < last)
{
while(first < last && arr[last] >= key)
{
--last;
}
arr[first] = arr[last]; /*移动到左区间*/
while(first < last && arr[first] <= key)
{
++first;
}
arr[last] = arr[first]; /*移至右区间*/
}
arr[first] = key; /*最后重新插入对比值*/
Qsort(arr, low, first-1); /*左区间递归排序*/
Qsort(arr, first+1, high); /*右区间递归排序*/
}
int main()
{
int n;
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
while(cin>>n){
for(int i=0;i<n;i++)
cin>>arr[i];
Qsort(arr, 0, n-1); /*存储在从0到n的数组中*/
for(int i = 0; i < n; i++)
cout << arr[i] << " ";
cout<<endl;
}
return 0;
}
如有不对,欢迎指出。