`
plussai
  • 浏览: 88380 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

快速排序(qsort)

阅读更多

         快速排序是一种高效的非稳定排序,它的基本思路是分支法,在一个序列a[]中找到一个数a[mid],然后将序列a[]分为3部分a[start]---a[i-1],a[i],a[i+1]---a[end],第一部分的序列中,所有的数都小于a[i],第二部分的序列中,所有的数都大于a[i]。然后递归的对前后两部分进行处理,直到序列完成排序。

        那么快速排序的关键步骤就是对序列进行重排。有两种思路1)单向扫描。2)双向扫描。

       单向扫描:根据算法导论第二版他的算法流程为:

PARTITION(A, p, r)
1  x ← A[r]         //以最后一个元素,A[r]为主元
2  i ← p - 1
3  for j ← p to r - 1    //注,j从p指向的是r-1,不是r。
4       do if A[j] ≤ x
5             then i ← i + 1
6                  exchange A[i] <-> A[j]
7  exchange A[i + 1] <-> A[r]    //最后,交换主元
8  return i + 1

    可以看到,以序列的最后一个元素为基准元素,从序列头部开始扫描,如果发现a[i]小于基准元素,将他交换到序列前部(注意前部指针交换一次就加1)

       双向扫描:

OARE-PARTITION(A, p, r)
 1  x ← A[p]
 2  i ← p - 1
 3  j ← r + 1
 4  while TRUE
 5      do repeat j ← j - 1
 6           until A[j] ≤ x
 7         repeat i ← i + 1
 8           until A[i] ≥ x
 9         if i < j
10            then exchange A[i] <-> A[j]
11            else return j

  可以看到,扫秒从2头开始,如果发现a[i]>mid&&a[j]<mid将两者交换,注意基准元素为a[p],最后返回的是j

    最后给出具体代码,附带了随机化版本:

  

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
using namespace std;
void swap(int *src,int a,int b)
{
	int temp=src[a];
	src[a]=src[b];
	src[b]=temp;
}
int partition(int* src,int start,int end)
{
	int result;
	int i=start;
	int j=end;
	int mid=src[start];
	end=end+1;
	while(1)
	{
		while(src[++start]<mid&&start<j);
		while(src[--end]>mid);
		if(start>=end)
		break;
		swap(src,start,end);
	}	
	swap(src,i,end);
	return end;
}
int partition_single(int*src,int start,int end)
{
	int mid=src[end];
	int i=start-1;
	for(int j=start;j<end;j++)
	{
		if(src[j]<=mid)
		{
			++i;
			swap(src,i,j);
		}
	}	
	swap(src,i+1,end);
	return i+1;
}
int randomPartition(int*src,int start,int end)
{
	srand(time(NULL));
	int n=rand()%(end-start+1);
	int r=start+n;
	swap(src,start,r);
	return partition(src,start,end);
	//return partition_single(src,start,end);
}
void q_sort(int *src,int start,int end)
{
	if(start>=end)
		return;
	//int result=partition(src,start,end);
	//int result=partition_single(src,start,end);
	int result=randomPartition(src,start,end);
	q_sort(src,start,result-1);
	q_sort(src,result+1,end);
	
}
int main()
{
	int src[16]={16,11,15,9,10,13,14,8,2,1,5,12,6,3,7,4};
	q_sort(src,0,15);
	for(int i=0;i<16;i++)
	cout<<src[i]<<" ";
	cout<<endl;
	
	return 0;
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics