File tree Expand file tree Collapse file tree 3 files changed +146
-8
lines changed Expand file tree Collapse file tree 3 files changed +146
-8
lines changed Original file line number Diff line number Diff line change @@ -2,19 +2,53 @@ import 'MaxHeap.dart';
2
2
3
3
/**
4
4
* 堆排序
5
+ * 以及堆排序优化
5
6
*/
6
7
class HeapSort {
8
+ HeapSort () {}
7
9
8
- HeapSort () {
9
-
10
- }
11
10
static sort <E extends Comparable <E >>(List data) {
12
11
MaxHeap <E > maxHeap = MaxHeap .withCapacity (10 );
13
- for (E e in data){
12
+ for (E e in data) {
14
13
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-- ) {
17
17
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
+ }
18
31
}
19
32
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
+ }
Original file line number Diff line number Diff line change
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
+ }
Original file line number Diff line number Diff line change 13
13
9 . 二分搜索,二分搜索优化
14
14
10 . 二分搜索树,二分搜索树搜索、移除最大最小值
15
15
11 . 集合 和 映射
16
- 12 . 堆
16
+ 12 . 堆
17
17
18
18
#### SDK版本
19
19
1 . 版本:2.12.3
You can’t perform that action at this time.
0 commit comments