概念

  • 集合是由一组无序且唯一(即不能重复)的项组成的
  • 该数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中
  • 集合的存储是值 和 值对应

集合方法

  • add(element):向集合添加一个新元素。
  • delete(element):从集合移除一个元素。
  • has(element):如果元素在集合中,返回true,否则返回false。
  • clear():移除集合中的所有元素。
  • size():返回集合所包含元素的数量。它与数组的length 属性类似。
  • values():返回一个包含集合中所有值(元素)的数组。

实现

构造存储结构:对象{value: value} 值 和 值

  1. class set {
  2. constructor() {
  3. this.items = {};
  4. }
  5. }

判断元素唯一性的方法

  1. has(ele) {
  2. return Object.prototype.hasOwnProperty.call(this.items, ele);
  3. }

各种方法的实现

  1. add(ele) {
  2. if (!this.has(ele)) {
  3. this.items[ele] = ele;
  4. return true;
  5. }
  6. return false;
  7. }
  8. delete(ele) {
  9. if (this.has(ele)) {
  10. delete this.items[ele];
  11. return true;
  12. }
  13. return false;
  14. }
  15. clear() {
  16. this.items = {};
  17. }
  18. size() {
  19. // return Object.keys(this.items).length // es6写法
  20. let cnt = 0;
  21. for (let key in this.items) {
  22. if (this.has(key)) {
  23. cnt++;
  24. }
  25. }
  26. return cnt;
  27. }
  28. values() {
  29. let values = [];
  30. for (let key in this.items) {
  31. if (this.has(key)) {
  32. values.push(this.items[key]);
  33. }
  34. }
  35. return values;
  36. }

交集,并集,差集,子集

  • 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。
  • 交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合。
  • 差集:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。
  • 子集:验证一个给定集合是否是另一集合的子集。

并集运算

  1. union(otherSet) {
  2. let unionSet = new MySet(); // 存储最终的并集集合数据
  3. this.values().forEach(value => {
  4. unionSet.add(value);
  5. });
  6. otherSet.values().forEach(value => {
  7. unionSet.add(value);
  8. });
  9. return unionSet;
  10. }

交集运算

  1. intersection(otherSet) {
  2. let intersection = new MySet();
  3. let values = this.values(); // 预存当前集合值数组
  4. // 判断哪个大哪个小
  5. let otherValues = otherSet.values();
  6. let bigSet = undefined;
  7. let smallSet = undefined;
  8. if (values.length > otherValues.length) {
  9. bigSet = values;
  10. smallSet = otherValues;
  11. } else {
  12. bigSet = otherValues;
  13. smallSet = values;
  14. }
  15. for (let i = 0; i < smallSet.length; i++) {
  16. // 直接判断可能导致性能损耗,应该判断小的那个集合
  17. if (bigSet.has(smallSet[i])) {
  18. intersection.add(smallSet[i]);
  19. }
  20. }
  21. }

差集运算

集合 - 图1

  1. difference(otherSet) {
  2. // 需要深拷贝
  3. let differenceSet = this;
  4. let intersection = this.intersection(otherSet);
  5. // 删除交集元素
  6. intersection.values().forEach(value => {
  7. differenceSet.delete(value);
  8. });
  9. return differenceSet;
  10. }

子集运算

集合 - 图2

  1. isSubsetOf(otherSet) {
  2. if (this.size() > otherSet.size()) {
  3. return false;
  4. }
  5. let isSubset = true;
  6. this.values().every(value => {
  7. if (!otherSet.has(value)) {
  8. isSubset = false;
  9. return false;
  10. }
  11. return true;
  12. });
  13. return isSubset;
  14. }

完整代码

  1. class MySet {
  2. constructor() {
  3. this.items = {};
  4. }
  5. // 判断元素的唯一性
  6. has(ele) {
  7. return Object.prototype.hasOwnProperty.call(this.items, ele);
  8. }
  9. add(ele) {
  10. if (!this.has(ele)) {
  11. this.items[ele] = ele;
  12. return true;
  13. }
  14. return false;
  15. }
  16. delete(ele) {
  17. if (this.has(ele)) {
  18. delete this.items[ele];
  19. return true;
  20. }
  21. return false;
  22. }
  23. clear() {
  24. this.items = {};
  25. }
  26. size() {
  27. // return Object.keys(this.items).length // es6写法
  28. let cnt = 0;
  29. for (let key in this.items) {
  30. if (this.has(key)) {
  31. cnt++;
  32. }
  33. }
  34. return cnt;
  35. }
  36. values() {
  37. let values = [];
  38. for (let key in this.items) {
  39. if (this.has(key)) {
  40. values.push(this.items[key]);
  41. }
  42. }
  43. return values;
  44. }
  45. union(otherSet) {
  46. let unionSet = new MySet(); // 存储最终的并集集合数据
  47. this.values().forEach(value => {
  48. unionSet.add(value);
  49. });
  50. otherSet.values().forEach(value => {
  51. unionSet.add(value);
  52. });
  53. return unionSet;
  54. }
  55. intersection(otherSet) {
  56. let intersection = new MySet();
  57. let values = this.values(); // 预存当前集合值数组
  58. // 判断哪个大哪个小
  59. let otherValues = otherSet.values();
  60. let bigSet = undefined;
  61. let smallSet = undefined;
  62. if (values.length > otherValues.length) {
  63. bigSet = values;
  64. smallSet = otherValues;
  65. } else {
  66. bigSet = otherValues;
  67. smallSet = values;
  68. }
  69. for (let i = 0; i < smallSet.length; i++) {
  70. // 直接判断可能导致性能损耗,应该判断小的那个集合
  71. if (bigSet.has(smallSet[i])) {
  72. intersection.add(smallSet[i]);
  73. }
  74. }
  75. }
  76. difference(otherSet) {
  77. // 需要深拷贝
  78. let differenceSet = this;
  79. let intersection = this.intersection(otherSet);
  80. // 删除交集元素
  81. intersection.values().forEach(value => {
  82. differenceSet.delete(value);
  83. });
  84. return differenceSet;
  85. }
  86. isSubsetOf(otherSet) {
  87. if (this.size() > otherSet.size()) {
  88. return false;
  89. }
  90. let isSubset = true;
  91. this.values().every(value => {
  92. if (!otherSet.has(value)) {
  93. isSubset = false;
  94. return false;
  95. }
  96. return true;
  97. });
  98. return isSubset;
  99. }
  100. }