Skip to content

Commit 81609dd

Browse files
author
tianqing.liang
committed
堆排序优化,以及最小堆
1 parent 345ea69 commit 81609dd

File tree

3 files changed

+146
-8
lines changed

3 files changed

+146
-8
lines changed

12-Heap/HeapSort.dart

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,53 @@ import 'MaxHeap.dart';
22

33
/**
44
* 堆排序
5+
* 以及堆排序优化
56
*/
67
class HeapSort {
8+
HeapSort() {}
79

8-
HeapSort() {
9-
10-
}
1110
static sort<E extends Comparable<E>>(List data) {
1211
MaxHeap<E> maxHeap = MaxHeap.withCapacity(10);
13-
for (E e in data){
12+
for (E e in data) {
1413
maxHeap.add(e);
15-
}
16-
for (int i = data.length - 1; i >= 0; i --)
14+
};
15+
16+
for (int i = data.length - 1; i >= 0; i--) {
1717
data[i] = maxHeap.extractMax();
18+
}
19+
}
20+
21+
static sort2<T extends Comparable<T>>(List data) {
22+
if (data.length <= 1) return;
23+
24+
for (int i = (data.length - 2) / 2 as int; i >= 0; i--){
25+
_siftDown(data, i, data.length);
26+
}
27+
for (int i = data.length - 1; i >= 0; i--) {
28+
_swap(data, 0, i);
29+
_siftDown(data, 0, i);
30+
}
1831
}
1932

20-
}
33+
// 对 data[0, n) 所形成的最大堆中,索引 k 的元素,执行 siftDown
34+
static _siftDown<T>(List? data, int k, int n) {
35+
while (2 * k + 1 < n) {
36+
int j = 2 * k + 1; // 在此轮循环中,data[k]和data[j]交换位置
37+
if (j + 1 < n && data![j + 1].compareTo(data[j]) > 0) {
38+
j++;
39+
}
40+
// data[j] 是 leftChild 和 rightChild 中的最大值
41+
if (data![k].compareTo(data[j]) >= 0) {
42+
break;
43+
}
44+
_swap(data, k, j);
45+
k = j;
46+
}
47+
}
48+
49+
static _swap<E>(List arr, int i, int j) {
50+
E t = arr[i];
51+
arr[i] = arr[j];
52+
arr[j] = t;
53+
}
54+
}

12-Heap/MinHeap.dart

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* 最小堆
3+
*/
4+
class MinHeap<E extends Comparable<E>> {
5+
List? data;
6+
7+
MinHeap.withCapacity(int capacity) {
8+
data = List.filled(capacity, E, growable: true);
9+
}
10+
11+
MinHeap.withEmpty() {
12+
data = List.empty(growable: true);
13+
}
14+
15+
// 返回堆中的元素个数
16+
int? size() {
17+
return data!.length;
18+
}
19+
20+
// 返回一个布尔值, 表示堆中是否为空
21+
bool isEmpty() {
22+
return data!.isEmpty;
23+
}
24+
25+
int _parent(int index) {
26+
if (index == 0) {
27+
throw Exception("index-0 doesn't have parent.");
28+
}
29+
return ((index - 1) / 2).toInt();
30+
}
31+
32+
// 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引
33+
int _leftChild(int index) {
34+
return index * 2 + 1;
35+
}
36+
37+
// 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引
38+
int _rightChild(int index) {
39+
return index * 2 + 2;
40+
}
41+
42+
// 向堆中添加元素
43+
add(E e) {
44+
data!.add(e);
45+
siftUp(data!.length - 1);
46+
}
47+
48+
siftUp(int k) {
49+
while (k > 0 && data![_parent(k)].compareTo(data![k]) > 0) {
50+
_swap(k, _parent(k));
51+
k = _parent(k);
52+
}
53+
}
54+
55+
// 看堆中的最大元素
56+
E findMin() {
57+
if (data!.length == 0)
58+
throw new Exception("Can not findMax when heap is empty.");
59+
return data![0];
60+
}
61+
62+
// 取出堆中最大元素
63+
E extractMax() {
64+
E ret = findMin();
65+
_swap(0, data!.length - 1);
66+
data!.removeLast();
67+
_siftDown(0);
68+
69+
return ret;
70+
}
71+
72+
_siftDown(int k) {
73+
while (_leftChild(k) < data!.length) {
74+
int j = _leftChild(k); // 在此轮循环中,data[k]和data[j]交换位置
75+
if (j + 1 < data!.length && data![j + 1].compareTo(data![j]) < 0) {
76+
j++;
77+
}
78+
// data[j] 是 leftChild 和 rightChild 中的最大值
79+
if (data![k].compareTo(data![j]) <= 0) {
80+
break;
81+
}
82+
_swap(k, j);
83+
k = j;
84+
}
85+
}
86+
87+
// 取出堆中的最大元素,并且替换成元素e
88+
E replace(E e) {
89+
E ret = findMin();
90+
data![0] = e;
91+
;
92+
_siftDown(0);
93+
return ret;
94+
}
95+
96+
_swap(int i, int j) {
97+
if (i < 0 || i >= data!.length || j < 0 || j >= data!.length)
98+
throw new Exception("Index is illegal.");
99+
100+
E t = data![i];
101+
data![i] = data![j];
102+
data![j] = t;
103+
}
104+
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
9. 二分搜索,二分搜索优化
1414
10. 二分搜索树,二分搜索树搜索、移除最大最小值
1515
11. 集合 和 映射
16-
12.
16+
12.
1717

1818
#### SDK版本
1919
1. 版本:2.12.3

0 commit comments

Comments
 (0)