quick sort

[b]quicksort[/b]

------
[b]quicksort overview[/b]

quicksort 在实际应用中 非常出色,

时间复杂度:
理论上最差是:O(n^2),
实际应用中:平均可达到 O(n * lg(n)),且其中的 常量 比较小,

空间复杂度:
空间占用比较小,有优势,
即使在 虚拟内存中 也运行得较好,

------
[b]quicksort 原理[/b]

quicksort 采用 divide-conquer 方法,

分3步:
* divide
将 A[p .. r] 分解为 A[p .. q-1] 和 A[q+1 .. r] 2个子数组,分解函数称为 partition,
2个子数组 满足:
A[p .. q-1] 中所有元素 <= A[q],
A[q+1 .. r] 中所有元素 >= A[q],
* conquer
对2个子数组,递归调用 partition ,进行分解,
* combine
合并子数组,从底到上合并时,都是排过序的,因此不需要额外操作,直接合并即可,
*

partition 分解 函数:
取最后1个值作为中间值,前面的值依次和该值比较,然后决定放到该值的前面还是后面,
当然可以根据实际情况,决定取哪个值作为分隔值,基本原则是 balance,即 所取的值可以将数组分隔为大小相近的2个子数组,

------
[b]性能[/b]

性能取决于 分割点是否平衡,即 分割点的值在被分割数组中是否处于中间,
越平衡性能就越好,越不平衡性能越差,

最差性能是 O(n^2):
每次分割点都是 最大 或 最小值 时发生,

最好性能是 O(n*(lg n))
分割点每次都是 中间值时发生,

平均性能:
在实际应用中,quicksort 的性能更接近于 最好性能 O(n*(lg n)),


------
[b]例子[/b]:

* [b]js (quick_sort.js)[/b]

var arr_quicksort = [ 78, 13, 6, 177, 26, 90, 288, 45, 62, 83 ];

/**
* quict sort<br />
* <pre>
* <b>思路:</b>
* divide-and-conquer,
* 将数组 分成 左中右 3部分,左右是2个数组,左数组所有值 <= 中间值,右数组所有值 >= 中间值,
* 直到最后所有值都被分解为单个值,而且已经是排过序的,
* </pre>
* <b>时间复杂度:</b>理论上最差是 O(n^2),实际应用中是 O(n * (lg n)),且常量系数较小<br />
* <b>空间复杂度:</b>O(n),即使在虚拟内存中也运行良好<br />
*
* @author kuchaguangjie
* @date 2011年1月1日
* @return
*/
function QuickSort(initArr) {
this.totalCount = initArr.length;
this.tmpArr = [ initArr ];
this.resultArr = [];
}
/**
* 排序调用入口
*
* @return
*/
QuickSort.prototype.sort = function() {
while (this.resultArr.length < this.totalCount) {
this.partition();
}
return this.resultArr;
};
/**
* 将1个数组 分成 左中右 3块,满足:左 <= 中 <= 右,并将3块放到1个数组返回,
*
* @param arr
* 待分解的数组
* @return
*/
QuickSort.prototype.partitionSingle = function(arr) {
if (arr.length <= 1) {
return arr;
}

var partLeftArr = [];
var partRightArr = [];
var partMiddle = arr[arr.length - 1]; // 最后1个元素,用作分隔值
for ( var i = 0; i < arr.length - 1; i++) {
if (arr[i] <= partMiddle) {
partLeftArr[partLeftArr.length] = arr[i];
} else {
partRightArr[partRightArr.length] = arr[i];
}
}

var partArr = [];
if (partLeftArr.length > 0) {
if (partLeftArr.length == 1) {
partArr[0] = partLeftArr[0];
} else {
partArr[0] = partLeftArr;
}
}
partArr[partArr.length] = partMiddle;
if (partRightArr.length > 0) {
if (partRightArr.length == 1) {
partArr[partArr.length] = partRightArr[0];
} else {
partArr[partArr.length] = partRightArr;
}
}
return partArr;
};
/**
* 对整个数组做1次 partition
*
* @return
*/
QuickSort.prototype.partition = function() {
this.resultArr = [];
for ( var i = 0; i < this.tmpArr.length; i++) {
if (QuickSort.prototype.isArray(this.tmpArr[i])) { // 是 array 则分解
var partArr = this.partitionSingle(this.tmpArr[i]);
for ( var j = 0; j < partArr.length; j++) {
this.resultArr[this.resultArr.length] = partArr[j];
}
} else { // 单个数字
this.resultArr[this.resultArr.length] = this.tmpArr[i];
}
}
if (this.resultArr.length < this.totalCount) {
this.tmpArr = this.resultArr.slice(0, this.resultArr.length);
}
};

/**
* 检验是否是 Array
*
* @param v
* @return
*/
QuickSort.prototype.isArray = function(v) {
return Object.prototype.toString.apply(v) === '[object Array]';
}


* [b]html[/b]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="js/quick_sort.js"></script>
</head>
<body>
<input type="button" value="quick sort" onclick="alert(new QuickSort(arr_quicksort).sort());" />
</body>
</html>


*

------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值