常见数据结构Javascript实现

存储

集合

// 集合
class Set {
    constructor() {
        this._list = []
    }
    get size() {
        return this._list.length;
    }
    get isEmpty() {
        return this._list.length === 0;
    }
    add(e) {
        if (!this._list.includes(e)) {
            this._list.push(e)
        }
        return this;
    }
    delete(e) {
        let list = this._list;
        let index = list.indexOf(e)
        if (index != -1) {
            list.splice(index,1)
        }
        return index != -1;
    }
    has(e) {
        return this._list.includes(e)
    }
    clear() {
        this._list.length = 0;
    }
    iterator() { // 迭代器
        let _this = this;
        return {
            _i: 0,
            next() {
                if (this.hasNext()) {
                    return _this._list[this._i++];
                }
            },
            hasNext() {
                return this._i !== _this.size;
            }
        }
    }
}

链表

// 链表
class LinkedListNode {
    constructor(e, next=null) {
        this.e = e;
        this.next = next;
    }
}
// 单向链表
class LinkedList {
    constructor() {
        this._dummyhead = new LinkedListNode(null);
        this._tail = null; // 尾指针
        this._size = 0;
    }
    get size() {
        return this._size;
    }
    get isEmpty() {
        return this._size == 0;
    }

    // 插入元素
    insert(index, e) {
        if (index < 0 || index>this._size) {
            throw new RangeError("index is invalid");
        }
        let cur = this._dummyhead;
        for (let i=0; i<index; i++) {
            cur = cur.next;
        }
        cur.next = new LinkedListNode(e, cur.next);
        if (this._size === index) {
            this._tail = cur.next;
        }
        this._size++;
    }
    // 插入表头
    unshift(e) {
        this._dummyhead.next = new LinkedListNode(e, this._dummyhead.next);
        if (this._size == 0) {
            this._tail = this._dummyhead.next;
        }
        this._size++;
    }
    // 插入表尾
    push(e) {
        if (this._size == 0) {
            this._dummyhead.next = new LinkedListNode(e);
            this._tail = this._dummyhead.next;
        } else {
            this._tail.next = new LinkedListNode(e);
            this._tail = this._tail.next;
        }
        this._size++;
    }
    
    // 删除元素
    removeElement(e) {
        if (this.isEmpty) {
            return new Error("Element is empty");
        }
        let prev = this._dummyhead;
        while (prev != null) {
            if (Object.is(prev.next.e,e)) {
                break;
            }
            prev = prev.next;
        }
        if (prev != null) {
            let ret = prev.next;
            prev.next = ret.next;
            ret.next = null;
            if (Object.is(ret.e, this._tail.e)) {
                this._tail = prev;
            }
            this._size--;
            return ret;
        }
        return null;
    }
    // 根据位置删除元素
    removeIndex(index) {
        if (index < 0 || index>this._size) {
            throw new RangeError("index is invalid");
        }
        if (this.isEmpty) {
            return new Error("Element is empty");
        }
        let prev = this._dummyhead;
        let ret;
        for (let i=0; i<index; i++) {
            prev = prev.next;
        }
        ret = prev.next;
        prev.next = ret.next;
        ret.next = null;
        if (Object.is(ret.e, this._tail.e)) {
            this._tail = prev;
        }
        this._size--;
        return ret;
    }
    pop() {
        return this.removeIndex(this._size-1);
    }
    shift() {
        return this.removeIndex(0);
    }

    // 查找元素
    find(e) {
        let cur = this._dummyhead.next;
        let index = 0;

        while (cur !== null) {
            if (Object.is(cur.e, e)) {
                break;
            }
            index++;
            cur = cur.next;
        }
        if (cur == null) {
            return -1;
        } else {
            return index;
        }
    }
    contains(e) {
        let result = this.find(e);
        return result != -1 ? true : false;
    }
    // 访问元素
    get(index) {
        if (index < 0 || index>this._size) {
            throw new RangeError("index is invalid");
        }
        let cur = this._dummyhead.next;
        for (let i=0; i<index; i++) {
            cur = cur.next;
        }
        return cur;
    }
    toString() {
        let res = "";
        let cur = this._dummyhead.next;

        for (let i=0,len=this._size; i<len; i++) {
            res += cur.e;
            if (i != len-1) {
                res += " > ";
            }
            cur = cur.next;
        }
        return res;
    }
    iterator() { // 迭代器
        return {
            _item: this._dummyhead,
            next() {
                if (this.hasNext()) {
                    let ret = this._item.next;
                    this._item = this._item.next;
                    return ret;
                }
                return null;
            },
            hasNext() {
                return this._item.next !== null; 
            }
        }
    }
}

双向链表

