TypeScript数据结构与算法(11)基于二分搜索树实现的Map

实现Map类之前,需要先自实现Interface_Map<K, V>的接口,源码如下

export interface Interface_Map<K, V> {
    add(k: K, v: V): void;
    remove(k: K): V;
    contains(k: K): boolean;
    get(k: K): V;
    set(k: K, v: V): void;
    getSize(): number;
    isEmpty(): boolean;
}
DataStruct_BLT_Map类源码如下
import { Interface_Map } from "../Interface_Map";

//自定义comparable
type Comparable = {
    compareTo(that: Comparable): number;
    equals(that: Comparable): boolean;
}


class Node<K, V> {
    public key: K;
    public value: V;
    public left: Node<K, V>; //左孩子
    public right: Node<K, V>;//右孩子
    constructor(key: K, value: V) {
        this.key = key;
        this.value = value;
        this.left = null;
        this.right = null;
    }
}

//二分搜索树特定的数据类型
export class MapBST_Key implements Comparable {
    constructor(private e: any) {

    }
    //判断大于小于
    compareTo(that: MapBST_Key): number {
        return this.e - that.e;
    }
    //判断等于
    equals(that: MapBST_Key): boolean {
        return this.e === that.e;
    }
}

export class MapBST_Value {
    private data: any;
    public constructor(data) {
        this.data = data;
    }
}

/**
* Autor: Created by 李清风 on 2021-01-02.
* Desc: 基于二分树的映射Map实现,关键词:使用二分树实现map,key必须是可以比较的,推荐使用自定义类型
*/
export class DataStruct_BLT_Map<K, V> implements Interface_Map<K, V> {


    private root: Node<K, V>;
    private size: number;

    public constructor() {
        this.root = null;
        this.size = 0;
    }


    //添加元素操作
    add(k: K, v: V): void {
        this.root = this._add(this.root, k, v);
    }

    //加入元素
    private _add(node: Node<K, V>, key: K | any, value: V) {
        if (node == null) {
            this.size++;
            return new Node(key, value);
        }
        if (key.compareTo(node.key) < 0) {
            node.left = this._add(node.left, key, value);
        } else if (key.compareTo(node.key) > 0) {
            node.right = this._add(node.right, key, value);
        } else if (key.equals(node.key)) {
            node.value = value; //如果存在这个key,则直接更新
        }
    }

    private _getNode(node: Node<K, V>, key: K | any) {
        if (node == null) {
            return null;
        }
        if (key.compareTo(node.key) < 0) {
            return this._getNode(node.left, key);
        } else if (key.compareTo(node.key) > 0) {
            return this._getNode(node.right, key);
        } else {
            return node;//如果相等,则直接返回
        }
    }

    //删除某个元素
    remove(key: K): V {
        let node = this._getNode(this.root, key);
        if (node != null) {
            this.root = this._remove(this.root, key)
        }
    }

    private _remove(node: Node<K, V>, key: K | any) {
        if (node == null) {
            return null;
        }
        //左子树比较删除
        if (key.compareTo(node.key) < 0) {
            node.left = this._remove(node.left, key);
            return node;
        } else if (key.compareTo(node.key) > 0) {
            //右子树比较删除
            node.right = this._remove(node.right, key);
            return node;
        } else {
            //成功找到待删除元素e
            if (node.left == null) {
                let right = node.right;
                node.right = null;
                this.size--;
                return right;
            }
            if (node.right == null) {
                let left = node.left;
                node.left = null;
                this.size--;
                return left;
            }

            //待删除节点左右子树都不为空的情况
            //找到比待删除节点大的最小节点,即待删除节点右子树的最小节点
            //用这个节点顶替待删除的节点位置
            let successor = this._searchMinElement(node.right);
            successor.right = this._removeMin(node.right);
            this.size++
            successor.left = node.left;
            node.left = node.right = null;
            this.size--;
            return successor;
        }
    }

    private _searchMinElement(node: Node<K, V>): Node<K, V> {
        if (node.left == null) {
            return node;
        }
        return this._searchMinElement(node.left);
    }

    _removeMin(node: Node<K, V | any>) {
        if (node.left == null) {
            let rightNode = node.right;
            node.right = null;
            this.size--;
            return rightNode;
        }

        node.left = this._removeMin(node.left);
        return node;
    }


    //查看是否包含某个值
    contains(k: K): boolean {
        return this._getNode(this.root, k);
    }

    //获取某个值
    get(k: K): V {
        let node = this._getNode(this.root, k);
        return node == null ? null : node.value;
    }

    //更新某个值
    set(k: K, v: V): void {
        let node = this._getNode(this.root, k);
        if (node == null) {
            throw new Error("doesn't exist!");
        }
        node.value = v;
    }


    getSize(): number {
        return this.size;
    }


    isEmpty(): boolean {
        return this.size == 0;
    }

}

 

posted @ 2021-01-21 18:10  CYNLINQ  阅读(177)  评论(0)    收藏  举报