JavaScript 数据结构与算法(八)集合
集合
几乎每种编程语言中,都有集合结构。集合比较常见的实现方式是哈希表,这里使用 JavaScript 的 Object 进行封装。
集合特点
封装集合
ES6 中的 Set
就是一个集合类,这里我们重新封装一个 Set
类,了解集合的底层实现。
集合常见的操作
add(value)
向集合添加一个新的项。
remove(value)
从集合移除一个值。
has(value)
如果值在集合中,返回 true
,否则返回 false
。
clear()
移除集合中的所有项。
size()
返回集合所包含元素的数量。与数组的 length
属性类似。
values()
返回一个包含集合中所有值的数组。
- 还有其他的方法,用的不多,这里不做封装。
代码实现
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 31 32 33 34 35 36 37 38 39 40
| class Set { constructor() { this.items = {}; }
has(value) { return this.items.hasOwnProperty(value); }
add(value) { if (this.has(value)) return false; this.items[value] = value; return true; }
remove(value) { if (!this.has(value)) return false; delete this.items[value]; }
clear() { this.items = {}; }
size() { return Object.keys(this.items).length; }
values() { return Object.keys(this.items); } }
|
代码测试
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
| const set = new Set();
set.add("abc"); set.add("abc"); set.add("123"); set.add("zxc"); console.log(set);
console.log(set.has("123")); console.log(set.has("456"));
set.remove("abc"); console.log(set);
console.log(set.size());
console.log(set.values());
set.clear(); console.log(set.values());
|
集合间的操作
- 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。
- 交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合。
- 差集:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。
- 子集:验证一个给定集合是否是另一个集合的子集。
并集的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| union(otherSet) { let unionSet = new Set();
for (let value of this.values()) { unionSet.add(value); }
for (let value of otherSet.values()) { unionSet.add(value); }
return unionSet; }
|
交集的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| intersection(otherSet) {
let intersectionSet = new Set();
for (let value of this.values()) { if (otherSet.has(value)) { intersectionSet.add(value); } }
return intersectionSet; }
|
差集的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| difference(otherSet) {
let differenceSet = new Set();
for (let value of this.values()) { if (!otherSet.has(value)) { differenceSet.add(value); } }
return differenceSet; }
|
子集的实现
1 2 3 4 5 6 7 8 9 10 11 12
| subset(otherSet) {
for (let value of this.values()) { if (!otherSet.has(value)) { return false; } } return true; }
|
集合的完整实现
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| export default class Set { constructor() { this.items = {}; }
has(value) { return this.items.hasOwnProperty(value); }
add(value) { if (this.has(value)) return false; this.items[value] = value; return true; }
remove(value) { if (!this.has(value)) return false; delete this.items[value]; }
clear() { this.items = {}; }
size() { return Object.keys(this.items).length; }
values() { return Object.keys(this.items); }
union(otherSet) { let unionSet = new Set();
for (let value of this.values()) { unionSet.add(value); }
for (let value of otherSet.values()) { unionSet.add(value); }
return unionSet; }
intersection(otherSet) { let intersectionSet = new Set();
for (let value of this.values()) { if (otherSet.has(value)) { intersectionSet.add(value); } }
return intersectionSet; }
difference(otherSet) { let differenceSet = new Set();
for (let value of this.values()) { if (!otherSet.has(value)) { differenceSet.add(value); } }
return differenceSet; }
subset(otherSet) { for (let value of this.values()) { if (!otherSet.has(value)) { return false; } } return true; } }
|