class LinkedListNode {
    constructor(item, next = null, prev = null) {
        this.item = item;
        this.next = next;
        this.prev = prev;
    }
}
// 双向链表
class LinkedList {
    constructor() {
        this._dummyhead = new LinkedListNode(null);
        this._tail = null; // 尾指针
        this._size = 0;
    }
    get size() {
        return this._size;
    }
    get isEmpty() {
        return this._size === 0;
    }
    // 插入元素
    insert(index, e) {
        if (index < 0 || index > this._size) {
            throw new RangeError("index is invalid");
        }
        let cur = this._dummyhead;
        for (let i = 0; i < index; i++) {
            cur = cur.next;
        }
        cur.next = new LinkedListNode(e, cur.next, cur);
        if (cur.next.next) {
            cur.next.next.prev = cur.next;
        }
        if (this._size === index) {
            this._tail = cur.next;
        }
        this._size++;
    }
    // 插入表头
    unshift(e) {
        this._dummyhead.next = new LinkedListNode(e, this._dummyhead.next);
        if (this._size == 0) {
            this._tail = this._dummyhead.next;
        }
        this._size++;
    }
    // 插入表尾
    push(e) {
        if (this._size == 0) {
            this._dummyhead.next = new LinkedListNode(e, null, this._dummyhead);
            this._tail = this._dummyhead.next;
        } else {
            this._tail.next = new LinkedListNode(e, null, this._tail);
            this._tail = this._tail.next;
        }
        this._size++;
    }
    // 删除元素
    removeElement(e) {
        if (this.isEmpty) {
            return new Error("Element is empty");
        }
        let prev = this._dummyhead;
        while (prev != null) {
            if (prev.next !== null && Object.is(prev.next.item, e)) {
                break;
            }
            prev = prev.next;
        }
        if (prev != null) {
            let ret = prev.next;
            prev.next = ret.next;
            if (ret.next) {
                ret.next.prev = prev; // 调整上一个元素指向
            }
            ret.next = null;
            if (Object.is(ret.item, this._tail.item)) {
                this._tail = prev;
            }
            this._size--;
            return ret;
        }
        return null;
    }
    // 根据位置删除元素
    removeIndex(index) {
        if (index < 0 || index > this._size) {
            throw new RangeError("index is invalid");
        }
        if (this.isEmpty) {
            return new Error("Element is empty");
        }
        let prev = this._dummyhead;
        let ret;
        for (let i = 0; i < index; i++) {
            prev = prev.next;
        }
        ret = prev.next;
        prev.next = ret.next;
        if (ret.next) {
            ret.next.prev = prev; // 调整上一个元素指向
        }
        ret.next = null;
        if (Object.is(ret.item, this._tail.item)) {
            this._tail = prev;
        }
        this._size--;
        return ret;
    }
    pop() {
        return this.removeIndex(this.size - 1);
    }
    shift() {
        return this.removeIndex(0);
    }
    // 查找元素
    find(e) {
        let cur = this._dummyhead.next;
        let index = 0;

        while (cur !== null) {
            if (Object.is(cur.item, e)) {
                break;
            }
            index++;
            cur = cur.next;
        }
        if (cur == null) {
            return -1;
        } else {
            return index;
        }
    }
    contains(e) {
        let result = this.find(e);
        return result != -1 ? true : false;
    }
    // 访问元素
    get(index) {
        if (index < 0 || index > this._size) {
            throw new RangeError("index is invalid");
        }
        let cur = this._dummyhead.next;
        for (let i = 0; i < index; i++) {
            cur = cur.next;
        }
        return cur;
    }
    toString() {
        let res = "";
        let cur = this._dummyhead.next;

        for (let i = 0, len = this._size; i < len; i++) {
            res += cur.item;
            if (i != len - 1) {
                res += " > ";
            }
            cur = cur.next;
        }
        return res;
    }
    iterator() { // 迭代器
        return {
            _item: this._dummyhead,
            next() {
                if (this.hasNext()) {
                    let ret = this._item.next;
                    this._item = this._item.next;
                    return ret;
                }
                return null;
            },
            hasNext() {
                return this._item.next !== null; 
            }
        }
    }
}

队列

class Queue {
    constructor() {
        this.list = [];
    }
    enqueue(item) {
        this.list.push(item);
    }
    dequeue() {
        return this.list.shift();
    }
    get isEmpty() {
        return this.list.length === 0;
    }
    get size() {
        return this.list.length;
    }
}

class Stack {
    constructor() {
        this.list = [];
    }
    get isEmpty() {
        return this.list.length=== 0;
    }
    get size() {
        return this.list.length;
    }
    push(item) {
        this.list.push(item);
    }
    pop() {
        return this.list.pop();
    }
}

// 优先队列
class PriorityQueue {
    constructor() {
        // 先引入最大堆
        this._list = new MaxHeap();
    }
    get size() {
        return this._list.size;
    }
    get isEmpty() {
        return this._list.isEmpty;
    }
    get top() {
        return this._list.max;
    }
    enqueue(e) {
        this._list.push(e)
    }
    dequeue() {
        return this._list.pop();
    }
}

最大堆

