数据结构

232 阅读2分钟

  • Queue-队列
  • Stack-栈
  • LinkList-链表
  • Set-集合
  • Map-hash表
  • Tree-树
  • Graph-图(没研究)

1.Queue-队列

class Queue {
    constructor() {
        this.arr = [];
    }
    enqueue(element) {
        this.arr.push(element);
    }
    unqueue() {
        return this.arr.shift();
    }
}
let queue = new Queue();
queue.enqueue(1);
queue.enqueue(2);
console.log(queue.unqueue());

2.栈-Stack;

class Stack {
    constructor() {
        this.arr = [];
    }
    push(element) {
        this.arr.push(element);
    }
    pop() {
        return this.arr.pop();
    }
}
let stack = new Stack();
stack.push(1);
stack.push(2);
console.log(stack.pop());

// 函数调用就是栈结构
function a() {
    function b() {
        function c() {

        }
        c();
    }
    b();
}
a();

3.链表-LinkList

  • 优点,队里和栈数量很大,向中间操作插入、删除数据,余下数据所以都需改变,性能损失很大,查询数据只能靠遍历
  • 链表 插入/删除只需要操作相关联对象,即上一个、下一个和当前对象
// 示例-单向链表;(双向链表-prev-next;循环链表-last->first)

class LinkNode {
    constructor(element) {
        this.element = element;
        this.next = null;
    }
}

class LinkList {
    constructor() {
        this.head = null;
        this.length = 0;
    }
    append(element) {
            let node = new LinkNode(element);
            if (!this.head) {
                this.head = node;
            } else {
                let current = this.head;
                while (current.next) {
                    current = current.next;
                }
                current.next = node;
            }
            this.length++;
        }
        // 即使数据量很大,插入的数据异常快
    insert(position, element) {
        if (position >= 0 && position < this.length) {
            let node = new LinkNode(element);
            if (!this.head) {
                this.head = node;
            } else {
                let index = 0;
                let current = this.head;
                let previous = null;
                while (index++ < position) {
                    previous = current;
                    current = current.next;
                }
                previous.next = node;
                node.next = current;
            }
            this.length++;
        }
    }
}

let linkList = new LinkList();
linkList.append(1);
linkList.append(2);
linkList.append(3);
linkList.insert(1, 'hello');
console.log(linkList);

4.集合-Set;

  • 键===值;
  • 不能有重复键
  • 原理还是对象存储
class Set {
    constructor() {
        this.obj = {};
    }
    add(value) {
        if (!Reflect.has(this.obj, value)) {
            this.obj[value] = value;
        }
    }
}
let set = new Set();
set.add(1);
set.add(1);
console.log(set);

5.Hash表-Map;

  • 查询速率异常快,键值对形式存储
  • 原理:取值和存值都根据键使用hash算法算出一个唯一的索引值,存到数组中,难度就在于如何计算出唯一的key
class Map {
    constructor() {
        this.arr = [];
    }
    calcKey(key) {
        let code = 0;
        for (let i of key) { // 这个算法只是示意,hash算法作用就是算出唯一值
            code += i.charCodeAt();
        }
        return code % 100; // 只开放长度100的数组
    }
    set(key, value) {
        let index = this.calcKey(key);
        this.arr[index] = value;
    }
    get(key) {
        let index = this.calcKey(key);
        return this.arr[index];
    }
}

let map = new Map();
map.set('hello', 'world');
map.set('world', 'hello');
map.set('olleh', 'world1'); // 我的hash算法的bug
console.log(map.get('hello'));

6.树-Tree

  • (二叉树、平衡树、DOM树)
// 示例二叉树
class NodeTree {
    constructor(value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }
}

class Tree {
    constructor() {
        this.root = null;
    }

    set(value) {
        let node = new NodeTree(value);
        if (!this.root) {
            this.root = node;
        } else {
            this.insertTree(this.root, node)
        }
    }

    insertTree(currentNode, newNode) {
        if (newNode.value < currentNode.value) {
            // 新节点小于当前节点-左边
            if (!currentNode.left)
                currentNode.left = newNode;
            else {
                this.insertTree(currentNode.left, newNode);
            }
        } else {
            if (!currentNode.right)
                currentNode.right = newNode;
            else {
                this.insertTree(currentNode.right, newNode);
            }
        }
    }
}

let tree = new Tree();
tree.set(100);
tree.set(200);
tree.set(80);
tree.set(70);
console.log(tree);