快速排序顾名思义就是一种能够快速的将混乱的数列排序的算法,但是快排的编写具有一定的难度,听人说全世界的编程大师有50%不能独立的写出正确排序算法,听着好像有一点假,不过这也从侧面说明的快排的难度,我将先介绍传统的快排思想,然后介绍我的巧解(不耐烦的朋友可以直接看下方的巧解)。快速排序由C. A. R. Hoare在1962年提出,它的基本思想是:首先选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分,不大于基准数的数在基准数的左边,大于它的数在它的右边,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
一般意义上的详细排序过程:
1.以数列的第一个元素作为基准数K,设置两个变量i,j分别指向数列的首尾;
2.以 j 作为“指针”开始从后往前访问数列,当访问到小于或等于K的元素时交换基准数和这个元素的位置;
3.从后往前访问交换一次之后,转为以 i 为“指针”从前往后访问,当访问到大于K的元素后,交换此时基准数和这个元素的位置;
4.第二步和第三步交替进行直到 i=j(遍历完整个数列);
5.然后对完成初步排序的数列基准数的左边和右边按照上面四步进行排序,直到数列被分割成一个一个的元素就
停止,这时排序也完成了。
巧解:
你可能会认为这个算法很容易,自己动手试一试,如果编的很轻松我只能说你的天赋很好,如果不行请看我下面的讲解。这个解法主要是减轻我们思维上的负担,让我们在编程的时候头脑比较清晰,我给它取名叫做“挖洞法”,别看下面的文字变多了,其实思维变简单了。
挖洞法法详细步骤:
1.以数列的第一个元素作为基准数K,这时认为数列第一个数已被挖掉,即不存在,用变量aim来记录洞的位置,设置两个变量i,j分别指向数列的首尾;
2.以 j 作为“指针”开始从后往前访问数列,当访问到小于或等于K的元素时将这个元素填到刚才aim记录的洞的位置,然后将填到洞里的元素刚才的位置作为一个新的洞由aim记录;
3.从后往前访问填洞完成一次之后,转为以 i 为“指针”从前往后访问,当访问到大于K的元素后,将这个元素填到洞里去,并记录新洞的位置;
4.交替重复第二步和第三步,直到 i=j ,遍历完整个数列后将K填入到最后一个洞中,这样第一次挖洞填洞完成。
5.用递归的方法对数列的左边和右边进行同样的处理,直到数列被分割成一个一个的元素,排序完成。
巧解讲完了感兴趣的朋友可以试一试是不是比传统的思想要简单许多,实践是检验真理的唯一标准,感觉吃力的朋友可以看一看我下面的代码。
核心算法如下:
void quick_sort(int b[],int c,int d)//c为下标的起始位,d为下标的终止位
{
if(c<d)
{
int i=c;
int j=d;
int k=b[c];
int aim=c;//记录洞的位置
int count=0;
while(i<=j)//<=
{
while(cout==0&&j>=i)
{
if(k>=b[j]) {b[aim]=b[j];aim=j;count++;}//>=
j--;
}
count=0;
while(cout==0&&i<=j)
{
if(k<b[i]) {b[aim]=b[i];aim=i;count++;}
i++;
}
count=0;
}
b[aim]=k;
quick_sort(b,c,aim-1);
quick_sort(b,aim+1,d);
}
}
整体代码如下:
#include<iostream>
using namespace std;
const static int num=9;
static int*a;
void quick_sort(int b[],int c,int d)//c为下标的起始位,d为下标的终止位
{
if(c<d)
{
int i=c;
int j=d;
int k=b[c];
int aim=c;//记录洞的位置
int count=0;
while(i<=j)//<=
{
while(cout==0&&j>=i)
{
if(k>=b[j]) {b[aim]=b[j];aim=j;count++;}//>=
j--;
}
count=0;
while(cout==0&&i<=j)
{
if(k<b[i]) {b[aim]=b[i];aim=i;count++;}
i++;
}
count=0;
}
b[aim]=k;
quick_sort(b,c,aim-1);
quick_sort(b,aim+1,d);
}
}
int main()
{
a=new int[num];
for(int i=0; i<num;i++)
{
cin>>a[i];
}
quick_sort(a,0,num-1);
for(int i=0;i<num;i++)
{
cout<<a[i]<<" ";
}
system("pause");
return 0;
}