// 数组从1开始计算,这样左子元素索引=2*k,右子元素=2*k+1;
// 如果从0开始计算,左子元素索引=2*k+1,右子元素=2*k+2;
// 插入时进行上浮操作,移到相应位置
// 弹出最大元素后再进行下沉操作,将现有最大元素排到顶部
class MaxHeap {
    constructor() {
        this.data = [];
    }
    get isEmpty() {return this.data.length === 0}
    get size() {return this.data.length}
    get max() {
        return this.data[0];
    }
    swap(x, y) {
        let temp = this.data[x]
        this.data[x] = this.data[y]
        this.data[y] = temp;
    }
// 返回完全二叉树的数组表示中,一个索引所表示的元素的父亲节点的索引
    parent(index){
        return Math.floor((index - 1) / 2);
    }
    // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引
    leftChild(index){
        return index * 2 + 1;
    }
    // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引
    rightChild(index){
        return index * 2 + 2;
    }
    // 向堆中添加元素
    push(e){
        this.data.push(e);
        this.siftUp(this.size - 1);
    }
    // 大的往上走
    siftUp(k){
        while(k > 0 && this.data[this.parent(k)] < this.data[k] ){
            this.swap(k, this.parent(k));
            k = this.parent(k);
        }
    }
    // 取出堆中最大元素
    pop(){
        let ret = this.max;
        this.swap(0, this.size - 1);
        this.data.pop();
        this.siftDown(0);
        return ret;
    }
    siftDown(k){
        while(this.leftChild(k) < this.size){
            let j = this.leftChild(k); // 在此轮循环中,data[k]和data[j]交换位置
            if( j + 1 < this.size && this.data[j+1] > this.data[j] )
                j ++;
            if(this.data[k] >= this.data[j])
                break;

            this.swap(k, j);
            k = j;
        }
    }

}

最小堆

// 数组从1开始计算,这样左子元素索引=2*k,右子元素=2*k+1;
// 如果从0开始计算,左子元素索引=2*k+1,右子元素=2*k+2;
// 插入时进行上浮操作,移到相应位置
// 弹出最大元素后再进行下沉操作,将现有最大元素排到顶部
class MinHeap {
    constructor() {
        this.data = [];
    }
    get isEmpty() {return this.data.length === 0}
    get size() {return this.data.length}
    get min() {
        return this.data[0];
    }
    swap(x, y) {
        let temp = this.data[x]
        this.data[x] = this.data[y]
        this.data[y] = temp;
    }
// 返回完全二叉树的数组表示中,一个索引所表示的元素的父亲节点的索引
    parent(index){
        return Math.floor((index - 1) / 2);
    }
    // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引
    leftChild(index){
        return index * 2 + 1;
    }
    // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引
    rightChild(index){
        return index * 2 + 2;
    }
    // 向堆中添加元素
    push(e){
        this.data.push(e);
        this.siftUp(this.size - 1);
    }
    // 小的往上走
    siftUp(k){
        while(k > 0 && this.data[this.parent(k)] > this.data[k] ){
            this.swap(k, this.parent(k));
            k = this.parent(k);
        }
    }
    // 取出堆中最大元素
    pop(){
        let ret = this.min;
        this.swap(0, this.size - 1);
        this.data.pop();
        this.siftDown(0);
        return ret;
    }
    // 大的往下走
    siftDown(k){
        while(this.leftChild(k) < this.size){
            let j = this.leftChild(k); // 在此轮循环中,data[k]和data[j]交换位置
            if( j + 1 < this.size && this.data[j+1] < this.data[j] )
                j ++;
            if(this.data[k] <= this.data[j])
                break;

            this.swap(k, j);
            k = j;
        }
    }

}

// 无向图,无方向无权重
// 经典算法:广度优先搜索、深度优先搜索、最短路径、单点连通性、v > w的路径、多点连通性
class Graph {
    constructor(V=10) {
        this.V = V; // 点
        this.E = 0; // 边
        this.adj = []; // 连通点
        for(let i=0; i<V; i++) {
            this.adj[i] = new Set()
        }
    }
    // 添加连通性
    // @param{Number}v 点
    // @param{Number}w 点
    addEdge(v,w) {
        this.adj[v].add(w)
        this.adj[w].add(v)
        this.E++;
    }
    // 返回附近连通点
    // @return{Set}
    Iterable(v) {return this.adj[v]}
    
}
// 广度优先搜索
class BreadthFirstPaths {
    constructor(graph, s) {
        this.marked = []; // 访问过的点
        this.edgeTo = []; // 记录访问过的路径
        this.s = s;
        this.bfs(graph, s)
    }
    bfs(graph, s) {
        let queue = [s];
        this.marked[s] = true;
        while(queue.length != 0) {
            s = queue.shift();
            graph.Iterable(s).forEach(item=>{
                if (!this.marked[item]) {
                    this.marked[item] = true;
                    this.edgeTo[item] = s;
                    queue.push(item)
                }
            })
        }
    }
    // s > v 的最短路径
    shortest(v) {
        if (!this.marked[v]) return null;
        let path = [];
        for (let x=v; x!=this.s; x=this.edgeTo[x]) {
            path.unshift(x)
        }
        path.unshift(this.s)
        return path;
    }
}

