Skip to content

Commit 39d6a23

Browse files
quickSort
1 parent 32fa47f commit 39d6a23

File tree

4 files changed

+131
-1
lines changed

4 files changed

+131
-1
lines changed

Note/sort/index.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
const bubbleSort = require('./bubbleSort.js');
22
const selectSort = require('./selectSort.js');
3+
const insertSort = require('./insertSort.js');
4+
const quickSort = require('./quickSort.js');
35

46

57
function randomNums(len=1, min=0, max=1) {
68
let nums = [];
79
while(len--) nums.push(Math.floor(Math.random() * max + min));
810
return nums;
911
}
10-
let nums = randomNums(10, 0, 100);
12+
let nums = randomNums(10, 0, 300);
1113
console.log(nums);
1214

1315
// 测试代码
1416
console.log(bubbleSort([...nums]));
1517
console.log(selectSort([...nums]));
18+
console.log(insertSort([...nums]));
19+
console.log(quickSort([...nums]));

Note/sort/insertSort.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function insertSort(nums) {
2+
if (!nums || nums.length <= 1) return nums;
3+
4+
// 假设数组前 i 个元素有序, 循环后续元素, 一依次插入到合适位置
5+
for(let i=1; i< nums.length; i++) {
6+
let j = i-1;
7+
const cur = nums[i]; // 当前操作的元素
8+
// 倒序遍历有序部分, 查找合适的位置
9+
while(j>=0 && nums[j] > cur) {
10+
nums[j+1] = nums[j]; // 后移比当前元素大的元素
11+
j--;
12+
}
13+
nums[j+1] = cur;
14+
}
15+
return nums;
16+
}
17+
18+
19+
module.exports = insertSort;

Note/sort/quickSort.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
function quickSort(nums) {
2+
3+
if (!nums || nums.length <=1) return nums;
4+
5+
function partition(nums, left, right) {
6+
7+
let base = nums[left];
8+
let savePoint = left+1; // 这里存放的是大于基准值的区间下限位置
9+
10+
11+
for(let i=left+1; i<=right; i++) {
12+
const cur = nums[i];
13+
// 如果当前值小于基准值, 则将其余大区间下限交换, 同时将下限提升
14+
if (cur<base) {
15+
[nums[savePoint], nums[i]] = [nums[i], nums[savePoint]];
16+
savePoint++;
17+
}
18+
}
19+
// 循环结束后, 小于 savePoint 的元素, 均小于基准值, 大于等于savePoint 的值, 均大于基准值
20+
// 此时基准值仍在最左侧, 所以将基准值和小区间上限交换, 则达成目标, 基准值左侧均小于基准值, 基准值右侧均大于基准值
21+
[nums[savePoint-1], nums[left]] = [nums[left], nums[savePoint-1]];
22+
return savePoint-1; // 返回此时基准值位置, 便于拆分区间
23+
}
24+
25+
function recursive(nums, left, right) {
26+
if (left >= right) return nums;
27+
const index = partition(nums, left, right);
28+
recursive(nums, left, index-1);
29+
recursive(nums, index+1, right);
30+
}
31+
32+
recursive(nums, 0, nums.length-1);
33+
return nums;
34+
}
35+
36+
module.exports = quickSort;
37+
38+

Note/sort/sort.md

+69
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,78 @@
6969
* 示例代码
7070

7171
```js
72+
function insertSort(nums) {
73+
if (!nums || nums.length <= 1) return nums;
74+
75+
// 假设数组前 i 个元素有序, 循环后续元素, 一依次插入到合适位置
76+
for(let i=1; i< nums.length; i++) {
77+
let j = i-1;
78+
const cur = nums[i]; // 当前操作的元素
79+
// 倒序遍历有序部分, 查找合适的位置
80+
while(j>=0 && nums[j] > cur) {
81+
nums[j+1] = nums[j]; // 后移比当前元素大的元素
82+
j--;
83+
}
84+
nums[j+1] = cur;
85+
}
86+
return nums;
87+
}
7288
```
89+
* 代码分析
90+
* 空间复杂度:未使用额外空间,空间复杂度为 O(1)
91+
* 时间复杂度:
92+
* 最好:数组已有序,内层插入操作每次仅一次, O(n)
93+
* 最坏:数组反序,内层插入操作每次都要遍历已有序部分,O(n<sup>2</sup>)
94+
* 平均:O(n<sup>2</sup>)
7395

7496
#### 快速排序
97+
* 基本思想
98+
* 快速排序采用分治的思想,递归处理
99+
* 首先选择基准值,通常选择区间最左侧元素
100+
* 遍历区间,将区间分为小于基准值和大于基准值的两部分
101+
* 将基准值插入到这两部分之间,
102+
* 以基准值的位置为中点,拆分并递归处理这两个子区间
103+
* 示例代码
104+
105+
```js
106+
function quickSort(nums) {
107+
108+
if (!nums || nums.length <=1) return nums;
109+
110+
function partition(nums, left, right) {
111+
112+
let base = nums[left];
113+
let savePoint = left+1; // 这里存放的是大于基准值的区间下限位置
114+
115+
116+
for(let i=left+1; i<=right; i++) {
117+
const cur = nums[i];
118+
// 如果当前值小于基准值, 则将其余大区间下限交换, 同时将下限提升
119+
if (cur<base) {
120+
[nums[savePoint], nums[i]] = [nums[i], nums[savePoint]];
121+
savePoint++;
122+
}
123+
}
124+
// 循环结束后, 小于 savePoint 的元素, 均小于基准值, 大于等于savePoint 的值, 均大于基准值
125+
// 此时基准值仍在最左侧, 所以将基准值和小区间上限交换, 则达成目标, 基准值左侧均小于基准值, 基准值右侧均大于基准值
126+
[nums[savePoint-1], nums[left]] = [nums[left], nums[savePoint-1]];
127+
return savePoint-1; // 返回此时基准值位置, 便于拆分区间
128+
}
129+
130+
function recursive(nums, left, right) {
131+
if (left >= right) return nums;
132+
const index = partition(nums, left, right);
133+
recursive(nums, left, index-1);
134+
recursive(nums, index+1, right);
135+
}
136+
137+
recursive(nums, 0, nums.length-1);
138+
return nums;
139+
}
140+
```
141+
* 代码分析
142+
* 空间复杂度: 未使用额外空间,空间复杂度 O(1)
143+
*
75144

76145
#### 归并排序
77146

0 commit comments

Comments
 (0)