分治思想的应用:C++实现快速排序和随机化的快速排序

1. 快速排序时冒泡排序的升级版

都知道冒泡排序需要从0-n-1轮n-1次两两比较。并且进行多次两两交换才能得到最后的排列结果。需要 

for(i from 0 to n-1)

   for(j from i+1 to n-1)

   compare(a[i], a[j])  and switch(a[i], a[j])

算法复杂度为O(n power 2)

快速排序通过对冒泡的改进,j将i和j从两边移到中间,使得第一次循环结果为以选取的中心值为中心。如果需要升序,

left = 0, right = n-1, pivot = a[left]

while(i< =j)

{

  if(a[j]<pivot) a[i]= a[i] , i++小的往左边移动

      if(a[i]>pibot) a[j] = a[j], j++, 大的往右移动

      else i++     

 else j++

}

quicksort(a,left,i-1);

quicksort(a,i+1,right);


快速排序则添加入循环迭代思想, 不断的拆分这个数组。

选取中心元素的问题

选取第一个数为中心元素

如何划分问题
如何重复步骤①②将所有数据排序

使用递归

函数头:quicksort(inta[],intleft,intright)

初始化: i = left;j = right;int temp=a[left] ;
划分: do{ 一次划分 } while( i <j);
中心元素填入: a[ i ]=temp;
递归地对剩余段作快速排序

quicksort(a,left,i-1);

quicksort(a,i+1,right);

2. 如何随机排列数列?

用这个 random_shuffle() 可以得到一个随即排序:
先用数组构造一个 vector 容器,
然后给 random_shuffle() 算法传递容易的首尾迭代器即可 

参考地址: http://www.cnblogs.com/afarmer/archive/2011/05/01/2033715.html

如何从一个数列中随机得到一个数?

#include <iostream> 
#include <stdlib.h> 
#include <time.h>  
using namespace std;  
int main() 
{  
srand((unsigned)time(NULL));  
for(int i = 0; i < 10;i++ )  
        cout << rand() << '\t';  
cout << endl;  
return 0; 
}

产生一定范围随机数的通用表示公式 
要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 
要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a



3.下面实现随机化的快速排序

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
bool static Inc(const int& x, const int& y)
{
	return x<y;
}
bool static Dec(const int& x, const int& y)
{
	return x>y;
}
//template<bool  cmp(const int&, const int&)>
void quicksort(int a[],int left,int right)
{	int i,j;
	if(left<right)
	{	i=left;j=right;
		int temp=a[left]; //store the pivot number, it can be anyone of the array a[]
		do
		{	while(Inc(a[j],temp) && i<j)//Inc for des
			j--; //j一直减直到可以交换
			if(i<j)
			{	a[i]=a[j];//blank postion i = a[j]
				i++;
			}
			while(Inc(temp, a[i]) && i<j)//i一直加直到a[i]大于j
			i++;
			if(i<j)
			{	a[j]=a[i];
				j--;
			}
		}while(i<j);// do while can make sure the i=j will be executed
		a[i]=temp;//i =j, only one positon left, so its the last temp
		quicksort(a,left,i-1);
		quicksort(a,i+1,right);
	}
}
int main()
{
	cout<<"input n"<<endl;
	int n;
	scanf("%d",&n);
	int a[100];
	cout<<"input "<< n<<" numbers"<<endl;
	for(int i = 0; i< n; i++)
	{
		scanf("%d", a+i);
	}
	int left = 0, right = n-1;
	srand(time(NULL));
	left = rand()%n;
	cout<<"random pivot is "<<a[left]<<endl;

	//swap with the first one
	int tmp;
	tmp = a[0];
	a[0]= a[left];
	a[left] = tmp;
	quicksort(a,0,n-1);

	cout<<"the result is:"<<endl;
    for(int i = 0; i< n; i++)
	{
		cout<<a[i]<<" ";
	}

	system("pause");
	return 0;
}
或者<pre name="code" class="cpp">	if(left<right)
	{	i=left;j=right;
		int pivot = a[left]; //store the pivot number, it can be anyone of the array a[]
		while(i <= j)
		{
			if(Inc(a[j],pivot) && i<j)
			{
				a[i] = a[j]; //大的往左边移动
				i++;
				if(Inc(pivot, a[i]) && i<j)
				{
					a[j] = a[i];//小的往右边移动
					j--;
				}
				else
				{
					i++;
				}
			}
			else
			{
			j--;
			}
		}
		a[i]=pivot;//i =j, only one positon left, so its the last temp
		quicksort(a,left,i-1);
		quicksort(a,i+1,right);
	}

 4. 快速排序的变体 

注意最后是交换a[i] 和A[r] 不是i+1

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
bool static Inc(const int& x, const int& y)
{
	return x<y;
}
bool static Dec(const int& x, const int& y)
{
	return x>y;
}
//template<bool  cmp(const int&, const int&)>
void quicksort(int a[], int left, int right)
{	int i,j;
	if(left < right)
	{	
		i=left;//j=size -1;
		int pivot = a[left];
		int tmp;
		//int temp=a[i]; //store the pivot number, it can be anyone of the array a[]
	    for(j = i+1; j <= right; j++)
		{
			if(a[j]<pivot)
			{
				if(j> ++i)
				{
				tmp = a[j];
				a[j] = a[i];//sawp i+1 and j
				a[i]=tmp;
				}
			}
		}
		tmp = a[i];
		a[i] = a[left];
		a[left] = tmp;
	    quicksort(a,left,i-1);
	    quicksort(a,i+1,right);
	}

}
int main()
{
	cout<<"input n"<<endl;
	int n;
	scanf("%d",&n);
	int a[100];
	cout<<"input "<< n<<" numbers"<<endl;
	for(int i = 0; i< n; i++)
	{
		scanf("%d", a+i);
	}
	int left = 0, right = n-1;
	srand(time(NULL));
	left = rand()%n;
	cout<<"random pivot is "<<a[left]<<endl;

	//swap with the first one
	int tmp;
	tmp = a[0];
	a[0]= a[left];
	a[left] = tmp;
	quicksort(a,0,n-1);

	cout<<"the result is:"<<endl;
    for(int i = 0; i< n; i++)
	{
		cout<<a[i]<<" ";
	}

	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值