// 深度优先搜索
class DepthFirstPaths {
    constructor(graph, s) {
        this.marked = []; // 访问过的点
        this.edgeTo = []; // 记录访问过的路径
        this.s = s;
        this.dfs(graph, s);
    }
    dfs(graph, v) {
        this.marked[v] = true;
        graph.Iterable(v).forEach(item=>{
            if (!this.marked[item]) {
                this.edgeTo[item] = v;
                this.dfs(graph,item)
            }
        }) 
    }
    // s是否能到达点v,单点连通性
    hasPathTo(v) {
        return this.marked[v]
    }
    // s到达目标点v的路径
    pathTo(v) {
        if (!this.hasPathTo(v)) return null;
        let path = [];
        for (let x=v; x!=this.s; x=this.edgeTo[x]) {
            path.unshift(x)
        }
        path.unshift(this.s)
        return path;
    }
}
// 查找所有点的连通分量
class CC {
    constructor(graph) {
        this.marked = [];
        this._id = []; // 记录点之间的连通关系,值相同则为连通
        this._count = 0;
        for (let s=0; s<graph.V; s++) {
            if (!this.marked[s]) {
                this.dfs(graph, s)
                this._count++;
            }
        }
    }
    dfs(graph, v) {
        if (!this.marked[v]) {
            this.marked[v] = true;
            this._id[v] = this._count; // 连通的点回一直递归下去,而this._count 不会变,当递归结束才会++
            graph.Iterable(v).forEach(item=>{
                if (!this.marked[s]) {
                    this.dfs(graph, item)
                }
            })
        }
    }
    // v w是否连通
    connected(v, w) {
        return this._id[v] == this._id[w]
    }
    id(v) {return this._id[v]}
    get count() {return this._count}
}


查找

二分查找树

class Node {
    constructor(key, value, size = 0) {
        this.key = key;
        this.value = value;
        this.size = size;
        this.left = this.right = null;
    }
}
class BST {
    constructor() {
        this.root = null;
    }
    get size() {
        return this._getSize(this.root);
    }
    _getSize(node) {
        if (node === null) {
            return 0;
        } else {
            return node.size;
        }
    }
    get(key) {
        function _get(node, key) {
            if (node === null) return null;
            if (key > node.key) {
                return _get(node.right, key);
            } else if (key < node.key) {
                return _get(node.left, key);
            } else {
                return node.value;
            }
        }
        key = this._strToNum(key);
        return _get(this.root, key);
    }
    put(key, value) { 
        let _this = this;
        key = this._strToNum(key);
        this.root = _put(this.root, key, value);
        function _put(node, key, value) {
            if (node === null) { return new Node(key, value) };
            if (key < node.key) {
                node.left = _put(node.left, key, value);
            } else if (key > node.key) {
                node.right = _put(node.right, key, value);
            } else {
                node.value = value;
            }
            node.size = _this._getSize(node.left) + _this._getSize(node.right) + 1;
            return node;
        }
    }
    contains(key) {
        return this.get(key) !== null;
    }
    delete(key) {
        // 删除思路:拿到被删除元素的右子树最小的元素,放到当前位置。因为被删除元素的右子树最小的元素 满足 大于左子树任意一个且小于右子树任意一个,不会打破顺序。
        let ret = null;
        let _this = this;
        key = this._strToNum(key);
        function _delete(node, key) {
            if (node === null) { return null }
            if (key < node.key) {
                node.left = _delete(node.left, key);
            } else if (key > node.key) {
                node.right = _delete(node.right, key)
            } else {
                ret = node;
                if (node.right === null) return node.left;
                if (node.left === null) return node.right;
                node = _this._min(node.right);
                _this._deleteMin(node.right);
            }
            node.size = _this._getSize(node.left) + _this._getSize(node.right) + 1;
            return node;
        }
        this.root = _delete(this.root, key);
        return ret;
    }
    // 前序遍历
    preOrder() {
        _preOrder(this.root);
        function _preOrder(node) {
            if (node == null) {
                return;
            }
            console.log(node.value);
            _preOrder(node.left);
            _preOrder(node.right);
        }
    }
    // 中序遍历
    inOrder() {
        _inOrder(this.root);
        function _inOrder(node) {
            if (node == null) {
                return;
            }
            _inOrder(node.left);
            console.log(node.value);
            _inOrder(node.right);
        }
    }
    // 后序序遍历
    postOrder() {
        _postOrder(this.root);
        function _postOrder(node) {
            if (node == null) {
                return;
            }
            _postOrder(node.left);
            _postOrder(node.right);
            console.log(node.value);
        }
    }

