快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
这个分割不一定是均等分割,意思就是,假如这个数组一共有16个元素,不一定是分割成8和8两个数组,也有可能是1和15两个数组。
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
#include<iostream>
using namespace std;
void QSort(int arr[],int begin,int end)
{
//如果起始位置≥终点位置,那么就应该结束函数了
//因为在>的情况下,那是不合理;在=的情况下,只有一个元素,所以也不用排了
if(begin>=end)
{
return;
}
int first=begin,last=end;
//以11,4,7,8,43,2,56,23,8,1,3,9为例,介绍这个while
//这里是以第一个元素分分割点。
//目标是把比key小的都放在key的左边比key大的都放在key的右边
//整个快速排序算法,最最最重要,也是最最最难理解的地方就是这个while
int key=arr[first];
while(first<last)
{
//这个while的作用是从最右端开始,向左找,一直到有比arr[first]小的元素,然后停止
while(first<last&&arr[last]>=key)
{
last--;
}
//停止后,立马把从右到左第一个比key小元素赋给arr[first]
arr[first]=arr[last];
//这个while的作用是从最左端开始,向右找,一直到有比arr[first]大的元素,然后停止
while(first<last&&arr[first]<=key)
{
first++;
}
//停止后,立马把从左到到第一个比key大元素赋给arr[last]
arr[last]=arr[first];
}
arr[first]=key;
//演示第一轮:原数组为11,4,7,8,43,2,56,23,8,1,3,9,key值为11,
//从右往左,比较到9<11,此时last为11,arr[first]=arr[last], 所以9,4,7,8,43,2,56,23,8,1 ,3,9
//从左往右,比较到43>11,此时first为4,arr[last]=arr[first],所以9,4,7,8,43,2,56,23,8,1 ,3,43
//从右往左,比较到3<11,此时last为10,arr[first]=arr[last], 所以9,4,7,8,3 ,2,56,23,8,1 ,3,43
//从左往右,比较到56>11,此时first为6,arr[last]=arr[first],所以9,4,7,8,3 ,2,56,23,8,1 ,56,43
//从右往左,比较到1<11,此时last为9,arr[first]=arr[last], 所以9,4,7,8,3 ,2,1 ,23,8,1 ,56,43
//从左往右,比较到23>11,此时first为7,arr[last]=arr[first],所以9,4,7,8,3 ,2,1 ,23,8,23,56,43
//从右往左,比较到8<11,此时last为8,arr[first]=arr[last], 所以9,4,7,8,3 ,2,1 ,8 ,8,23,56,43
//从左往右,比较到8<11,此时first为8,arr[last]=arr[first], 所以9,4,7,8,3 ,2,1 ,8 ,8,23,56,43
//不满足 first<last, 所以跳出循环
//执行 arr[first]=key,所以9,4,7,8,3 ,2,1 ,8 ,11,23,56,43
//上面的while循环完及执行完赋值语句之后,得到的效果是
//比arr[first]小的都排在它的左边, 比arr[first]大的都排在它的右边
/* for(int i=0;i<12;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
*/
/* 原数组为 11,4,7,8,43,2,56,23,8,1,3,9
你可以把上面的输出语句的注释去掉,这样就可以得到很多行数据如下:
9 4 7 8 3 2 1 8 11 23 56 43 比11小的都排在它的左边, 比11大的都排在它的右边
8 4 7 8 3 2 1 9 11 23 56 43 对上一行数据key值11左边的数据也就是9 4 7 8 3 2 1 8进行排序,选择9为key值
比9小的都排在它的左边, 比9大的都排在它的右边,
1 4 7 8 3 2 8 9 11 23 56 43 对上一行数据key值9左边的数据也就是8 4 7 8 3 2 1进行排序,选择8为key值
比8小的都排在它的左边, 比8大的都排在它的右边
注意这里有点特殊,因为有两个8,所以可能会有读者觉得我上面那一句话不对,
要注意我说的8是 1 4 7 8 3 2 8 里最右边的那个8.
1 4 7 8 3 2 8 9 11 23 56 43 对上一行数据key值8左边的数据也就是1 4 7 8 3 2进行排序,选择1为key值
比1小的都排在它的左边, 比1大的都排在它的右边
1 2 3 4 8 7 8 9 11 23 56 43 本来应该对上一行数据key值1左边的数据进行比较的,
但可以看到1左边都没有数据,所以直接return了 。
这是对上一行数据key值1右边的数据也就是4 7 8 3 2进行排序,选择4为key值
比4小的都排在它的左边, 比4大的都排在它的右边
1 2 3 4 8 7 8 9 11 23 56 43 对上一行数据key值4右边的数据也就是1 2 3进行排序,选择1为key值
比1小的都排在它的左边, 比1大的都排在它的右边
1 2 3 4 7 8 8 9 11 23 56 43 对上一行数据key值1右边的数据也就是2 3进行排序,选择2为key值
比2小的都排在它的左边, 比2大的都排在它的右边
1 2 3 4 7 8 8 9 11 23 56 43
1 2 3 4 7 8 8 9 11 23 43 56 依次类推,大概能理解就行了
*/
QSort(arr,begin,first-1);
QSort(arr,first+1,end);
}
int main(){
int arr[]={11,4,7,8,43,2,56,23,8,1,3,9};
int size = sizeof(arr)/sizeof(int);
QSort(arr,0,size-1);
for(int i=0;i<size;i++)
{
cout<<arr[i]<<" ";
}
return 0;
}