快速排序详解,附源码

一、基本思想:通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序



二、排序过程

对r[s……t]中记录进行一趟快速排序,附设两个指针i和j,设枢轴记录rp=r[s],x=rp.key

1.初始时令i=s,j=t
2.首先从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个题很有启发性



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值