【数据结构】自己动手使用JavaScript实现字典、哈希表、集合(第二篇)

1. 字典(Dictionary)

<待补充>

export class Dictionary {
    constructor(toStrFn = defaultToString) {
        this.toStrFn = toStrFn;
        this.table = {};
    }

    set(key, value) {
        if(key != null && value !=null) {
            const tableKey = this.toStrFn(key)
            const pair = new ValuePair(key, value)
            this.table[tableKey] = pair;
            return true;
        }
        return false;
    }

    get(key) {
        if(this.hasKey(key)) {
            const tableKey = this.toStrFn(key);
            const pair = this.table[tableKey];
            return pair.value;
        }
        return undefined;
    }

    remove(key) {
        if(this.hasKey(key)) {
            const tableKey = this.toStrFn(key);
            delete this.table[tableKey];
            return true;
        }
        return false;
    }

    hasKey(key) {
        const tableKey = this.toStrFn(key);
        return this.table[tableKey] != null;
    }

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

    isEmpty() {
        return this.size() === 0
    }

    keys() {
        return this.keyValues().map(item => item.key);
    }

    values() {
        return this.keyValues().map(item => item.value);
    }

    keyValues() {
        return Object.values(this.table);
    }

    toString() {
        if(this.isEmpty()) {
            return '';
        }
        const valuePairs = this.keyValues();
        let str = valuePairs[0].toString();
        for(let i = 1; i < valuePairs.length; i++) {
            str = `${str}, ${valuePairs[i].toString()}`;
        }
        return str;
    }
}

class ValuePair {
    constructor(key, value) {
        this.key = key;
        this.value = value;
    }

    toString() {
        let keyStr = '', valueStr = '';
        try {
            keyStr = `${this.key}`;
        } catch(e) {
            keyStr = this.key.toString();
        }
        try {
            valueStr = `${this.value}`;
        } catch(e) {
            valueStr = this.value.toString();
        }
        return `{${keyStr}: ${valueStr}}`;
    }
}

const defaultToString = item => {
    if(item === null) {
        return 'NULL';
    }
    if(item === undefined) {
        return 'UNDEFINED';
    }
    if(typeof item === 'string' || item instanceof String) {
        return `${item}`;
    }
    return item.toString();
}

const dic = new Dictionary();
const obj = {};
const sym = Symbol();

dic.set('a', 1);
dic.set('b', true);
dic.set(obj, 1);
dic.set(sym, 1);

2. 哈希表(Hash)

<待补充>

export class HashTable {
    constructor(toStrFn = defaultToString) {
        this.toStrFn = toStrFn;
        this.table = {};
    }

    put(key, value) {
        if(key != null && value !=null) {
            const tableKey = this.hashCode(key)
            const pair = new ValuePair(key, value)
            this.table[tableKey] = pair;
            return true;
        }
        return false;
    }

    get(key) {
        if(this.hasKey(key)) {
            const tableKey = this.hashCode(key);
            const pair = this.table[tableKey];
            return pair.value;
        }
        return undefined;
    }

    remove(key) {
        if(this.hasKey(key)) {
            const tableKey = this.hashCode(key);
            delete this.table[tableKey];
            return true;
        }
        return false;
    }

    forEach(fn) {
        const keys = this.keys();
        for(let i = 0; i < keys; i++) {
            const key = keys[i];
            const tableKey = this.hashCode(key);
            const item = this.item[tableKey];
            fn(item, key, i);
        }
    }

    hasKey(key) {
        const tableKey = this.hashCode(key);
        return this.table[tableKey] != null;
    }

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

    isEmpty() {
        return this.size() === 0
    }

    keys() {
        return this.keyValues().map(item => item.key);
    }

    values() {
        return this.keyValues().map(item => item.value);
    }

    keyValues() {
        return Object.values(this.table);
    }

    toString() {
        if(this.isEmpty()) {
            return '';
        }
        const valuePairs = this.keyValues();
        let str = valuePairs[0].toString();
        for(let i = 1; i < valuePairs.length; i++) {
            str = `${str}, ${valuePairs[i].toString()}`;
        }
        return str;
    }

    hashCode(key) {
        if(typeof key === 'number') {
            return key;
        }
        const tableKey = this.toStrFn(key);
        let hash = 0;
        for(let i = 0; i < tableKey.length; i++) {
            hash += tableKey.charCodeAt(i);
        }
        hash = hash % 72;
        return hash;
    }
}


class ValuePair {
    constructor(key, value) {
        this.key = key;
        this.value = value;
    }

    toString() {
        let keyStr = '', valueStr = '';
        try {
            keyStr = `${this.key}`;
        } catch(e) {
            keyStr = this.key.toString();
        }
        try {
            valueStr = `${this.value}`;
        } catch(e) {
            valueStr = this.value.toString();
        }
        return `{${keyStr}: ${valueStr}}`;
    }
}

const defaultToString = item => {
    if(item === null) {
        return 'NULL';
    }
    if(item === undefined) {
        return 'UNDEFINED';
    }
    if(typeof item === 'string' || item instanceof String) {
        return `${item}`;
    }
    return item.toString();
}

const dic = new Dictionary();
const obj = {};
const sym = Symbol();

dic.set('a', 1);
dic.set('b', true);
dic.set(obj, 1);
dic.set(sym, 1);

3. 集合(Set)

<待补充>

export class Set {
    constructor() {
        this.items = {};
        this.length = 0;
    }

    add(item) {
        if(this.has(item)) {
            return this;   
        }
        this.items[item] = item;
        this.length++;
        return this;
    }

    delete() {
        if(this.has(item)) {
            this.length--;
            return delete this.items[item];
        }
        return false;
    }

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

    has(item) {
        return item in this.items;
    }

    size() {
        return this.length;
    }

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

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

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

    forEach(callback) {
        let index = 0;
        for(let item in this.items) {
            if(this.items.hasOwnProperty(item)) {
                callback(item, index, this);
                index++;
            }
        }
    }

    union(set) {
        const unionSet = new Set();
        if(set instanceof Set) {
            this.forEach((key) => {
                if(!unionSet.has(key)) {
                    unionSet.add(this.items[key]);
                }
            });
            set.forEach((key) => {
                if(!unionSet.has(key)) {
                    unionSet.add(this.items[key]);
                }
            });
        }
        return unionSet;
    }

    intersection(set) {
        const intersectionSet = new Set();
        if(set instanceof Set) {
            const keys = this.keys().concat(set.keys());
            for(const key of keys) {
                if(this.has(key) && set.has(key)) {
                    intersectionSet.add(this.items[key]);
                }
            }
        }
        return intersectionSet;
    }


    difference() {

    }
}

下一篇:【数据结构】自己动手使用JavaScript实现二叉搜索树、二叉堆(第三篇)-CSDN博客

注:以上,如有不合理之处,还请帮忙指出,大家一起交流学习~

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值