    // 层序遍历
    levelOrder() {
        let queue = []; // 引入队列
        let node;
        queue.push(this.root);

        while (queue.length) {
            node = queue.shift();
            console.log(node.value);
            if (node.left != null) {
                queue.push(node.left);
            }
            if (node.right != null) {
                queue.push(node.right);
            }
        }
    }
    _min(node = this.root) { // 是按键值转成数字的大小比较,并非按照value比较,所以最小的指的是键值转成数字后的大小
        if (node === null) { return null }
        return _min(node);
        function _min(node) {
            if (node.left === null) return node;
            return _min(node.left);
        }
    }
    _deleteMin(node = this.root) { // 最左边那个就是最小的
        let ret = this._min(this.root);
        let _this = this;
        if (ret === null) { return null }
        this.root = _deleteMin(node);
        return ret;
        function _deleteMin(node) {
            if (node === null) { return node }
            if (node.left === null) {
                node = node.right;
            } else if (node.left.left === null) {
                node.left = node.left.right;
            } else {
                node.left = _deleteMin(node.left);
            }
            if (node) {
                node.size = _this._getSize(node.left) + _this._getSize(node.right) + 1;
            }
            return node;
        }
    }
    _strToNum(key) { // 将字符串转成数字,方便比较大小
        if (typeof key !== "string") { throw ("key need string type") }
        let num = "";
        for (let i = 0; i < key.length; i++) {
            num += String(key.charAt(i).charCodeAt());
        }
        return Number(num);
    }
}

AVL

class Node {
    constructor(key, value, height = 1) {
        this.key = key;
        this.value = value;
        this.height = height; 
        this.left = this.right = null;
    }
}
class AVL {
    constructor() {
        this.root = null;
    }
    get height() {
        return this._getHeight(this.root);
    }
    _getHeight(node) {
        if (node === null) {
            return 0;
        } else {return node.height}
    }
    _leftRotate(node) { // 右倾斜使用
        let n = node;
        node = node.right;
        n.right = node.left;
        node.left = n;
        n.height = Math.max(this._getHeight(n.left), this._getHeight(n.right))+1;
        node.height = Math.max(this._getHeight(node.left), this._getHeight(node.right))+1;
        return node;
    }
    _rightRotate(node) { // 左倾斜使用
        let n = node;
        node = node.left;
        n.left = node.right;
        node.right = n;
        n.height = Math.max(this._getHeight(n.left), this._getHeight(n.right))+1;
        node.height = Math.max(this._getHeight(node.left), this._getHeight(node.right))+1;
        return node;
    }
    _rlRotate(node) { // 右-左倾斜使用
        node.right = this._rightRotate(node.right);
        node = this._leftRotate(node);
        return node;
    }
    _lrRotate(node) { // 左-右倾斜使用
        node.left = this._leftRotate(node.left);
        node = this._rightRotate(node);
        return node;
    }
    _getBalanceFactor(node) { // 获取平衡因子用于判断倾斜状态
        if(node == null) {
            return 0;
        }
        return this._getHeight(node.left) - this._getHeight(node.right);
    }
    _rotate(node) { // 用于平衡二叉树
        let balanceFactor = this._getBalanceFactor(node);
        if (Math.abs(balanceFactor) > 1) { // 任意一边倾斜 任意一边高度差高于2
            if (balanceFactor > 1 && this._getBalanceFactor(node.left) >= 0) { // 左倾斜
                node = this._rightRotate(node);
            }
            if (balanceFactor < -1 && this._getBalanceFactor(node.right) <= 0) { // 右倾斜
                node = this._leftRotate(node);
            }
            if(balanceFactor > 1 && this._getBalanceFactor(node.left) < 0) { // 左-右倾斜
                node = this._lrRotate(node);
            }
            if (balanceFactor < -1 && this._getBalanceFactor(node.right) > 0) { // 右-左倾斜
                node = this._rlRotate(node);
            }
        }
        return node;
    }
    get(key) {
        function _get(node, key) {
            if (node === null) return null;
            if (key > node.key) {
                return _get(node.right, key);
            } else if (key < node.key) {
                return _get(node.left, key);
            } else {
                return node.value;
            }
        }
        key = this._strToNum(key);
        return _get(this.root, key);
    }
    put(key, value) { 
        let _this = this;
        key = this._strToNum(key);
        this.root = _put(this.root, key, value);
        function _put(node, key, value) {
            if (node === null) { return new Node(key, value) };
            if (key < node.key) {
                node.left = _put(node.left, key, value);
            } else if (key > node.key) {
                node.right = _put(node.right, key, value);
            } else {
                node.value = value;
            }
            node.height = Math.max(_this._getHeight(node.left), _this._getHeight(node.right))+1;
            return _this._rotate(node);
        }
    }
    contains(key) {
        return this.get(key) !== null;
    }
    delete(key) {
        // 删除思路:拿到被删除元素的右子树最小的元素,放到当前位置。
        // 因为被删除元素的右子树最小的元素 满足 大于左子树任意一个且小于右子树任意一个,不会打破顺序。
        let ret = null;
        let _this = this;
        key = this._strToNum(key);
        function _delete(node, key) {
            if (node === null) { return null }
            if (key < node.key) {
                node.left = _delete(node.left, key);
            } else if (key > node.key) {
                node.right = _delete(node.right, key)
            } else {
                ret = node;
                if (node.right === null) return node.left;
                if (node.left === null) return node.right;
                node = _this._min(node.right);
                _this._deleteMin(node.right);
            }
            node.height = Math.max(_this._getHeight(node.left), _this._getHeight(node.right))+1;
            return _this._rotate(node);
        }
        this.root = _delete(this.root, key);
        return ret;
    }
    // 前序遍历
    preOrder() {
        _preOrder(this.root);
        function _preOrder(node) {
            if (node == null) {
                return;
            }
            console.log(node.value);
            _preOrder(node.left);
            _preOrder(node.right);
        }
    }
    // 中序遍历
    inOrder() {
        _inOrder(this.root);
        function _inOrder(node) {
            if (node == null) {
                return;
            }
            _inOrder(node.left);
            console.log(node.value);
            _inOrder(node.right);
        }
    }
    // 后序序遍历
    postOrder() {
        _postOrder(this.root);
        function _postOrder(node) {
            if (node == null) {
                return;
            }
            _postOrder(node.left);
            _postOrder(node.right);
            console.log(node.value);
        }
    }

