#前言
本文根据《数据结构与算法 JavaScript 描述》来写的,相当于个人的读书笔记。
#字典
字典是一种以键-值对形式存储数据的数据结构。
#JS 模拟实现字典
实现基本的增加、查找、删除、展示功能
class Dictionary {
constructor() {
this.dataStore = [];
}
add(key, value) {
this.dataStore[key] = value;
}
find(key) {
return this.dataStore[key];
}
remove(key) {
delete this.dataStore[key];
}
showAll() {
Object.keys(this.dataStore).forEach(key => {
console.log(key + "->" + this.dataStore[key]);
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#添加辅助功能
获取字典中的元素个数count、清除字典内的所有元素clear
class Dictionary {
// ...
// 注意这里不能使用length,否则返回0
count() {
return Object.keys(this.dataStore).length;
}
// 同样这里设置length为0无效
clear() {
Object.keys(this.dataStore).forEach(key => {
delete this.dataStore[key];
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
#为字典添加排序功能
class Dictionary {
// ...
// 只需要在原先的基础上添加sort方法进行排序
showAll() {
Object.keys(this.dataStore)
.sort()
.forEach(key => {
console.log(key + "->" + this.dataStore[key]);
});
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
#集合
集合是一种包含不同元素的数据结构。集合中的元素称为成员。集合的两个最重要的特性是:首先,集合中的成员是无序的;其次,集合中不允许相同的成员存在。
#集合的定义
- 不包含任何成员的集合称为空集,全集则是包含一切可能成员的集合
- 如果两个集合的成员完全相同,则称两个集合相等
- 如果一个集合中所有的成员都属于另外一个集合,则前一个集合称为后一个集合的子集
#集合的操作
- 并集:将两个集合中的成员合并,得到一个新集合
- 交集:两个集合中共同存在的成员组成一个新的集合
- 补集:属于一个集合而不属于另一个集合的成员组成的集合
#JS 模拟实现 Set 类
class Set {
constructor() {
this.dataStore = [];
}
add(data) {
if (this.dataStore.indexOf(data) < 0) {
this.dataStore.push(data);
return true;
}
return false;
}
remove(data) {
const index = this.dataStore.indexOf(data);
if (index > -1) {
this.dataStore.splice(index, 1);
return true;
}
return false;
}
// 显示集合中的成员
show() {
return this.dataStore;
}
size() {
return this.dataStore.length;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#Set 类的操作
- union()——并集
- intersect()——交集
- subset()——判定子集
- difference()——补集
#并集
class Set {
// ...
contains(data) {
return this.dataStore.indexOf(data) > -1;
}
union(set) {
const nSet = new Set();
this.dataStore.forEach(ele => nSet.add(ele));
set.show().forEach(ele => {
if (!this.contains(ele)) {
nSet.add(ele);
}
});
return nSet;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#交集
class Set {
// ...
intersect(set) {
const nSet = new Set();
this.dataStore.forEach(ele => {
if (set.contains(ele)) {
nSet.add(ele);
}
});
return nSet;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
#判定子集
class Set {
// ...
// 判断该集合是否是set的子集
subset(set) {
if (this.size() > set.size()) return false;
for (let i = 0; i < this.size(); i++) {
if (!set.contains(this.dataStore[i])) {
return false;
}
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
#补集
class Set {
// ...
// 该方法返回一个新集合,该集合包含的是那些属于第一个集合不属于第二个集合(set)的成员,如果需要两个集合不同的元素,那么需要遍历第二个集合同时比较第一个集合
difference(set) {
const nSet = new Set();
this.dataStore.forEach(ele => {
if (!set.contains(ele)) {
nSet.add(ele);
}
});
return nSet;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
#ES6 中提供的新数据结构 Set
#语法介绍
- add: 添加某个值,返回 Set 结构本身
- delete: 删除某个值,返回一个布尔值表示是否删除成功
- size: 返回 Set 中的成员总数
- has: 返回一个布尔值,表示该值是否为 Set 成员
- clear: 清除所有成员,没有返回值
- keys: 使用 for...of 遍历,遍历的是 key
- values: 使用 for...of 遍历,遍历的是 value
- entries: 使用 for...of 遍历,遍历的是[key, value]
- forEach: 与数组一致,直接在变量值遍历,
set.forEach((value, key) => {})
const s = new Set();
s.add("1");
s.add("2");
s.add(NaN);
s.add(NaN);
console.log(s.size); // 3
console.log(s.has(NaN)); // true
for (const key of s.keys()) {
console.log(key);
}
s.forEach((value, key) => {
console.log(value, key);
});
s.delete(NaN);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#几点说明
- 在自定义的 Set 中不能判断 NaN,但是 ES6 提供的 Set 中能判断 NaN,并且认为 NaN 为同一个值
- 无论自定义 Set 还是 ES6 提供的 Set 都不能判断对象,都会认为对象都是不相等的,这也符合 JS 语法认为两个对象不相等