快速排序分为两部分:
1,partition函数,找到基准所在的位置并返回,这个函数的用途非常多,不仅在快速排序,而且在线性时间选择中也运用广泛,这个函数有多种写法,我仅会两种。
2,快排函数本身,通过递归调用自身,每次调用可以使一个元素回归正确的位置,并使该元素之前的元素都小于该元素,之后的元素都大于该元素(递归的退出条件是base>=top)。这样,我们可以最后把整个数列割到最小两个元素的子列,再使子列有序,从而整个数列都有序。值得注意的是,快排不会使某个元素向自己合适位置相反的方向运动。(比如2在最后结果序列处于第3位,那么它绝不可能在排序的过程中出现在第3位之后)。
int partition(int a[],int base,int top)
{
int temp=a[base];
int i=base;
int j=top;
while(i<j)
{
while(i<j&&a[j]>=temp)
{
j--;
}
if(j>i)
{
a[i]=a[j];
}
while(i<j&&a[i]<=temp)
{
i++;
}
if(i<j)
{
a[j]=a[i];
}
}
a[i]=temp;
return i;
}
以上是第一种partition函数,也是严老师版教科书的参考方法,不需要其它函数,但是思路比较复杂。
int partition(int a[],int base,int top)
{
int i=base;
int j=top;
int temp=a[base];
while(j>i)
{
while(j>i&&a[j]>=temp)
{
j--;
}
while(j>i&&a[i]<=temp)
{
i++;
}
swap(&a[i],&a[j]);
}
a[base]=a[i];
a[i]=temp;
return i;
}
以上是自己书写的partition函数,用到了交换变量的函数,相对思路简单。
1,最后,我们总是把基准值(比如第一个数字)赋予a[i],那么i是什么?无论是在哪种方法的partition函数中,最后的i与j指针指向了同一个单元,通过i指针的意义我们易知,它是一个值小于基准值的数。
2,两种方法的排序过程中子列的顺序不完全一致。
3,两点是一致的并且易错之处在于:1,先j指针从右向左遍历。2,判断条件是j>i,没有等号。