快速排序的时间复杂度:
平均时间复杂度的情况:O(nlogn)–在每次数组一分为二时近乎平均分配
最差时间复杂度:O(n²)–在数组完全有序的情况下/超大量重复数组时
快速排序的核心思想
快速排序的核心思想是:分治,分而治之,把所有的子问题解决了,主要问题也就得到了解决。
快速排序的原理:在一个数组中,首先选定一个标定元素,然后根据这个标定元素将数组一分为二,一部分(数组中所有元素)小于这个标定元素,一部分(数组中所有元素)大于这个标定元素,然后将标定元素放置到正确位置(也就是下方代码中__partition函数返回的位置),然后分别对分出的数组进行递归排序,直至循环完成。
快速排序的基本算法
/*返回P值,使得arr[l...p-1]<arr[p],arr[p+1...r]>arr[p]*/
function __partition(arr, l, r) {
var v = arr[l];
/*arr[l+1...j]<v,arr[j+1...r]>v*/
var j = l;
for (var i = l + 1; i <= r; i++) {
if (arr[i] < v) {
[arr[i], arr[j + 1]] = [arr[j + 1], arr[i]];
j++;
}
}
[arr[l], arr[j]] = [arr[j], arr[l]];
return j;
}
/*对arr[l....r]进行快速排序*/
function __quickSort(arr, l, r) {
if (l >= r) return;
var p = __partition(arr, l, r);
__quickSort(arr, l, p - 1);
__quickSort(arr, p + 1, r);
}
function quickSort(arr, n) {
__quickSort(arr, 0, n - 1);
}
快速排序优化(时间优化–插入排序)
/*返回P值,使得arr[l...p-1]<arr[p],arr[p+1...r]>arr[p]*/
function __partition(arr, l, r) {
var v = arr[l];
/*arr[l+1...j]<v,arr[j+1...r]>v*/
var j = l;
for (var i = l + 1; i <= r; i++) {
if (arr[i] < v) {
[arr[i], arr[j + 1]] = [arr[j + 1], arr[i]];
j++;
}
}
[arr[l], arr[j]] = [arr[j], arr[l]];
return j;
}
/*对arr[l....r]进行快速排序*/
function __quickSort(arr, l, r) {
/*当剩余数组较短时,可采用插入排序,本次不对插入排序做过多介绍 */
if(r-l >= 15){
insertionSort(arr, l, r);
return;
}
var p = __partition(arr, l, r);
__quickSort(arr, l, p - 1);
__quickSort(arr, p + 1, r);
}
function quickSort(arr, n) {
__quickSort(arr, 0, n - 1);
}
快速排序的优化(解决近乎完全有序的情况)
/*Math.floor(Math.random()*(max-min+1)+min);
max - 期望的最大值
min - 期望的最小值*/
function __partition(arr, l, r) {
//随机数法
var random = Math.floor(Math.random() * (r - l + 1) + l);
[arr[l], arr[random]] = [arr[random], arr[l]];
var v = arr[l];
var j = l;
for (var i = l + 1; i <= r; i++) {
if (arr[i] < v) {
[arr[i], arr[j + 1]] = [arr[j + 1], arr[i]];
j++;
}
}
[arr[l], arr[j]] = [arr[j], arr[l]];
return j;
}
function __quickSort(arr, l, r) {
if (l >= r) return;
var p = __partition(arr, l, r);
__quickSort(arr, l, p - 1);
__quickSort(arr, p + 1, r);
}
function quickSort2(arr, n) {
__quickSort(arr, 0, n - 1);
}
快速排序优化(解决大量重复数据)
/*Math.floor(Math.random()*(max-min+1)+min);
max - 期望的最大值
min - 期望的最小值*/
function __partition(arr, l, r) {
if (l >= r) return;
//随机数法
var random = Math.floor(Math.random() * (r - l + 1) + l);
[arr[l], arr[random]] = [arr[random], arr[l]];
var v = arr[l];
/*arr[l+1...i)<=v,arr(j...r]>=v*/
var i = l + 1, j = r;
while (true) {
while (i <= r && arr[i] < v) i++;
while (arr[j] > v && j >= l + 1) j--;
if (i > j) break;
[arr[i], arr[j]] = [arr[j], arr[i]];
i++;
j--;
}
[arr[l], arr[j]] = [arr[j], arr[l]];
return j;
}
function __quickSort(arr, l, r) {
if (l >= r) return;
var p = __partition(arr, l, r);
__quickSort(arr, l, p - 1);
__quickSort(arr, p + 1, r);
}
function quickSort2(arr, n) {
__quickSort(arr, 0, n - 1);
}
快速排序优化(典型的三路排序)
function __quickSort3Ways(arr, l, r) {
if (l >= r) return;
/*partition*/
var random = Math.floor(Math.random() * (r - l + 1) + l);
[arr[l], arr[random]] = [arr[random], arr[l]];
var v = arr[l];
var lt = l; //arr[l+1...lt]<v
var gt = r + 1; //arr[gt...r]>v
var i = l + 1; //arr[lt+1...i]==v
while (i < gt) {
if (arr[i] < v) {
[arr[i], arr[lt + 1]] = [arr[lt + 1], arr[i]];
lt++;
i++;
} else if (arr[i] > v) {
[arr[i], arr[gt - 1]] = [arr[gt - 1], arr[i]];
gt--;
} else { //arr[i]==v
i++;
}
}
[arr[l], arr[lt]] = [arr[lt], arr[l]];
__quickSort3Ways(arr, l, lt - 1);
__quickSort3Ways(arr, gt, r);
}
function quickSort3Ways(arr, n) {
__quickSort3Ways(arr, 0, n - 1);
}