美文网首页
数据结构与算法JavaScript描述 笔记 - 链表、二叉树、

数据结构与算法JavaScript描述 笔记 - 链表、二叉树、

作者: 我叫Aliya但是被占用了 | 来源:发表于2021-10-18 14:45 被阅读0次

    // 无序图
    function Graph() {
    // this.nodes = n; // 一共几个节点
    this.edges = {}; // 每个节点的边

    // 为节点添加边
    this.link = (v, m) => {
    this.edges[v] = this.edges[v] ? [...this.edges[v], m] : [m];
    this.edges[m] = this.edges[m] ? [...this.edges[m], v] : [v];
    }
    }
    /** 广度遍历 /
    Graph.prototype.eachByLevel = function (v) {
    const pipe = [v]; // 管道,先进先出
    const marked = [] // 已被遍历节点
    while (pipe.length > 0) {
    const node = pipe.shift();
    if (!marked.includes(node)) {
    marked.push(node)
    pipe.push(...(this.edges[node] || []))
    }
    }
    console.log('广度遍历:', marked) // , this.edges
    }
    /
    * 最短路径 */
    Graph.prototype.shortest = function (v, w) {
    const pipe = [v]; // 管道,先进先出
    const marked = []; // 已被遍历节点
    const edgeTo = {}; // 遍历时反向记录节点间关系
    while (pipe.length > 0) {
    const node = pipe.shift();
    if (!marked.includes(node)) {
    marked.push(node)
    const edges = this.edges[node] || []
    pipe.push(...edges)

      // 相邻节点为key,当前节点为value,存入edgeTo
      edges.forEach(e => {
        edgeTo[e] = edgeTo[e] === undefined ? node : edgeTo[e]
      })
    }
    

    }
    console.log('edgeTo:', edgeTo)

    // 从终点反向找起点
    const paths = [w]
    while (edgeTo[w] !== v) {
    w = edgeTo[w]
    paths.push(w)
    }
    paths.push(v)
    console.log('reverse shortest path:', paths)
    }

    /** 深度遍历 */
    Graph.prototype.eachByDeep = function (v) {
    const marked = []
    const recursion = (v) => {
    if (marked.includes(v)) return;
    else marked.push(v);

    const nodes = this.edges[v] || [];
    nodes.forEach(n => recursion(n));
    

    }
    recursion(v)
    console.log('深度遍历:', marked) // , this.edges
    }

    const graph = new Graph(5)
    graph.link(0, 1)
    graph.link(0, 2)
    // graph.link(0, 4)
    graph.link(1, 3)
    graph.link(2, 3)
    graph.link(5, 3)
    graph.link(5, 4)
    graph.shortest(0, 5)

    // - 广度遍历 比 深度遍历 耗时

    // 二叉树
    class Node {
    constructor(data) {
    this.data = data;
    this.left = null;
    this.right = null;
    }
    show() {
    console.log('data:', this.data)
    }
    }
    class Bst {
    constructor(root) {
    this.root = root;
    this.current = root;
    }

    insert(node) {
    this.current = this.root;
    while (true) {
    if (node.data < this.current.data) {
    if (this.current.left) this.current = this.current.left;
    else {
    this.current.left = node;
    break;
    }
    } else {
    if (this.current.right) this.current = this.current.right;
    else {
    this.current.right = node;
    break;
    }
    }
    }
    this.current = this.root;
    }

    show(current) {
    current = current ? current : this.root;
    const left = current.left ? this.show(current.left) : [];
    const right = current.right ? this.show(current.right) : [];
    return [...left, current.data, ...right];
    }

    /** 先序遍历 先访问根节点,然后以同样方式访问左子树和右子树 /
    showBefore(current) {
    current = current ? current : this.root;
    const left = current.left ? this.showBefore(current.left) : [];
    const right = current.right ? this.showBefore(current.right) : [];
    return [current.data, ...left, ...right];
    }
    /
    * 后序遍历 先访问叶子节点,从左子树到右子树,再到根节点 */
    showAfter(current) {
    current = current ? current : this.root;
    const left = current.left ? this.showAfter(current.left) : [];
    const right = current.right ? this.showAfter(current.right) : [];
    return [...left, ...right, current.data];
    }

    find(data, current) {
    current = current ? current : this.root;
    if (data === current.data) return current;
    if (data < current.data) {
    current = current.left
    } else {
    current = current.right
    }
    if (!current) return 'not find'
    return this.find(data, current)
    }

    findParent(node) {
    let current = this.root;
    let attr = ''
    while (current) {
    attr = node.data < current.data ? 'left' : 'right'
    if (current[attr] === node) break;
    else current = current[attr];
    }
    return { node: current, attr };
    }

    delete(data) {
    const node = this.find(data);
    if (node.left === null || node.right === null) {
    // 删除根节点
    const newnode = node.left || node.right;
    if (this.root === node) this.root = newnode;

      const parent = this.findParent(node)
      parent.node[parent.attr] = newnode;
    } else {
      let newnode = node.right;
      while (newnode.left) {
        newnode = newnode.left;
      }
      newnode = newnode.data;
      this.delete(newnode);
      node.data = newnode;
    }
    

    }

    // 练习1
    count() {
    return this.show().length
    }
    max() {
    let max = this.root;
    while (max.right) {
    max = max.right;
    }
    return max.data
    }
    }

    var root = new Node(23)
    var bst = new Bst(root)
    bst.insert(new Node(45))
    bst.insert(new Node(16))
    bst.insert(new Node(37))
    bst.insert(new Node(3))
    bst.insert(new Node(99))
    bst.insert(new Node(22))
    // console.log('BST:', bst.show())
    // console.log('BST bf:', bst.showBefore())
    // console.log('BST af:', bst.showAfter())
    // console.log('find 3:', bst.find(3))
    // console.log('find 3:', bst.find(4))
    console.log('BST:', bst.root)
    // bst.delete(99)
    bst.delete(23)
    console.log('2 BST:', bst.root)
    console.log('BST count:', bst.count(), 'max:', bst.max())

    /**

    // 链表
    function Node(data) {
    this.ele = data;
    this.next = null;
    }
    function LinkList() {
    this.head = new Node("head");
    this.head.next = this.head;
    this.current = this.head;
    this.length = 0;
    this.push = function (data) {
    const newNode = new Node(data);
    newNode.next = this.current.next;
    this.current.next = newNode;
    this.current = newNode;
    this.length++;
    };
    this.delete = function () {
    prev.next = this.current.next;
    this.current = prev;
    this.next();
    this.length--;
    };
    let prev = this.head;
    this.next = function () {
    prev = this.current;
    this.current = this.current.next;
    if (this.current == this.head) this.next();
    };

    this.show = function () {
    return this.head;
    };
    }

    // 杀人
    function kill(link, number) {
    link.current = link.head;
    link.next();
    while (link.length > 1) {
    link.next();
    link.next();
    console.log(link.current);
    link.delete(); //01234 0134 034
    }
    return link.head;
    }

    let link = new LinkList();
    for (let i = 0; i < 5; i++) link.push(i);
    // console.log(link.show()); // 1-29
    console.log(kill(link, 3));
    // 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
    // 1,2,,4,5,,7,8,,10,11,,13,14,,16,17,,19,20,,22,23,,25,26,,28,29
    // ,2,,4,,,7,8,,,11,,13,,,16,17,,,20,,22,,,25,26,,,29
    // ,2,,,,,7,8,,,,,13,,,16,,,,20,,22,,,,26,,,29
    // ,,,,,,7,8,,,,,,,,16,,,,20,,,,,,26,,,29
    // ,,,,,,,,,,,,,,,16,,,,,,,,,,26,,,

    // function lastRemaining(n, m) {
    // let k = 0;
    // for (let i = 2; i <= n; i++) {
    // k = (k + m) % i;
    // }
    // return k;
    // }
    // console.log(lastRemaining(5000, 3));
    */

    相关文章

      网友评论

          本文标题:数据结构与算法JavaScript描述 笔记 - 链表、二叉树、

          本文链接:https://www.haomeiwen.com/subject/kilnoltx.html