数据结构之集合

本文介绍了如何手写实现JavaScript中的集合数据结构,包括添加、删除、检查元素等基本操作,并展示了并集、交集和差集的运算。此外,还探讨了多重集的概念,允许存储重复元素的集合,并提供了相应的增删查改方法。通过实例展示了这些数据结构的使用。
摘要由CSDN通过智能技术生成

1. 手写集合

集合是一种保存不重复数据的数据结构,和ES6中的Set类类似。

  1. add(element) 添加元素
  2. delete(element) 删除元素
  3. has(element) 是否包含某元素
  4. clear() 删除所有元素
  5. size() 返回元素个数
  6. values() 返回由所有元素组成的数组
class SetCustom {
  constructor() {
    this.items = {};
  }

  add(element) {
    if (this.has(element)) return false;

    this.items[element] = element;
    return true;
  }

  delete(element) {
    if (this.has(element)) {
      delete this.items[element];
      return true;
    }
    return false;
  }

  has(element) {
    return Object.prototype.hasOwnProperty.call(this.items, element);
  }

  size() {
    return Object.keys(this.items).length;
  }

  clear() {
    this.items = {};
  }

  values() {
    return Object.values(this.items);
  }
}

let set = new SetCustom();
set.add('Alice');
set.add('Bob');
set.add('Jack');
set.delete('Bob');
console.log('values', set.values());
console.log('size', set.size());

2. 集合的运用

  1. 并集:对于给定的两个集合,返回包含两个集合中所有元素的新集合。
  2. 交集:对于给定的两个集合,返回两个集合共有的元素的新集合。
  3. 差集:对于给定的两个集合,返回存在于第一个集合但是不存在于第二个集合的元素组成的新集合。
  4. 子集:验证一个集合是不是另一个元素的子集。
class Set extends SetCustom {
  constructor() {
    super();
  }

  // 并集
  union(otherSet) {
    let result = new Set();
    let thisValue = this.values();
    let otherValue = otherSet.values();
    [...thisValue, ...otherValue].forEach(item => {
      result.add(item);
    });
    return result;
  }

  // 交集
  intersection(otherSet) {
    let thisValue = this.values();
    let result = new Set();
    thisValue.forEach(item => {
      if (otherSet.has(item)) {
        result.add(item);
      }
    });
    return result;
  }

  // 差集
  difference(otherSet) {
    let thisValue = this.values();
    let result = new Set();
    thisValue.forEach(item => {
      if (!otherSet.has(item)) {
        result.add(item);
      }
    });
    return result;
  }

  // 判断是否是子集
  isSubsetOf(otherSet) {
    if (this.size() > otherSet.size()) return false;

    let isSubset = true;
    this.values().forEach(item => {
      if (!otherSet.has(item)) {
        isSubset = false;
      }
    });
    return isSubset;
  }

}

let setTest = new Set();
let otherTest = new Set();
setTest.add('Alice');
setTest.add('Bob');
setTest.add('Jack');

otherTest.add('Alice');
otherTest.add('Vivian');
console.log(setTest.union(otherTest).values());
console.log(setTest.intersection(otherTest).values());
console.log(setTest.difference(otherTest).values());
console.log('isSubsetOf:', otherTest.isSubsetOf(setTest));

3. 多重集

能够保存重复数据的集合就是多重集。

class Multiset {
  constructor() {
    this.items = {};
  }

  add(element) {
    if (this.has(element)) {
      this.items[element].count += 1;
    }
    else {
      this.items[element] = {
        value: element,
        count: 1
      };
    }
  }

  delete(element) {
    if (this.has(element)) {
      const thisValue = this.items[element];
      if (thisValue.count === 1) {
        delete this.items[element]
      }
      else {
        thisValue.count -= 1;
      }
      return true;
    }
    return false;
  }

  has(element) {
    return Object.prototype.hasOwnProperty.call(this.items, element);
  }

  size() {
    let count = 0;
    Object.keys(this.items).forEach(key => {
      let element = this.items[key];
      count += element.count;
    });

    return count;
  }

  values() {
    let result = [];
    console.log(this.items)
    Object.keys(this.items).forEach(key => {
      let element = this.items[key];
      for (let i = 0; i < element.count; i++) {
        result.push(element.value);
      }
    });

    return result;
  }

  clear() {
    this.items = {};
  }

}

let multiset = new Multiset();
multiset.add('Alice');
multiset.add('Bob');
multiset.add('Jack');
multiset.add('Bob');
console.log('values', multiset.values());
console.log('size', multiset.size());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值