GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — 快速排序 · Issue #41 · sl1673495/leetcode-javascript Open Labels Description初始版最初的版本,对于 它的问题在于,如果数组是个近似有序的数组的话,它的时间复杂度会退化到接近 On² 的级别。排序分治形成的二叉树会非常不平衡,退化成接近链表。 function partition(arr, left, right) { // 取一个基准值 取第一项 let pivot = arr[left] // arr[left+1...index] < pivot, arr[index+1...i) > pivot let index = left for (let i = left + 1; i <= right; i++) { let num = arr[i] if (num < pivot) { swap(arr, index + 1, i) index++ } } swap(arr, left, index) return index } 随机数优化版对于上述的近似有序数组的问题,我们可以选择每次的基准值选取一个随机值,这样退化成 On² 的可能性就趋近于零了。 function partition(arr, left, right) { // 取一个基准值 取随机值 let rand = random(left, right) swap(arr, left, rand) let pivot = arr[left] // arr[left+1...index] < pivot, arr[index+1...i) > pivot let index = left for (let i = left + 1; i <= right; i++) { let num = arr[i] if (num < pivot) { // 如果当前值小于基准值的话,就交换到index + 1的位置去。 // 扩充了index的范围 [index...], pivot, [...right] swap(arr, index + 1, i) index++ } } swap(arr, left, index) return index } 但是这样还是会有问题,对于重复元素很多的数组,只会简单的把大于等于基准值的元素简单粗暴的划分到右侧范围里,然后继续递归的快排,浪费了大量时间。 三路快排最终优化版就是三路快排了,顾名思义这种快排就是把数组区分成 function sortArray(arr) { _quickSort(arr, 0, arr.length - 1) return arr } /** * 对 arr[l...r] 部分进行快速排序 * @param {number[]} arr * @param {number} l 左边界 * @param {number} r 右边界 */ function _quickSort(arr, l, r) { if (l >= r) { return } let [p, q] = partition(arr, l, r) _quickSort(arr, l, p) _quickSort(arr, q, r) } function random(low, high) { return Math.round(Math.random() * (high - low)) + low } function swap(arr, i, j) { let temp = arr[i] arr[i] = arr[j] arr[j] = temp } /** * 对 arr[l...r] 部分进行快速排序 * @param {number[]} arr * @param {number} l 左边界 * @param {number} r 右边界 * @returns {number} 返回索引值p,使得arr[l...p-1] < arr[p] < arr[p+1...r] */ function partition(arr, left, right) { // 取一个基准值 取随机值 let rand = random(left, right) swap(arr, left, rand) let pivot = arr[left] // 三路 注意看注释里的区间 let lt = left // arr[left + 1...lt] < v let gt = right + 1 // arr[gt...r] > v let index = left + 1 // arr[lt + 1...index) === v while (index < gt) { let num = arr[index] if (num < pivot) { swap(arr, index, lt + 1) lt++ index++ } else if (num > pivot) { swap(arr, index, gt - 1) gt-- } else if (num === pivot) { index++ } } swap(arr, left, lt) return [lt - 1, gt] } ActivityMetadataMetadataAssigneesLabelsProjectsMilestoneRelationshipsDevelopmentIssue actions |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |