一、基本思想:通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序
二、排序过程:
对r[s……t]中记录进行一趟快速排序,附设两个指针i和j,设枢轴记录rp=r[s],x=rp.key
1.初始时令i=s,j=t2.首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换
3.再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换
4.重复上述两步,直至i==j为止
5.再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止
三、排序举例:
四、代码(已经编译并测试通过):
//program name :quicksort
//author :Dam
//email : zhq651@126.com
//discription : This is a sort that fits for most situation¡¯s sort.
// It's very fast.
//step 1: make the first node as the pivotkey,then divide the set into two parts,
// that every one of the first part is bigger or smaller than every one of
// the second part. (How: compare the pivotkey to every one of the set from the
// end and top element alternately,if replace each other .)
//step 2: divide the first part and second part into subpart, and sort it by way like step 1;
// Time & Space
// Time:T(n) = O( nlog(2,n) )
// Space:S(n)= O(n) ;need stack Space to implement the function recursion.
#include <stdio.h>
#include <time.h>
#define NUMMAX 15
#define BORDER "================================================="
typedef struct qs_data
{
unsigned int key;
char value[30];
}elemType, *pElemtype;
void quick_sort(elemType r[], int n);
int q_sort(elemType r[], int n);
void print_banner(int type, char * banner);
int print_set(elemType lt[],unsigned int n);
void print_banner(int type, char * banner)
{
//banner first
if(type == 0){
printf("%s\n", banner);
printf(BORDER);
printf("\n");
}
//banner final
else{
printf(BORDER);
printf("\n");
printf("%s\n", banner);
}
}
// print the result in before sorting and after sorting
int print_set(elemType lt[],unsigned int n)
{
print_banner(1, "start print....");
int i=0;
while(i < n )
{
printf("%u\n", lt[i].key);
i++;
}
//printf("print end ....\n");
//printf("=====================================\n");
print_banner(0, "print end.");
return 0;
}
//make the set into a set that every one before pivot is smaller than every one after.
//get the first node as the pivot usually.
int q_sort(elemType r[], int n)
{
elemType pivot =r[0];
int i =0,j =n-1; //as front point, rear point
while( i < j )
{
//find the first element which smaller than the pivot key, by comparing from the rear.
while(i < j && r[j].key >= pivot.key)
j--;
if(i < j){
r[i] =r[j];
i++;
}
//find the first element which bigger than the pivot key, by comparing from the front.
while(i < j && r[i].key <= pivot.key )
i++;
if(i < j){
r[j] =r[i];
j--;
}
}
r[i] =pivot;
return i;
}
void quick_sort(elemType r[], int n)
{
if( n > 1 ){
int pos =0;
pos =q_sort(r, n);
quick_sort(r, pos);
quick_sort(r+pos+1, n-pos-1);
}
}
int main(void)
{
elemType hugset[NUMMAX+1];
int i;
//init the rander with different seeds;
srand(time(NULL));
for(i=0; i<NUMMAX+1; i++)
{
unsigned int t = rand()%NUMMAX;
hugset[i].key = t;
strcpy(hugset[i].value, "");
}
printf("before sort,the set is :\n");
print_set(hugset, NUMMAX);
quick_sort(hugset, NUMMAX);
printf("after sort,the set is :\n");
print_set(hugset, NUMMAX);
return 0;
}
1.时间复杂度
最好情况(每次总是选到中间值作枢轴)T(n)=O(nlog(2,n))
证明:横向来看,不管怎么分解,都需要n次操作,关键是需要多少次这样的横向。
列举一下,第1次分成2个,第2次分解成4个,如此log(2,n)后,就分解成 n个只有1个元素的序列,递归结束。
因此得证。
最坏情况(每次总是选到最小或最大元素作枢轴)T(n)=O(n²),例如:对于基本有序的序列,此种情况下就蜕化成冒泡排序。
2.空间复杂度:需栈空间以实现递归
最坏情况:S(n)=O(n)
一般情况:S(n)=O(log(2,n))
证明:每次
3.改进的方法,用“三者取中”的法则选取枢轴记录(pivotkey).这个代码就是采用双向进行比较的方法。
4.该排序是不稳定排序
5.同其它排序相比,就平均时间而言,快速排序是最好的.
六、直接应用
c语言qsort函数默认的就是该算法;对序列未知的情况下,我们优先使用该算法;
七、原理应用
让我么深刻理解下基本算法思想:分治和归并思想。
http://blog.csdn.net/zhq651/article/details/7918148 第六章第2个题很有启发性