js数据结构与算法_集合

集合

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

你也可以把集合想象成一个既没有重复元素,也没有顺序概念的数组。

创建

创建一个集合需要声明一些集合可用的方法,现在我们尝试模拟与 ECMAScript 6 实现相同的 Set 类

function Set() {
  var items = {}; //在这里我们用对象来实现,但也可以用数组实现
  this.add = function(value) {
    //向集合添加一个新的项。
    if (!this.has(value)) {
      items[value] = value;
      return true; //返回 true ,表示添加了这个值
    }
    return false; //如果集合中已经有这个值,就返回 false ,表示没有添加它
  };
  this.remove = function(value) {
    if (this.has(value)) {
      //如果存在,就从集合中移除 value
      delete items[value];
      return true; //表示值被移除
    }
    return false;
  };
  this.has = function(value) {
    //它会被 add 、 remove 等其他方法调用
    //如果值在集合中,返回 true ,否则返回 false 。
    return items.hasOwnProperty(value);
  };
  this.clear = function() {
    //移除集合中的所有项
    items = {}; //重置items对象,把一个空对象重新赋值给它
  };
  this.size = function() {
    //返回集合所包含元素的数量。与数组的 length 属性类似。
    // return Object.keys(items).length 这是另一种方法,有兼容性
    var count = 0;
    for (var prop in items) {
      if (items.hasOwnProperty(prop))
        ++count; 
    }
    return count;
  };
  this.values = function() {
    //返回一个包含集合中所有值的数组
    // return  Object.keys(items) 这是另一种方法,有兼容性
    var keys = [];
    for (var key in items) {
      keys.push(key);
    }
    return keys;
  };

  //......常用的集合操作
}

var s1 = new Set();
s1.add(1001);
s1.add(1002);
console.log(s1.size()); //3
console.log(s1.values()); //["1001", "1002"]
console.log(s1.add(1002)); //false
console.log(s1.size()); //2
console.log(s1.values());  //["1001", "1002"]

集合操作

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

//并集
this.union = function(otherSet) {
  var unionSet = new Set(); //需要创建一个新的集合,代表两个集合的并集
  var values = this.values(); //获取第一个集合
  for (var i = 0; i < values.length; i++) {
    unionSet.add(values[i]);
  }
  values = otherSet.values();
  for (var i = 0; i < values.length; i++) {
    unionSet.add(values[i]);
  }
  return unionSet; //
};

//交集
this.intersection = function(otherSet) {
  var intersectionSet = new Set(); //创建一个新的集合,代表两个集合的并集
  var values = this.values();
  for (var i = 0; i < values.length; i++) {
    if (otherSet.has(values[i])) {
      //判断并返回共有的元素
      intersectionSet.add(values[i]);
    }
  }
  return intersectionSet;
};

//差集: difference 方法会得到所有存在于集合A但不存在于B的值
this.difference = function(otherSet) {
  var differenceSet = new Set();
  var values = this.values();
  for (var i = 0; i < values.length; i++) {
    if (!otherSet.has(values[i])) {
      //与intersection方法在实现上唯一的区别就是此处
      differenceSet.add(values[i]);
    }
  }
  return differenceSet;
};

//子集:集合A是B的子集(或集合B包含了A),表示为A⊆B
this.subset = function(otherSet) {
  if (this.size() > otherSet.size()) {
    return false; //不是子集(子集的元素个数需要小于或等于要比较的集合)
  } else {
    var values = this.values();
    for (var i = 0; i < values.length; i++) {
      if (!otherSet.has(values[i])) {
        //验证这些元素也存在于 otherSet 中
        return false; //如果所有元素都存在于 otherSet 中,行 {4} 就不会被执行
      }
    }
    return true;
  }
};

var s1 = new Set();
s1.add(1001);
s1.add(1002);
s1.add(1004);
console.log(s1.size());   //3
console.log(s1.values()); //["1001", "1002", "1004"]
console.log(s1.add(1002)); //false
console.log(s1.size()); //3
console.log(s1.values()); //["1001", "1002", "1004"]
console.log(`-----------------------------------`);
var s2 = new Set();
s2.add(1001);
s2.add(1002);
s2.add(1003);
console.log(s2.union(s1).values()); // 并集 ["1001", "1002", "1003", "1004"]
console.log(s2.intersection(s1).values()); //交集 ["1001", "1002"]
console.log(s1.difference(s2).values()); //差集 存在s1但不存在s2  ["1004"]
console.log(s2.difference(s1).values()); //差集 存在s2但不存在s1  ["1003"]
console.log(`-----------------------------------`);
var s3 = new Set();
s3.add(1001);
s3.add(1002);
s3.add(1003);
s3.add(1004);
console.log(s1.subset(s3)); // s1是s3的子集 true
console.log(s2.subset(s3)); // s2是s3的子集 true

你可能感兴趣的:(js数据结构与算法_集合)