Skip to content

Commit 684f27c

Browse files
authored
feat: add dart code for chapter_stack_and_queue and chapter_hashing (#445)
* feat: add dart code for chapter stack and queue * feat: add dart code for chapter_hashing * Update array_hash_map.dart
1 parent cac38c0 commit 684f27c

File tree

11 files changed

+975
-0
lines changed

11 files changed

+975
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/**
2+
* File: array_hash_map.dart
3+
* Created Time: 2023-03-29
4+
* Author: liuyuxin (gvenusleo@gmail.com)
5+
*/
6+
7+
/* 键值对 int -> String */
8+
class Entry {
9+
int key;
10+
String val;
11+
Entry(this.key, this.val);
12+
}
13+
14+
/* 基于数组简易实现的哈希表 */
15+
class ArrayHashMap {
16+
late List<Entry?> _buckets;
17+
18+
ArrayHashMap() {
19+
// 初始化数组,包含 100 个桶
20+
_buckets = List.filled(100, null);
21+
}
22+
23+
/* 哈希函数 */
24+
int _hashFunc(int key) {
25+
final int index = key % 100;
26+
return index;
27+
}
28+
29+
/* 查询操作 */
30+
String? get(int key) {
31+
final int index = _hashFunc(key);
32+
final Entry? pair = _buckets[index];
33+
if (pair == null) {
34+
return null;
35+
}
36+
return pair.val;
37+
}
38+
39+
/* 添加操作 */
40+
void put(int key, String val) {
41+
final Entry pair = Entry(key, val);
42+
final int index = _hashFunc(key);
43+
_buckets[index] = pair;
44+
}
45+
46+
/* 删除操作 */
47+
void remove(int key) {
48+
final int index = _hashFunc(key);
49+
_buckets[index] = null;
50+
}
51+
52+
/* 获取所有键值对 */
53+
List<Entry> entrySet() {
54+
List<Entry> entrySet = [];
55+
for (final Entry? pair in _buckets) {
56+
if (pair != null) {
57+
entrySet.add(pair);
58+
}
59+
}
60+
return entrySet;
61+
}
62+
63+
/* 获取所有键 */
64+
List<int> keySet() {
65+
List<int> keySet = [];
66+
for (final Entry? pair in _buckets) {
67+
if (pair != null) {
68+
keySet.add(pair.key);
69+
}
70+
}
71+
return keySet;
72+
}
73+
74+
/* 获取所有值 */
75+
List<String> values() {
76+
List<String> valueSet = [];
77+
for (final Entry? pair in _buckets) {
78+
if (pair != null) {
79+
valueSet.add(pair.val);
80+
}
81+
}
82+
return valueSet;
83+
}
84+
85+
/* 打印哈希表 */
86+
void printHashMap() {
87+
for (final Entry kv in entrySet()) {
88+
print("${kv.key} -> ${kv.val}");
89+
}
90+
}
91+
}
92+
93+
/* Driver Code */
94+
void main() {
95+
/* 初始化哈希表 */
96+
final ArrayHashMap map = ArrayHashMap();
97+
98+
/* 添加操作 */
99+
// 在哈希表中添加键值对 (key, value)
100+
map.put(12836, "小哈");
101+
map.put(15937, "小啰");
102+
map.put(16750, "小算");
103+
map.put(13276, "小法");
104+
map.put(10583, "小鸭");
105+
print("\n添加完成后,哈希表为\nKey -> Value");
106+
map.printHashMap();
107+
108+
/* 查询操作 */
109+
// 向哈希表输入键 key ,得到值 value
110+
String? name = map.get(15937);
111+
print("\n输入学号 15937 ,查询到姓名 $name");
112+
113+
/* 删除操作 */
114+
// 在哈希表中删除键值对 (key, value)
115+
map.remove(10583);
116+
print("\n删除 10583 后,哈希表为\nKey -> Value");
117+
map.printHashMap();
118+
119+
/* 遍历哈希表 */
120+
print("\n遍历键值对 Key->Value");
121+
map.entrySet().forEach((kv) => print("${kv.key} -> ${kv.val}"));
122+
print("\n单独遍历键 Key");
123+
map.keySet().forEach((key) => print("$key"));
124+
print("\n单独遍历值 Value");
125+
map.values().forEach((val) => print("$val"));
126+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* File: hash_map.dart
3+
* Created Time: 2023-03-29
4+
* Author: liuyuxin (gvenusleo@gmail.com)
5+
*/
6+
7+
/* Driver Code */
8+
void main() {
9+
/* 初始化哈希表 */
10+
final Map<int, String> map = {};
11+
12+
/* 添加操作 */
13+
// 在哈希表中添加键值对 (key, value)
14+
map[12836] = "小哈";
15+
map[15937] = "小啰";
16+
map[16750] = "小算";
17+
map[13276] = "小法";
18+
map[10583] = "小鸭";
19+
print("\n添加完成后,哈希表为\nKey -> Value");
20+
map.forEach((key, value) => print("$key -> $value"));
21+
22+
/* 查询操作 */
23+
// 向哈希表输入键 key ,得到值 value
24+
final String? name = map[15937];
25+
print("\n输入学号 15937 ,查询到姓名 $name");
26+
27+
/* 删除操作 */
28+
// 在哈希表中删除键值对 (key, value)
29+
map.remove(10583);
30+
print("\n删除 10583 后,哈希表为\nKey -> Value");
31+
map.forEach((key, value) => print("$key -> $value"));
32+
33+
/* 遍历哈希表 */
34+
print("\n遍历键值对 Key->Value");
35+
map.forEach((key, value) => print("$key -> $value"));
36+
print("\n单独遍历键 Key");
37+
map.forEach((key, value) => print("$key"));
38+
print("\n单独遍历值 Value");
39+
map.forEach((key, value) => print("$value"));
40+
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/**
2+
* File: array_deque.dart
3+
* Created Time: 2023-03-28
4+
* Author: liuyuxin (gvenusleo@gmail.com)
5+
*/
6+
7+
/* 基于环形数组实现的双向队列 */
8+
class ArrayDeque {
9+
late List<int> _nums; // 用于存储双向队列元素的数组
10+
late int _front; // 队首指针,指向队首元素
11+
late int _queSize; // 双向队列长度
12+
13+
/* 构造方法 */
14+
ArrayDeque(int capacity) {
15+
this._nums = List.filled(capacity, 0);
16+
this._front = this._queSize = 0;
17+
}
18+
19+
/* 获取双向队列的容量 */
20+
int capacity() {
21+
return _nums.length;
22+
}
23+
24+
/* 获取双向队列的长度 */
25+
int size() {
26+
return _queSize;
27+
}
28+
29+
/* 判断双向队列是否为空 */
30+
bool isEmpty() {
31+
return _queSize == 0;
32+
}
33+
34+
/* 计算环形数组索引 */
35+
int index(int i) {
36+
// 通过取余操作实现数组首尾相连
37+
// 当 i 越过数组尾部后,回到头部
38+
// 当 i 越过数组头部后,回到尾部
39+
return (i + capacity()) % capacity();
40+
}
41+
42+
/* 队首入队 */
43+
void pushFirst(int num) {
44+
if (_queSize == capacity()) {
45+
throw Exception("双向队列已满");
46+
}
47+
// 队首指针向左移动一位
48+
// 通过取余操作,实现 _front 越过数组头部后回到尾部
49+
_front = index(_front - 1);
50+
// 将 num 添加至队首
51+
_nums[_front] = num;
52+
_queSize++;
53+
}
54+
55+
/* 队尾入队 */
56+
void pushLast(int num) {
57+
if (_queSize == capacity()) {
58+
throw Exception("双向队列已满");
59+
}
60+
// 计算尾指针,指向队尾索引 + 1
61+
int rear = index(_front + _queSize);
62+
// 将 num 添加至队尾
63+
_nums[rear] = num;
64+
_queSize++;
65+
}
66+
67+
/* 队首出队 */
68+
int popFirst() {
69+
int num = peekFirst();
70+
// 队首指针向右移动一位
71+
_front = index(_front + 1);
72+
_queSize--;
73+
return num;
74+
}
75+
76+
/* 队尾出队 */
77+
int popLast() {
78+
int num = peekLast();
79+
_queSize--;
80+
return num;
81+
}
82+
83+
/* 访问队首元素 */
84+
int peekFirst() {
85+
if (isEmpty()) {
86+
throw Exception("双向队列为空");
87+
}
88+
return _nums[_front];
89+
}
90+
91+
/* 访问队尾元素 */
92+
int peekLast() {
93+
if (isEmpty()) {
94+
throw Exception("双向队列为空");
95+
}
96+
// 计算尾元素索引
97+
int last = index(_front + _queSize - 1);
98+
return _nums[last];
99+
}
100+
101+
/* 返回数组用于打印 */
102+
List<int> toArray() {
103+
// 仅转换有效长度范围内的列表元素
104+
List<int> res = List.filled(_queSize, 0);
105+
for (int i = 0, j = _front; i < _queSize; i++, j++) {
106+
res[i] = _nums[index(j)];
107+
}
108+
return res;
109+
}
110+
}
111+
112+
/* Driver Code */
113+
void main() {
114+
/* 初始化双向队列 */
115+
final ArrayDeque deque = ArrayDeque(10);
116+
deque.pushLast(3);
117+
deque.pushLast(2);
118+
deque.pushLast(5);
119+
print("双向队列 deque = ${deque.toArray()}");
120+
121+
/* 访问元素 */
122+
final int peekFirst = deque.peekFirst();
123+
print("队首元素 peekFirst = $peekFirst");
124+
final int peekLast = deque.peekLast();
125+
print("队尾元素 peekLast = $peekLast");
126+
127+
/* 元素入队 */
128+
deque.pushLast(4);
129+
print("元素 4 队尾入队后 deque = ${deque.toArray()}");
130+
deque.pushFirst(1);
131+
print("元素 1 队首入队后 deque = ${deque.toArray()}");
132+
133+
/* 元素出队 */
134+
final int popLast = deque.popLast();
135+
print("队尾出队元素 = $popLast,队尾出队后 deque = ${deque.toArray()}");
136+
final int popFirst = deque.popFirst();
137+
print("队首出队元素 = $popFirst,队首出队后 deque = ${deque.toArray()}");
138+
139+
/* 获取双向队列的长度 */
140+
final int size = deque.size();
141+
print("双向队列的长度 size = $size");
142+
143+
/* 判断双向队列是否为空 */
144+
final bool isEmpty = deque.isEmpty();
145+
print("双向队列是否为空 = $isEmpty");
146+
}

0 commit comments

Comments
 (0)