    // 层序遍历
    levelOrder() {
        let queue = []; // 引入队列
        let node;
        queue.push(this.root);

        while (queue.length) {
            node = queue.shift();
            console.log(node.value);
            if (node.left != null) {
                queue.push(node.left);
            }
            if (node.right != null) {
                queue.push(node.right);
            }
        }
    }
    _min(node = this.root) { // 是按键值转成数字的大小比较,并非按照value比较,所以最小的指的是键值转成数字后的大小
        if (node === null) { return null }
        return _min(node);
        function _min(node) {
            if (node.left === null) return node;
            return _min(node.left);
        }
    }
    _deleteMin(node = this.root) { // 最左边那个就是最小的
        let ret = this._min(this.root);
        let _this = this;
        if (ret === null) { return null }
        this.root = _deleteMin(node);
        return ret;
        function _deleteMin(node) {
            if (node === null) { return node }
            if (node.left === null) {
                node = node.right;
            } else if (node.left.left === null) {
                node.left = node.left.right;
            } else {
                node.left = _deleteMin(node.left);
            }
            if (node) {
                node.size = _this._getSize(node.left) + _this._getSize(node.right) + 1;
            }
            return node;
        }
    }
    _strToNum(key) { // 将字符串转成数字,方便比较大小
        if (typeof key !== "string") { throw ("key need string type") }
        let num = "";
        for (let i = 0; i < key.length; i++) {
            num += String(key.charAt(i).charCodeAt());
        }
        return Number(num);
    }
}

红黑树

// 前提
// 了解红黑树的性质,满足红黑树的性质就达到了平衡
// 了解插入时不满足红黑树性质进行的操作(颜色翻转、旋转操作)
const RED = true;
const BLACK = false;
class Node {
    constructor(key, value) {
        this.key = key;
        this.value = value;
        this.left = null;
        this.right = null;
        this.color = RED;
    }
}
class RBTree {
    constructor() {
        this.root = null;
        this.size = 0;
    }
    get getsize() {
        return this.size;
    }
    get isEmpty() {
        return this.size == 0;
    }
    put(key, value) {
        let _this = this;
        this.root = put(this.root, this._strToNum(key), value);
        this.root.color = BLACK;
        function put(node, key, value) {
            if (node == null) {
                _this.size++;
                //默认红色
                return new Node(key, value);
            }

            if (key < node.key) {
                node.left = put(node.left, key, value);
            } else if (key > node.key) {
                node.right = put(node.right, key, value);
            } else {
                node.value = value;
            }
            if (_this.isRed(node.right) && !_this.isRed(node.left)) {
                node = _this.leftRotate(node);
            }
            if (_this.isRed(node.left) && _this.isRed(node.left.left)) {
                node = _this.rightRotate(node);
            }
            if (_this.isRed(node.left) && _this.isRed(node.right)) {
                _this.flipColors(node);
            }

            return node;
        }
    }
    remove(key) {
        let node = this.getNode(this.root, this._strToNum(key));
        let _this = this;
        if (node != null) {
            this.root = remove(this.root, this._strToNum(key));
            return node.value;
        }
        function remove(node, key) {
            if (node == null) {
                return null;
            }
            if (key < node.key) {
                node.left = remove(node.left, key);
                return node;
            } else if (key > node.key) {
                node.right = remove(node.right, key);
                return node;
            } else {
                if (node.left == null) {
                    let rightNode = node.right;
                    node.right = null;
                    _this.size--;
                    return rightNode;
                } else if (node.right == null) {
                    let leftNode = node.left;
                    node.left = null;
                    _this.size--;
                    return leftNode;
                } else {
                    //待删除节点左右子树都不为空的情况
                    //调用minimum方法,寻找右子树中的最小节点
                    let successor = _this.minimum(node.right);
                    //removeMin操作中已经维护过size了
                    successor.right = _this.removeMin(node.right);
                    successor.left = node.left;
                    node.left = node.right = null;
                    return successor;
                }
            }
        }
        return null;
    }
    get(key) {
        let node = this.getNode(this.root, this._strToNum(key));
        return node == null ? null : node.value;
    }
    contains(key) {
        return this.getNode(this.root, this._strToNum(key)) != null;
    }
    // 前序遍历
    preOrder() {
        _preOrder(this.root);
        function _preOrder(node) {
            if (node == null) {
                return;
            }
            console.log(node.value);
            _preOrder(node.left);
            _preOrder(node.right);
        }
    }
    // 中序遍历
    inOrder() {
        _inOrder(this.root);
        function _inOrder(node) {
            if (node == null) {
                return;
            }
            _inOrder(node.left);
            console.log(node.value);
            _inOrder(node.right);
        }
    }
    // 后序序遍历
    postOrder() {
        _postOrder(this.root);
        function _postOrder(node) {
            if (node == null) {
                return;
            }
            _postOrder(node.left);
            _postOrder(node.right);
            console.log(node.value);
        }
    }

