快速排序
2015-09-22 09:31
162 查看
算法描述:
快速排序是一种分治的排序算法。
1、取出一个分割点,使数组左边的元素不大于该分割点的值,数组右边的元素不小于该分割点的值;
2、将数组的左半部分排序;
3、将数组的右半部分排序;
算法实现:
class Quick
{
public:
static bool sort(int *a, int lo, int hi)
{
if(hi <= lo) return true;
int p = partition(a, lo, hi);
sort(a, lo, p - 1);
sort(a, p + 1, hi);
return true;
}
static int partition(int *a, int lo, int hi)
{
int i = lo, j = hi + 1;
int v = a[lo];
while(true)
{
/* 扫描左右,检查扫描是否结束并交换元素 */
while(a[++i] < v)
{
if(i == hi) break;
}
while(v < a[--j])
{
if(j == lo) break;
}
if(i >= j) break;
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
/* 将v = a[j]放入正确的位置 */
a[lo] = a[j];
a[j] = v;
return j;
}
};
上述实现中,我们选取了a[lo]作为切分元素。在切分的过程中,我们保证左指针i左侧的元素不大于切分元素,右指针j右侧的元素不小于切分元素。当两个指针相遇时,我们只需要将切分元素a[lo]和a[j]进行交换,然后返回j即可。
时间复杂度:
快速排序最好的情况是每次都正好能将数组对半分,在这种情况下快速排序所用的次数正好满足分治递归的f(n) = 2 * f(n/2) + n,“2 * f(n/2) ”表示将两个子数组排序的成本,n表示切分元素和当前数组比较的成本。
公式推导:
f(n) = 2 * f(n/2) + n
= 4 * f(n/4) + 2 * n
= 8 * f(n/8) + 3 * n
...
= n + n * lg(n)
空间复杂度:
快速排序是原地排序,由于使用递归所以需要一个比较小的辅助栈(lg(n))。
稳定性:
快速排序是不稳定的,因为快速排序中不仅仅是相邻元素的交换。
适用情景:
快速排序可能是应用最广泛的算法,实现简单,速度快,不依赖输入情况,只用到一个很小的辅助栈(lg(n))。
快速排序是一种分治的排序算法。
1、取出一个分割点,使数组左边的元素不大于该分割点的值,数组右边的元素不小于该分割点的值;
2、将数组的左半部分排序;
3、将数组的右半部分排序;
算法实现:
class Quick
{
public:
static bool sort(int *a, int lo, int hi)
{
if(hi <= lo) return true;
int p = partition(a, lo, hi);
sort(a, lo, p - 1);
sort(a, p + 1, hi);
return true;
}
static int partition(int *a, int lo, int hi)
{
int i = lo, j = hi + 1;
int v = a[lo];
while(true)
{
/* 扫描左右,检查扫描是否结束并交换元素 */
while(a[++i] < v)
{
if(i == hi) break;
}
while(v < a[--j])
{
if(j == lo) break;
}
if(i >= j) break;
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
/* 将v = a[j]放入正确的位置 */
a[lo] = a[j];
a[j] = v;
return j;
}
};
上述实现中,我们选取了a[lo]作为切分元素。在切分的过程中,我们保证左指针i左侧的元素不大于切分元素,右指针j右侧的元素不小于切分元素。当两个指针相遇时,我们只需要将切分元素a[lo]和a[j]进行交换,然后返回j即可。
时间复杂度:
快速排序最好的情况是每次都正好能将数组对半分,在这种情况下快速排序所用的次数正好满足分治递归的f(n) = 2 * f(n/2) + n,“2 * f(n/2) ”表示将两个子数组排序的成本,n表示切分元素和当前数组比较的成本。
公式推导:
f(n) = 2 * f(n/2) + n
= 4 * f(n/4) + 2 * n
= 8 * f(n/8) + 3 * n
...
= n + n * lg(n)
空间复杂度:
快速排序是原地排序,由于使用递归所以需要一个比较小的辅助栈(lg(n))。
稳定性:
快速排序是不稳定的,因为快速排序中不仅仅是相邻元素的交换。
适用情景:
快速排序可能是应用最广泛的算法,实现简单,速度快,不依赖输入情况,只用到一个很小的辅助栈(lg(n))。
相关文章推荐
- js中使用正则表达式(二)操作正则表达式的对象RegExp、String和方法
- MySQL体系结构
- nodejs安装Yui Compressor
- 探究音节bo、po、 mo、 fo韵母的实际发音
- okhttp使用
- 【乐器常识】声音之美
- Android 类菜单栏 以及 透明居中排列
- Field Order - Who's on First?
- block,inline和inline-block概念和区别
- c语言算法小练习-19
- POI读取Word与Excel
- linux C信号量编程
- 菜鸟-手把手教你把Acegi应用到实际项目中(1.2)
- OC#import和#include的异同
- android studio导入别人项目快速配置方式
- C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
- 像生活一样跑步,像跑步一样生活
- cocos2d0基础知识三个音符
- CSS技巧
- 浅析android中的Bundle类