Skip to content

Commit 30ecd18

Browse files
committed
feat: add heap sort algorithm and template
1 parent 3b59b1a commit 30ecd18

File tree

8 files changed

+257
-0
lines changed

8 files changed

+257
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
- [归并排序(算法模板)](./basic/sorting/MergeSort/README.md)
4444
- [快速排序(算法模板)](./basic/sorting/QuickSort/README.md)
4545
- [希尔排序](./basic/sorting/ShellSort/README.md)
46+
- [堆排序(算法模板)](./basic/sorting/HeapSort/README.md)
4647

4748
### 查找算法
4849

README_EN.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Complete solutions to [LeetCode](https://leetcode.com/problemset/all/), [LCOF](h
3939
- [Merge Sort(Algorithm Template)](./basic/sorting/MergeSort/README.md)
4040
- [Quick Sort(Algorithm Template)](./basic/sorting/QuickSort/README.md)
4141
- [Shell Sort](./basic/sorting/ShellSort/README.md)
42+
- [Heap Sort(Algorithm Template)](./basic/sorting/HeapSort/README.md)
4243

4344
### Searching
4445

basic/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [选择排序](./sorting/SelectionSort/README.md)
88
- [归并排序](./sorting/MergeSort/README.md)
99
- [快速排序](./sorting/QuickSort/README.md)
10+
- [堆排序](./sorting/HeapSort/README.md)
1011

1112
## 查找算法
1213

basic/README_EN.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- [Merge Sort](./sorting/MergeSort/README.md)
99
- [Quick Sort](./sorting/QuickSort/README.md)
1010
- [Shell Sort](./sorting/ShellSort/README.md)
11+
- [Heap Sort](./sorting/HeapSort/README.md)
1112

1213
## Searching
1314

basic/sorting/HeapSort/Main.java

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import java.util.Scanner;
2+
3+
public class Main {
4+
private static int[] h = new int[100010];
5+
private static int size;
6+
7+
public static void main(String[] args) {
8+
Scanner sc = new Scanner(System.in);
9+
int n = sc.nextInt(), m = sc.nextInt();
10+
for (int i = 1; i <= n; ++i) {
11+
h[i] = sc.nextInt();
12+
}
13+
size = n;
14+
for (int i = n / 2; i > 0; --i) {
15+
down(i);
16+
}
17+
while (m-- > 0) {
18+
System.out.print(h[1] + " ");
19+
h[1] = h[size--];
20+
down(1);
21+
}
22+
}
23+
24+
public static void down(int u) {
25+
int t = u;
26+
if (u * 2 <= size && h[u * 2] < h[t]) {
27+
t = u * 2;
28+
}
29+
if (u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) {
30+
t = u * 2 + 1;
31+
}
32+
if (t != u) {
33+
swap(t, u);
34+
down(t);
35+
}
36+
}
37+
38+
public static void up(int u) {
39+
while (u / 2 > 0 && h[u / 2] > h[u]) {
40+
swap(u / 2, u);
41+
u /= 2;
42+
}
43+
}
44+
45+
public static void swap(int i, int j) {
46+
int t = h[i];
47+
h[i] = h[j];
48+
h[j] = t;
49+
}
50+
}

basic/sorting/HeapSort/Main.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
n, m = list(map(int, input().split(" ")))
2+
h = [0] + list(map(int, input().split(" ")))
3+
4+
size = n
5+
6+
7+
def down(u):
8+
t = u
9+
if u * 2 <= size and h[u * 2] < h[t]:
10+
t = u * 2
11+
if u * 2 + 1 <= size and h[u * 2 + 1] < h[t]:
12+
t = u * 2 + 1
13+
if t != u:
14+
h[t], h[u] = h[u], h[t]
15+
down(t)
16+
17+
18+
def up(u):
19+
while u // 2 > 0 and h[u // 2] > h[u]:
20+
h[u // 2], h[u] = h[u], h[u // 2]
21+
u //= 2
22+
23+
24+
for i in range(n // 2, 0, -1):
25+
down(i)
26+
27+
res = []
28+
for i in range(m):
29+
res.append(h[1])
30+
h[1] = h[size]
31+
size -= 1
32+
down(1)
33+
34+
print(' '.join(list(map(str, res))))

basic/sorting/HeapSort/README.md

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# 堆排序
2+
3+
**堆排序算法模板:**
4+
5+
```java
6+
// h存储堆中的值,h[1]是堆顶,h[x]的左儿子是2x,右儿子是2x+1
7+
int[] h = new int[N];
8+
9+
// 向下调整
10+
void down(int u) {
11+
int t = u;
12+
if (u * 2 <= size && h[u * 2] < h[t]) {
13+
t = u * 2;
14+
}
15+
if (u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) {
16+
t = u * 2 + 1;
17+
}
18+
if (t != u) {
19+
swap(t, u);
20+
down(t);
21+
}
22+
}
23+
24+
// 向上调整
25+
void up(int u) {
26+
while (u / 2 > 0 && h[u / 2] > h[u]) {
27+
swap(u / 2, u);
28+
u /= 2;
29+
}
30+
}
31+
32+
// O(n) 建堆
33+
for (int i = n / 2; i > 0; --i) {
34+
down(i);
35+
}
36+
```
37+
38+
## 题目描述
39+
40+
输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。
41+
42+
**输入格式**
43+
44+
第一行包含整数 n 和 m。
45+
46+
第二行包含 n 个整数,表示整数数列
47+
48+
**输出格式**
49+
50+
共一行,包含 m 个整数,表示整数数列中前 m 小的数。
51+
52+
**数据范围**
53+
54+
- 1 ≤ m ≤ n ≤ 10^5
55+
- 1 ≤ 数列中元素 ≤ 10^9
56+
57+
**输入样例:**
58+
59+
```
60+
5 3
61+
4 5 1 3 2
62+
```
63+
64+
**输出样例:**
65+
66+
```
67+
1 2 3
68+
```
69+
70+
## 代码实现
71+
72+
<!-- tabs:start -->
73+
74+
### **Python3**
75+
76+
```python
77+
n, m = list(map(int, input().split(" ")))
78+
h = [0] + list(map(int, input().split(" ")))
79+
80+
size = n
81+
82+
83+
def down(u):
84+
t = u
85+
if u * 2 <= size and h[u * 2] < h[t]:
86+
t = u * 2
87+
if u * 2 + 1 <= size and h[u * 2 + 1] < h[t]:
88+
t = u * 2 + 1
89+
if t != u:
90+
h[t], h[u] = h[u], h[t]
91+
down(t)
92+
93+
94+
def up(u):
95+
while u // 2 > 0 and h[u // 2] > h[u]:
96+
h[u // 2], h[u] = h[u], h[u // 2]
97+
u //= 2
98+
99+
100+
for i in range(n // 2, 0, -1):
101+
down(i)
102+
103+
res = []
104+
for i in range(m):
105+
res.append(h[1])
106+
h[1] = h[size]
107+
size -= 1
108+
down(1)
109+
110+
print(' '.join(list(map(str, res))))
111+
```
112+
113+
### **Java**
114+
115+
```java
116+
import java.util.Scanner;
117+
118+
public class Main {
119+
private static int[] h = new int[100010];
120+
private static int size;
121+
122+
public static void main(String[] args) {
123+
Scanner sc = new Scanner(System.in);
124+
int n = sc.nextInt(), m = sc.nextInt();
125+
for (int i = 1; i <= n; ++i) {
126+
h[i] = sc.nextInt();
127+
}
128+
size = n;
129+
for (int i = n / 2; i > 0; --i) {
130+
down(i);
131+
}
132+
while (m-- > 0) {
133+
System.out.print(h[1] + " ");
134+
h[1] = h[size--];
135+
down(1);
136+
}
137+
}
138+
139+
public static void down(int u) {
140+
int t = u;
141+
if (u * 2 <= size && h[u * 2] < h[t]) {
142+
t = u * 2;
143+
}
144+
if (u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) {
145+
t = u * 2 + 1;
146+
}
147+
if (t != u) {
148+
swap(t, u);
149+
down(t);
150+
}
151+
}
152+
153+
public static void up(int u) {
154+
while (u / 2 > 0 && h[u / 2] > h[u]) {
155+
swap(u / 2, u);
156+
u /= 2;
157+
}
158+
}
159+
160+
public static void swap(int i, int j) {
161+
int t = h[i];
162+
h[i] = h[j];
163+
h[j] = t;
164+
}
165+
}
166+
```
167+
168+
<!-- tabs:end -->

basic/summary.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
- [选择排序](/basic/sorting/SelectionSort/README.md)
66
- [归并排序](/basic/sorting/MergeSort/README.md)
77
- [快速排序](/basic/sorting/QuickSort/README.md)
8+
- [堆排序](/basic/sortring/HeapSort/README.md)
89
- 查找算法
910
- [二分查找](/basic/searching/BinarySearch/README.md)

0 commit comments

Comments
 (0)