    // 层序遍历
    levelOrder() {
        let queue = []; // 引入队列
        let node;
        queue.push(this.root);

        while (queue.length) {
            node = queue.shift();
            console.log(node.value);
            if (node.left != null) {
                queue.push(node.left);
            }
            if (node.right != null) {
                queue.push(node.right);
            }
        }
    }
    // 左旋
    leftRotate(node) {
        let x = node.right;
        node.right = x.left;
        x.left = node;
        x.color = node.color;
        node.color = RED;

        return x;
    }
    // 右旋
    rightRotate(node) {
        let x = node.left;
        node.left = x.right;
        x.right = node;
        x.color = node.color;
        node.color = RED;

        return x;
    }
    // 颜色反转
    flipColors(node) {
        node.color = RED;
        node.right.color = BLACK;
        node.left.color = BLACK;
    }
    // 判断节点node的颜色
    isRed(node) {
        if (node == null) {
            return BLACK;
        }
        return node.color;
    }
    _strToNum(key) { // 将字符串转成数字,方便比较大小
        if (typeof key !== "string") { throw ("key need string type") }
        let num = "";
        for (let i = 0; i < key.length; i++) {
            num += String(key.charAt(i).charCodeAt());
        }
        return Number(num);
    }

    minimum(node = this.root) {
        if (this.size === 0) throw ("size 0");
        return minimum(node);
        function minimum(node) {
            if (node.left == null) {
                return node;
            }
            return minimum(node.left);
        }
    }
    removeMin(node = this.root) {
        let _this = this;
        return removeMin(node);
        function removeMin(node) {
            if (node.left == null) {
                let rightNode = node.right;
                node.right = null;
                _this.size--;
                return rightNode;
            }
            node.left = removeMin(node.left);
            return node;
        }
    }
    // 返回以node为根节点的二分搜索树中key所在的节点
    getNode(node, key) {
        if (node == null) {
            return null;
        }
        if (key == node.key) {
            return node;
        } else if (key < node.key) {
            return this.getNode(node.left, key);
        } else {
            return this.getNode(node.right, key);
        }
    }

}

并查集

// 并查集
class UnionFind {
    constructor(size) {
        this._parent = new Array(size); // 节点
        this._rank = new Array(size); // 记录节点下的元素数量
        
        for (let i=0; i<size; i++) {
            this._parent[i] = i;
            this._rank[i] = 1;
        }
    }
    get size() {
        return this._parent.length;
    }
    // 查找所属集合
    find(p) {
        if (p < 0 && p >= parent.length) {
            throw new Error("p is out of bound");
        }
        let parent = this._parent;
        while (p != parent[p]) { 
            parent[p] = parent[parent[p]]; // 路径压缩,缩短到根节点的距离
            p = parent[p];
        }
        return p;
    }
    // 是否同一个集合
    isConnected(p, q) {
        return this.find(p) == this.find(q);
    }
    // 合并到一个集合中
    unionElements(p, q) {
        let pRoot = this.find(p);
        let qRoot = this.find(q);
        let rank = this._rank;
        let parent = this._parent;
        
        if (pRoot == qRoot) {
            return;
        }
        if (rank[pRoot] < rank[qRoot]) {
            parent[pRoot] = qRoot;
        } else if (rank[pRoot] > rank[qRoot]) {
            parent[qRoot] = pRoot;
        } else {
            parent[qRoot] = pRoot;
            rank[pRoot] += 1;
        }
    }
}

字典树

