JavaScript数据结构与算法3

63 阅读2分钟

参考

集合(Set)

  • 无序的、不重复的
    • 不能通过下标值访问,元素唯一
    • 集合的并、交、差、子集操作中,要注意引用值的赋值是浅复制,指向同一个地址空间
// 用Object的key来实现
// 因为是用Object的keys来存储数据,所以集合不包含集合、以及字符串和
// 数值类型元素无法区分
functio Set(){
  this.items = {};
  
  // add(value):向集合添加一个value
  Set.prototype.add = function(value){
    if(this.has(value))
      return false;
    this.items[value + ''] = value;
    return true;
  }  

  // remove(value):从集合移除value
  Set.prototype.remove = function(value){
    if(!this.has(value))    
      return false;
    delete this.items[value + ''];
    return true;
  }
  
  // has(value):value在集合中返回true,否则返回false
  Set.prototype.has = function(value){
    return this.items.hasOwnProperty(value);
  }  

  // clear():移除集合的元素个数
  Set.prototype.clear = function(){
    this.items = {};
  }  

  // size():返回集合中元素的个数
  Set.prototype.size = function(){
    return Object.keys(this.items).length;
  }  

  // values():返回一个包含集合所有元素的数组
  Set.prototype.values = function(){
    return Object.keys(this.items);
  }
  
// this.items:A    otherSet.items:B
  // union(otherSet):并集
  Set.prototype.union = function(otherSet){
    // 创建新的集合
    var newSet = new Set();
    
    // 将集合A的元素添加到newSet
    var values = this.values();
    for(var i = 0; i < values.length; i ++){
      newSet.add(values[i]);
    }
 
    // 将集合B的元素添加到newSet
    values = otherSet.values();
    for(var i = 0; i < values.length; i ++){
      newSet.add(values[i]);
    }
    
    return newSet;
  }  

  // intersection(otherSet):交集
  Set.prototype.intersection = function(otherSet){
    // 创建一个新集合
    var newSet = new Set();
    // 判断A集合的元素是否在B集合中,B有则添加到newSet集合中
    var values = this.values();
    for(var i = 0; i < values.length; i ++){
      if(otherSet.has(values[i])){
         newSet.add(values[i]);
      }
    }
    return newSet;
  }

  // difference(otherSet):A - B 差集
  Set.prototype.difference = function(otherSet){
    var newSet = new Set();
    var values = this.values();
    // 将A中特有的元素添加到newSet中,B没有的就加入到newSet
    for(var i = 0; i < values.length; i ++){
      if(!otherSet.has(values[i])){
        newSet.add(values[i]);
      }
    }
    return newSet;
  }

  // subset(otherSet):子集
  Set.prototype.subset = fucntion(otherSet){
  // 如果A中有元素不在B中,则不是B的子集
    var values = this.values();
    for(var i = 0; i < values.length; i ++){
      if(!otherSet.has(values[i])){
        return false;
      }
    }
    return true;
  }
}

    // 测试代码
    console.log("A test");
    var setA = new Set();
    console.log(setA.add("moon"));
    console.log(setA.add("difference"));
    console.log(setA.add("moon"));
    console.log(setA.add("sun"));
    console.log(setA.add("hao"));
    console.log(setA.size());
    console.log(setA.values());


    console.log(setA.has("moon"));
    console.log(setA.remove("hao"));
    console.log(setA.remove("hao"));
    console.log("A:",setA.values());


    var setB = new Set();
    setB.add(1);
    setB.add("sun");
    setB.add("hao");
    setB.add("moon");
    console.log("B:",setB.values());
    console.log("A U B:",setA.union(setB));


    console.log("-----");
    console.log("A intersection B:",setA.intersection(setB));
    console.log("A-B:",setA.difference(setB));
    console.log("B-A:",setB.difference(setA));


    var setC = setB;
    console.log("C:",setC.values());
    console.log("A is B subset:",setA.subset(setB));
    console.log("c is B subset:",setC.subset(setB));