基础算法(2):快速排序(随机划分+三数取中划分+ 随机三数取中划分+尾递归)
2013-12-23 15:10
543 查看
快速排序:
简介:快速排序是一种排序算法,包含n个数的输入数组,最坏情况为O(n^2),但是平均性能非常好: 期望运行时间为O(n*lg(n))。
基本思想:通过 一次划分得到一个主元在集合中的位置。
影响因素:划分算法决定着一个快速排序的效率。
划分算法分类
1.以集合尾元素(或首元素)为主元,以下代码以尾元素为主元。
[cpp] view
plaincopy
int partion(vector<int> &num, int beg, int end)
{
/*把最后集合最后一个元素作为主元*/
int x = num[end];
int i = beg - 1;
for (int j = beg; j != end; ++j)
{
if (num[j] <= x)
{
++i;
swap(num[i], num[j]);
}
}
swap(num[i + 1], num[end]);
return i + 1;
}
[cpp] view
plaincopy
void quickSort(vector<int> &num, int beg, int end)
{
if (beg < end)
{
int q = partion(num, beg, end);
quickSort(num, beg, q - 1);
quickSort(num, q + 1, end);
}
}
2. 随机数划分:随机选取数组中的一个元素为主元。随机数划分需要获得随机数,代码如下:
1) 头文件
[cpp] view
plaincopy
#include <ctime>
#include <cstdlib>
2)在main() 函数调用random()前设置随机种子:
[cpp] view
plaincopy
srand(unsigned(time(0)));// srand函数要在main函数开始的时候设置
3) 写随机函数
[cpp] view
plaincopy
int random(int start, int end)// 返回[start, end]之间的随机数
{
return start + (end - start + 1)*rand() / (RAND_MAX + 1);//[start, end]
//return start + (end - start)*rand() / (RAND_MAX + 1);//[start, end)
//return start + 1 + (end - start)*rand() / (RAND_MAX + 1);//(start, end]
}
3.三数取中划分:取集合中的首元素,中元素,尾元素,以其中位数为主元。
[cpp] view
plaincopy
int findMedian(const int &a, const int &b, const int &c)//取三个数的中位数
{
if (a <= b && a <= c)
{
if (b <= c)
return b;
else
return c;
}
else if (b < a && b <= c)
{
if (a <= c)
return a;
else
return c;
}
else
{
if (a <= b)
return a;
else
return b;
}
}
4.随机三个数取中位数。
[cpp] view
plaincopy
/*3种划分算法*/
int rand_Partion(vector<int> &num, int beg, int end)
{
//int temp = random(beg, end);
//swap(num[temp], num[end]);
/*以上随机返回[beg, end]数组中的一个数作为主元(pivot element);
*并把数组尾元素与这个随机数交换,因为partion()以最后一个数做主元
*/
//int a = random(beg, end);
//int b = random(beg, end);
//int c = random(beg, end);
//int temp = findMedian(a, b, c);
//swap(num[temp], num[end]);
/*以上随机返回[beg, end]数组中的三个数,取三个数的中位数作为
*主元(pivot element);并把数组尾元素与这个中位数交换
*/
int a = num[beg];
int b = num[beg + (end - beg) / 2];
int c = num[end];
int temp = findMedian(a, b, c);
/*以上取[beg, end]的首、尾、中间三个数,把三个数的中位数作为
*主元(pivot element);并把数组尾元素与这个中位数交换
*/
return partion(num, beg, end);//调用分割函数
}
[cpp] view
plaincopy
void rand_quickSort(vector<int> &num, int beg, int end)
{
if (beg < end)
{
int q = rand_Partion(num, beg, end);
rand_quickSort(num, beg, q - 1);
rand_quickSort(num, q + 1, end);
}
}
快速排序的尾递归:
quickSort()中的第二次递归调用并不是必须的,可以用迭代控制结构替代它。
[cpp] view
plaincopy
void quickSort_2(vector<int> &num, int beg, int end)//尾递归形式
{
while (beg < end)
{
int q = partion(num, beg, end);
quickSort_2(num, beg, q - 1);//一次循环把主元左边的排序好
beg = q + 1;
}
}
简介:快速排序是一种排序算法,包含n个数的输入数组,最坏情况为O(n^2),但是平均性能非常好: 期望运行时间为O(n*lg(n))。
基本思想:通过 一次划分得到一个主元在集合中的位置。
影响因素:划分算法决定着一个快速排序的效率。
划分算法分类
1.以集合尾元素(或首元素)为主元,以下代码以尾元素为主元。
[cpp] view
plaincopy
int partion(vector<int> &num, int beg, int end)
{
/*把最后集合最后一个元素作为主元*/
int x = num[end];
int i = beg - 1;
for (int j = beg; j != end; ++j)
{
if (num[j] <= x)
{
++i;
swap(num[i], num[j]);
}
}
swap(num[i + 1], num[end]);
return i + 1;
}
[cpp] view
plaincopy
void quickSort(vector<int> &num, int beg, int end)
{
if (beg < end)
{
int q = partion(num, beg, end);
quickSort(num, beg, q - 1);
quickSort(num, q + 1, end);
}
}
2. 随机数划分:随机选取数组中的一个元素为主元。随机数划分需要获得随机数,代码如下:
1) 头文件
[cpp] view
plaincopy
#include <ctime>
#include <cstdlib>
2)在main() 函数调用random()前设置随机种子:
[cpp] view
plaincopy
srand(unsigned(time(0)));// srand函数要在main函数开始的时候设置
3) 写随机函数
[cpp] view
plaincopy
int random(int start, int end)// 返回[start, end]之间的随机数
{
return start + (end - start + 1)*rand() / (RAND_MAX + 1);//[start, end]
//return start + (end - start)*rand() / (RAND_MAX + 1);//[start, end)
//return start + 1 + (end - start)*rand() / (RAND_MAX + 1);//(start, end]
}
3.三数取中划分:取集合中的首元素,中元素,尾元素,以其中位数为主元。
[cpp] view
plaincopy
int findMedian(const int &a, const int &b, const int &c)//取三个数的中位数
{
if (a <= b && a <= c)
{
if (b <= c)
return b;
else
return c;
}
else if (b < a && b <= c)
{
if (a <= c)
return a;
else
return c;
}
else
{
if (a <= b)
return a;
else
return b;
}
}
4.随机三个数取中位数。
[cpp] view
plaincopy
/*3种划分算法*/
int rand_Partion(vector<int> &num, int beg, int end)
{
//int temp = random(beg, end);
//swap(num[temp], num[end]);
/*以上随机返回[beg, end]数组中的一个数作为主元(pivot element);
*并把数组尾元素与这个随机数交换,因为partion()以最后一个数做主元
*/
//int a = random(beg, end);
//int b = random(beg, end);
//int c = random(beg, end);
//int temp = findMedian(a, b, c);
//swap(num[temp], num[end]);
/*以上随机返回[beg, end]数组中的三个数,取三个数的中位数作为
*主元(pivot element);并把数组尾元素与这个中位数交换
*/
int a = num[beg];
int b = num[beg + (end - beg) / 2];
int c = num[end];
int temp = findMedian(a, b, c);
/*以上取[beg, end]的首、尾、中间三个数,把三个数的中位数作为
*主元(pivot element);并把数组尾元素与这个中位数交换
*/
return partion(num, beg, end);//调用分割函数
}
[cpp] view
plaincopy
void rand_quickSort(vector<int> &num, int beg, int end)
{
if (beg < end)
{
int q = rand_Partion(num, beg, end);
rand_quickSort(num, beg, q - 1);
rand_quickSort(num, q + 1, end);
}
}
快速排序的尾递归:
quickSort()中的第二次递归调用并不是必须的,可以用迭代控制结构替代它。
[cpp] view
plaincopy
void quickSort_2(vector<int> &num, int beg, int end)//尾递归形式
{
while (beg < end)
{
int q = partion(num, beg, end);
quickSort_2(num, beg, q - 1);//一次循环把主元左边的排序好
beg = q + 1;
}
}
相关文章推荐
- 基础算法(2):快速排序(随机划分+三数取中划分+ 随机三数取中划分+尾递归)
- java基础算法-快速排序
- Algorithm--让人困惑的快速排序(划分算法) 续
- 分治法在排序算法中的应用(JAVA)--快速排序(Lomuto划分、Hoare划分、随机化快排)
- 基于随机游走的社团划分算法label progation 的python实现
- 【Visual C++】游戏开发笔记十七 游戏基础算法(一) 游戏随机系统初步
- 《github一天一道算法题》:快速排序和随机快速排序
- [算法基础]快速排序
- 【基础算法】排序-复杂排序之二(快速排序)
- 基于随机游走的社团划分算法label progation 的python实现
- 算法基础4:快速排序(随机化版本)
- 划分算法(快速排序的根基)
- 期末考试-复杂的整数划分问题(算法基础 第10周)
- // 快速排序中的划分 ,<<数据结构》算法10.6(b)
- 【Visual C++】游戏开发笔记十七 游戏基础算法(一) 游戏随机系统初步
- 快速排序(2)算法改进--小的子文件、三者取中、重复关键字三路划分
- 快速排序的插排随机主元三数取中优化C语言实现
- 【Visual C++】游戏开发笔记十七 游戏基础算法(一) 游戏随机系统初步
- 算法基础(3)分治策略之快速排序
- (1544): 序列划分(求极大值的最小值)&(1233): 【基础算法】 书的复制