// 前缀树
class Node {
    constructor(isWord = false) {
        this.isWord = isWord;
        this.next = {};
    }
}
class Trie {
    constructor() {
        this._root = new Node();
        this._size = 0;
    }
    get size() {
        return this._size;
    }
    add(word) {
        let cur = this._root;
        for (let i = 0; i < word.length; i++) {
            let key = word.charAt(i);
            if (cur.next[key] == undefined) {
                cur.next[key] = new Node();
            }
            cur = cur.next[key];
        }
        if (!cur.isWord) {
            cur.isWord = true;
            this._size++;
        }
    }
    contains(word) {
        let cur = this._root;
        for (let i = 0; i < word.length; i++) {
            let key = word.charAt(i);
            if (cur.next[key] == undefined) {
                return false;
            }
            cur = cur.next[key];
        }
        return cur.isWord;
    }
    delete(word) {
        if (this.contains(word)) {
            let cur = this._root;
            for (let i = 0; i < word.length; i++) {
                let key = word.charAt(i);
                cur = cur.next[key];
            }
            cur.isWord = false;
        }
    }
    // 是否包含单词前缀
    // @params{String} prefix 
    isPrefix(prefix) {
        let cur = this._root;
        for (let i = 0; i < prefix.length; i++) {
            let key = prefix.charAt(i);
            if (cur.next[key] == undefined) {
                return false;
            }
            cur = cur.next[key];
        }
        return true;
    }
    // 返回所有的单词,深度优先遍历
    // @return{Array} 单词集合
    iterator() {
        let cur = this._root;
        let ret = [];
        let w = "";
        function each(next) {
            for (let key in next) {
                let word = next[key];
                w += key;
                if (word.isWord) {
                    ret.push(w)
                    w = "";
                }
                if (word.next) {
                    each(word.next)
                }
            }
        }
        each(cur.next);
        return ret;
    }
}

哈希表

class HashTable {
    constructor(capacity) {
        if (!capacity) {
            throw new RangeError("capacity is empty");
        }
        this._data = new Array(capacity);
        this._size = 0;
    }
    hashCode(key) { // 根据不同场景设计不同的哈希函数
        let hash = 5381;
        key = String(key);
        for (let i = 0; i < key.length; i++) {
            hash = ((hash << 5) + hash) + key.charCodeAt(i);
        }
        return Math.abs(hash % this._data.length);
    }
    get size() {
        return this._size;
    }
    add(key, value) {
        let hashCode = this.hashCode(key);
        let map = this._data[hashCode];
        if (map === undefined) {
            this._data[hashCode] = {
                [key]: value
            }
        } else {
            map[key] = value;
        }
        this._size++;
    }
    remove(key) {
        let map = this._data[this.hashCode(key)];
        let ret = map[key];
        if (map) {
            delete map[key];
            this._size--;
        }
        return ret;
    }
    get(key) {
        let hashCode = this.hashCode(key);
        let map = this._data[hashCode];
        return map ? map[key] : undefined;
    }
    set(key, value) {
        let map = this._data[this.hashCode(key)];
        if (!map) {
            throw new RangeError("key is not found");
        }
        map[key] = value;
    }
    contains(key) {
        return !!(this.get(key));
    }
}

映射

class Node {
    constructor(key,value,prev=null,next=null) {
        this.key = key;
        this.value = value;
        this.next = next;
        this.prev = prev;
    }
}
class LinkedListMap {
    constructor() {
        this._root = null;
        this._tail = null;
        this._size = 0;
    }
    get size() {return this._size}
    get isEmpty() {return this._size === 0}
    contains(key) {
        if (typeof key !== "string") {throw("key need string type")}
        for(let cur=this._root; cur!=null; cur=cur.next) {
            if (cur.key === key) {
                return cur;   
            }
        }
        return null;
    }
    get(key) {
        if (typeof key !== "string") {throw("key need string type")}
        let ret = this.contains(key);
        return ret ? ret.value : null;
    }
    put(key, value) {
        if (typeof key !== "string") {throw("key need string type")}
        let ret = this.contains(key);
        if (ret !== null) { // 有则更新
            ret.value = value;
        } else { // 没有就创建
            let node = new Node(key,value);
            if (this.size === 0) {
                this._root = node;
                this._tail = node;
            } else {
                node.prev = this._tail;
                this._tail.next = node;  
                this._tail = node;
            }
            this._size++;
        }
    }
    delete(key) {
        if (typeof key !== "string") {throw("key need string type")}
        let node = this.contains(key);
        if (node !== null) {
            if (key === this._root.key) {
                let next = this._root.next;
                this._root.next = null;
                this._root = next;
                if (next != null) { 
                    next.prev = null;
                } else { // 只有一个节点
                    this._tail = null
                }
            } else {
                node.prev.next = node.next;
                if (key === this._tail.key) {
                    this._tail = node.prev;
                } else {
                    node.next = null;
                    node.next.prev = null;
                }
            }
            this._size--;
        }
    }

}

参考资料

《算法(第四版)》

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、资源 5来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、资 5源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值