Javascript数据结构与算法学习(六)—— 树

文章目录

树结构

树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样。

  • HTML结构就是典型的树结构
    在这里插入图片描述

二叉搜索树

  • 特点:
    • 节点最多只能有两个子节点,一个左子节点,一个右子节点,左右子节点的顺序不能颠倒。
    • 在左侧存储比父节点小的值
    • 在右侧存储比父节点大的值
  • 实现:
    • 树(Tree)有:根节点,内部的Node类,查找,删除,插入,遍历
      在这里插入图片描述
  • 插入节点
function Tree(){
 	var Node = function(val){
        this.value = val
        this.left = null
        this.right = null
    }

    var root = null
    //  插入节点
    /**
     * 1、树为空树:root = value
     * 2、树不是空的:对比节点
     */
    var insertNode = function(node,newNode){
        if(newNode.value>node.value){
            if(node.right===null){
                node.right = newNode
            }else{
                insertNode(node.right,newNode)
            }
        }else if(newNode.value<node.value){
            if(node.left===null){
                node.left = newNode
            }else{
                insertNode(node.left,newNode)
            }
        }
    }
    this.insert = function(value){
        var node = new Node(value)
        if(root===null){
            root = node
        }else{
            insertNode(root,node)
        }
    }
}

  • 遍历树
    在这里插入图片描述

 // 遍历节点
  // 借助递归
    function traverse(node, callback){
        if(node===null) return;
        traverse(node.left,callback)
        traverse(node.right,callback)
        callback(node.value)
    }
    this.traverse = function(callback){
        traverse(root,callback)
    }
  • 获取最小值
    在这里插入图片描述
  • 移除节点

移除节点有很多种情况:

  1. 移除有2个子节点的?——选哪个子节点来代替被删除的节点
  2. 移除末位节点(叶节点)
  3. 移除只有1个子节点
    在这里插入图片描述
    在这里插入图片描述
/**
 * 根节点 root
 * 插入 insert
 * 查找 search
 * 遍历 traverse
 * 删除 remove
 * 内部的Node类
 * 
 */
function Tree(){
    var Node = function (value){
        this.value = value
        this.left = null
        this.right = null
    }
    var root = null
    // 插入
    function insert(node,newNode){
        if(node.value<newNode.value){
            if(node.right===null){
                node.right = newNode
            }else{
                insert(node.right,newNode)
            }
        }else{
            if(node.left===null){
                node.left = newNode
            }else{
                insert(node.left,newNode)
            }
        }
    }
    this.insert = function(value){
        var node = new Node(value)
        if(!root){
            root = node
        }else{
            insert(root,node)
        }
    }
    // 搜索
    var searchNode = function(node,value){
        if(node===null) return null
        if(value<node.value) return searchNode(node.left,value)
        else if(value>node.value) return  searchNode(node.right,value)
        else return node
    }
    this.search = function(val){
        searchNode(root,value)
    }
    // 遍历
    function traverse (node,callback){
        if(!node) return;
        //  callback(node.value) //前序遍历 —— 访问根节点的操作发生在遍历其左右子树之前。
        traverse(node.left,callback)
        // callback(node.value) //中序遍历 —— 访问根节点的操作发生在遍历其左右子树之间。
        traverse(node.right,callback)
        callback(node.value) //后序遍历 —— 访问根节点的操作发生在遍历其左右子树之后
    }
    this.traverse = function(callback){
        traverse(root,callback)
    }
    // 最小值
    this.min = function(node){
        if(node===null) return null;
        while(node&&node.left!==null){
            node = node.left
        }
        return node
    }
    // 最大值
    this.max = function(node){
        if(node===null) return null
        while(node&&node.right!==null){
            node = node.right
        }
        return node
    }
    // 删除——重新构建树
    function findMinNode(node){
        if(node === null) return null
        while(node && node.left!== null){
            node = node.left
        }
        return node
    }
    let removeNode = function (node, key) {
        if (node === null) return null;
        
        // 查找
        if (key < node.value) {
            node.left = removeNode(node.left, key);
            return node;
        }else if (key > node.value) {
            node.right = removeNode(node.right, key);
            return node;
        }else {
            // 找到节点后,删除
            // 第一种情况:一个叶子节点(没有子节点)
            if (node.left === null && node.right === null) {
                node = null;
                return null;
            }
            // 第二种情况:只包含一个子节点
            if (node.left === null) {
                node = node.right;
                return node;
            }
            else if (node.right === null) {
                node = node.left;
                return node;
            }
    
            // 第三种情况:有两个子节点
            let aux = findMinNode(node);
            node.value = aux.key;
            node.right = removeNode(node.right, aux.value);
            return node;
        }
    };
    this.remove = function(key){
        root = removeNode(root,key)
    }
    this.getTree = function(){
        return root
    }
}
var t = new Tree

t.insert(8)
t.insert(2)
t.insert(3)
t.insert(9)

// t.remove(2)
// console.log(t.getTree())
发布了114 篇原创文章 · 获赞 146 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Sophie_U/article/details/103818766
今日推荐