Skip to content

Commit 5cb23b9

Browse files
authored
Merge pull request apachecn#265 from DangoSky/master
补充五种排序算法的实现思路和代码
2 parents a463729 + 8ef4119 commit 5cb23b9

File tree

1 file changed

+167
-1
lines changed
  • docs/Algorithm_Implementation/JavaScript

1 file changed

+167
-1
lines changed
Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,172 @@
11
# Some algorithm templates for better understanding!
22

33

4-
> [八大排序算法 集合](/docs/Algorithm/Sort)
4+
# 八大排序算法集合
55

66
![](/images/SortingAlgorithm/八大排序算法性能.png)
7+
8+
## 冒泡排序
9+
### 单向冒泡
10+
通过相邻元素的比较和交换,使得每一趟循环都能找到未有序数组的最大值或最小值。
11+
```
12+
function bubbleSort(nums) {
13+
for(let i=0, len=nums.length; i<len-1; i++) {
14+
// 如果一轮比较中没有需要交换的数据,则说明数组已经有序。主要是对[5,1,2,3,4]之类的数组进行优化
15+
let mark = true;
16+
for(let j=0; j<len-i-1; j++) {
17+
if(nums[j] > nums[j+1]) {
18+
[nums[j], nums[j+1]] = [nums[j+1], nums[j]];
19+
mark = false;
20+
}
21+
}
22+
if(mark) return;
23+
}
24+
}
25+
```
26+
27+
### 双向冒泡
28+
在一趟循环中,既找出最大值也找出最小值。
29+
30+
```
31+
function bubbleSort_twoWays(nums) {
32+
for(let i=0, len=nums.length; i<len-1; i++) {
33+
let mark = true;
34+
// 找到最大值放到右边
35+
for(let j=0; j<len-i-1; j++) {
36+
if(nums[j] > nums[j+1]) {
37+
[nums[j], nums[j+1]] = [nums[j+1], nums[j]];
38+
mark = false;
39+
}
40+
}
41+
// 找到最小值放到左边
42+
for(let t=len-i-2; t>0; t--) {
43+
if(nums[t] < nums[t-1]) {
44+
[nums[t], nums[t-1]] = [nums[t-1], nums[t]];
45+
mark = false;
46+
}
47+
}
48+
if(mark) return;
49+
}
50+
}
51+
```
52+
53+
## 选择排序
54+
和冒泡排序相似,区别在于选择排序是将每一个元素和它后面的元素进行比较和交换。
55+
```
56+
function selectSort(nums) {
57+
for(let i=0, len=nums.length; i<len; i++) {
58+
for(let j=i+1; j<len; j++) {
59+
if(nums[i] > nums[j]) {
60+
[nums[i], nums[j]] = [nums[j], nums[i]];
61+
}
62+
}
63+
}
64+
}
65+
```
66+
67+
## 插入排序
68+
以第一个元素作为有序数组,其后的元素通过在这个已有序的数组中找到合适的位置并插入。
69+
```
70+
function insertSort(nums) {
71+
for(let i=1, len=nums.length; i<len; i++) {
72+
let temp = nums[i];
73+
let j = i;
74+
while(j >= 0 && temp < nums[j-1]) {
75+
nums[j] = nums[j-1];
76+
j--;
77+
}
78+
nums[j] = temp;
79+
}
80+
}
81+
```
82+
83+
## 快速排序
84+
选择一个元素作为基数(通常是第一个元素),把比基数小的元素放到它左边,比基数大的元素放到它右边(相当于二分),再不断递归基数左右两边的序列。
85+
### 填坑法
86+
```
87+
function quickSort(nums) {
88+
// 递归排序基数左右两边的序列
89+
function recursive(arr, left, right) {
90+
if(left >= right) return;
91+
let index = partition(arr, left, right);
92+
recursive(arr, left, index - 1);
93+
recursive(arr, index + 1, right);
94+
return arr;
95+
}
96+
// 将小于基数的数放到基数左边,大于基数的数放到基数右边,并返回基数的位置
97+
function partition(arr, left, right) {
98+
// 取第一个数为基数
99+
let temp = arr[left];
100+
while(left < right) {
101+
while(left < right && arr[right] >= temp) right--;
102+
arr[left] = arr[right];
103+
while(left < right && arr[left] < temp) left++;
104+
arr[right] = arr[left];
105+
}
106+
arr[left] = temp;
107+
return left;
108+
}
109+
recursive(nums, 0, nums.length-1);
110+
}
111+
```
112+
113+
### 交换法
114+
```
115+
function quickSort1(nums) {
116+
function recursive(arr, left, right) {
117+
if(left >= right) return;
118+
let index = partition(arr, left, right);
119+
recursive(arr, left, index - 1);
120+
recursive(arr, index + 1, right);
121+
return arr;
122+
}
123+
function partition(arr, left, right) {
124+
let temp = arr[left];
125+
let p = left + 1;
126+
let q = right;
127+
while(p <= q) {
128+
while(p <= q && arr[p] < temp) p++;
129+
while(p <= q && arr[q] > temp) q--;
130+
if(p <= q) {
131+
[arr[p], arr[q]] = [arr[q], arr[p]];
132+
p++;
133+
q--;
134+
}
135+
}
136+
[arr[left], arr[q]] = [arr[q], arr[left]];
137+
return q;
138+
}
139+
recursive(nums, 0, nums.length-1);
140+
}
141+
```
142+
143+
## 归并排序
144+
递归将数组分为两个序列,有序合并这两个序列。
145+
```
146+
function mergeSort(nums) {
147+
// 有序合并两个数组
148+
function merge(l1, r1, l2, r2) {
149+
let arr = [];
150+
let index = 0;
151+
let i = l1, j = l2;
152+
while(i <= r1 && j <= r2) {
153+
arr[index++] = nums[i] < nums[j] ? nums[i++] : nums[j++];
154+
}
155+
while(i <= r1) arr[index++] = nums[i++];
156+
while(j <= r2) arr[index++] = nums[j++];
157+
for(let t=0; t<index; t++) {
158+
nums[l1 + t] = arr[t];
159+
}
160+
}
161+
// 递归将数组一分为二
162+
function recursive(left, right) {
163+
if(left >= right) return;
164+
let mid = parseInt((right - left) / 2) + left;
165+
recursive(left, mid);
166+
recursive(mid+1, right);
167+
merge(left, mid, mid+1, right);
168+
return nums;
169+
}
170+
recursive(0, nums.length-1);
171+
}
172+
```

0 commit comments

Comments
 (0)