JavaScript数据结构-树

我觉得这社会上,也不差钱好多人,可能好多人也不差权力,但是我觉得能得到这种满足的也不多。 –郭小平<临汾红丝带学校校长>

? 树是计算机科学中经常用到的一种数据结构。树是一种非线性的数据结构,以分层的方式存储数据。是被用来存储具有层级关系或有序的数据,比如文件系统中的文件。

二叉树

二叉树,每个节点最多有两个子树的树结构。二叉树是一种特殊的树,也是一个连通的无环图。

二叉查找树

? 二叉查找树是一种特殊的二叉树,其相对较小的值保存在左节点中,较大的值保存在右节点中。这一特性使其查找效率很高。

实现二叉查找树

? 如果待插入节点小于(大于)当前节点,且当前节点的左(右)节点为null,则将待插入节点插入到当前节点的左(右)节点位置上,结束循环;否则,将当前节点的左(右)节作为当前节点继续下次循环。

/**
 * 节点定义
 * @param data 数据
 * @param left 左子树
 * @param right 右子树
 * @constructor
 */
function Node(data, left, right) {
    this.data = data;
    this.left = left;
    this.right = right;
}
Node.prototype.show = function() {
    return this.data;
};

/**
 * 二叉查找树定义
 * @constructor
 */
function BST() {
    this.root = null;
}
/**
 * 插入节点
 * @constructor
 */
BST.prototype.insert = function(data) {
    // 待插入节点
    var node = new Node(data, null, null);
    if(this.root === null) {
        this.root = node;
    } else {
        var currentNode = this.root;
        var parent;
        while(true) {
            parent = currentNode;
            // 待插入节点小于当前节点
            if(data < currentNode.data) {
                // 将其左子树作为当前节点
                currentNode = currentNode.left;
                if(currentNode === null) {
                    parent.left = node;
                    break;
                }
            }else {
                // 将其右子树作为当前节点
                currentNode = currentNode.right;
                if(currentNode === null) {
                    parent.right = node;
                    break;
                }
            }
        }
    }
    return this; // 支持链式调用
};
  • 中序:先访问左子树,再访问根节点,最后访问右字数;以升序访问BST上所有节点;(左==>根==>右
  • 先序:先访问根节点,然后以同样方式访问左子树和右子树;(根==>左==>右
  • 后序:先访问叶子节点,从左子树到右子树,再到根节点。(左==>右==>根
BST.prototype.order = function(node, type) {
    switch (type) {
        case "inorder": // 中序
            if(node != null) {
               /*左==>根==>右*/
               this.order(node.left, type);
               console.log(node.show());
               this.order(node.right, type);
            }
            break;
        case "preorder": // 先序
            if(node != null) {
                /*根==>左==>右*/
                console.log(node.show());
                this.order(node.left, type);
                this.order(node.right, type);
            }
            break;
        case "postorder": // 后序
            if(node != null) {
                /*左==>右==>根*/
                this.order(node.left, type);
                this.order(node.right, type);
                console.log(node.show());
            }
            break;
    }
};

测试

var bst = new BST();
bst.insert(32).insert(11).insert(2)
    .insert(13).insert(75)
    .insert(66).insert(88);

bst.order(bst.root, "inorder"); // 中序
bst.order(bst.root, "preorder"); // 先序
bst.order(bst.root, "postorder"); // 后序

查询最小值和最大值

  • 最小值:遍历左子树,直到找到最后一个节点;
  • 最大值:遍历右子树,直到找到最后一个节点。
/**
 * 获取最小值:左子树的最后一个节点
 */
BST.prototype.getMin = function(node) {
    var currentNode = node || this.root;
    while(currentNode.left !== null) {
        currentNode = currentNode.left;
    }
    return currentNode;
};

/**
 * 获取最小值:右子树的最后一个节点
 */
BST.prototype.getMax = function(node) {
    var currentNode = node || this.root;
    while(currentNode.right !== null) {
        currentNode = currentNode.right;
    }
    return currentNode;
};

console.log(bst.getMin().data); // 2
console.log(bst.getMax().data); // 88 

查找某节点

/**
 * 查找某节点
 * @param data 数据
 */
BST.prototype.find = function(data) {
    var currentNode = this.root;
    while(currentNode !== null) {
        if(data === currentNode.data) {
            return currentNode;
        }
        currentNode = (data < currentNode.data) ?
            currentNode.left : currentNode.right;
    }
    return null;
};

console.log(bst.find(66)); // Node { data: 66, left: null, right: null }
console.log(bst.find(99)); // null

删除节点

  • 如果待删除节点为叶子节点,则直接删除它;
  • 如果待删除节点只有一个子节点,则直接将待删除节点的父节点指向其子节点;
  • 如果待删除节点包含两个子节点,我们选择右子树上的最小值创建一个临时节点,然后复制到待删节点,然后删除最小值节点。
/**
 * 移除指定数据节点
 * @param data
 */
BST.prototype.remove = function(node, data) {
    node = node || this.root;
    if(data === null) {
        // 待删除节点不存在
        return node;
    }
    if(node.data === data) {
        // 无子节点
        if(node.left === null && node.right === null) {
            return null;
        }
        // 只有右节点,无左节点
        if(node.left === null) {
            return node.right;
        }
        // 只有左节点,无右节点
        if(node.right === null) {
            return node.left;
        }
        // 存在两个节点
        var minNode = this.getMin(node.right);
        console.log(minNode);
        node.data = minNode.data;
        node.right = this.remove(node.right, minNode.data);
    }else if( node.data > data) {
        node.left = this.remove(node.left, data);
    }else if( node.data < data){
        node.right = this.remove(node.right, data);
    }
    return node;
};

总结

? 树,在计算机科学中体现的特别多 。如,我们熟悉的DOM树,数据库底层经常用到的B树等等。树能很好的保证字典序,存储词典的空间压缩率高, 能做前缀搜索。抽象地说,基本上有序列的地方就可以应用树,因为树结构即是一种序列索引结构

时间: 2024-08-11 05:29:36

JavaScript数据结构-树的相关文章

JavaScript数据结构——树

树:非顺序数据结构,对于存储需要快速查找的数据非常有用. 二叉树:二叉树中的节点最多只能有两个子节点(左侧子节点和右侧子节点).这些定义有助于我们写出更高效的向/从树中插入.查找和删除节点的算法. 二叉搜索树:二叉树的一种,但是它只允许你在左侧节点存储(比父节点)小的值,在右侧节点存储(比父节点)大/等于的值. 遍历一棵树:是指访问树的每个节点并对它们进行某种操作的过程.访问树的所有节点有三种方式:中序.先序和后序. 中序遍历:是一种以上行顺序访问 BST 所有节点的的遍历方式,也就是以从最小到

JavaScript数据结构——图的实现

在计算机科学中,图是一种网络结构的抽象模型,它是一组由边连接的顶点组成.一个图G = (V, E)由以下元素组成: V:一组顶点 E:一组边,连接V中的顶点 下图表示了一个图的结构: 在介绍如何用JavaScript实现图之前,我们先介绍一些和图相关的术语. 如上图所示,由一条边连接在一起的顶点称为相邻顶点,A和B是相邻顶点,A和D是相邻顶点,A和C是相邻顶点......A和E是不相邻顶点.一个顶点的度是其相邻顶点的数量,A和其它三个顶点相连,所以A的度为3,E和其它两个顶点相连,所以E的度为2

JavaScript 数据结构与算法之美 - 归并排序、快速排序、希尔排序、堆排序

1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算法和方便以后复习. 之所以把归并排序.快速排序.希尔排序.堆排序放在一起比较,是因为它们的平均时间复杂度都为 O(nlogn). 请大家带着问题:快排和归并用的都是分治思想,递推公式和递归代码也非常相似,那它们的区别在哪里呢 ? 来阅读下文. 2. 归并排序(Merge Sort) 思想 排序一个数

【实战】IFE的JavaScript和树

任务目的 熟练JavaScript 学习树这种数据结构的基本知识 任务描述 在页面中展现一颗二叉树的结构 提供一个按钮,显示开始遍历,点击后,以动画的形式呈现遍历的过程 二叉树的遍历算法和方式自定,前序中序后序皆可,但推荐可以提供多种算法的展示(增加多个按钮,每个按钮对应不同的算法) 当前被遍历到的节点做一个特殊显示(比如不同的颜色) 每隔一段时间(500ms,1s等时间自定)再遍历下一个节点 注意事项 如果按照示例图中展示树,可以使用flexbox布局 实现简单功能的同时,请仔细学习JavaS

JavaScript数据结构总结

一.什么是数据结构高层数据结构是用于存储和组织数据的技术,这些数据使修改,导航和访问变得更加容易.数据结构决定了如何收集数据,我们可以用来访问数据的功能以及数据之间的关系.数据结构几乎用于计算机科学和编程的所有领域,从操作系统到基本的编码再到人工智能.数据结构使我们能够: 管理和利用大型数据集 从数据库中搜索特定数据 针对特定程序量身定制的设计算法 一次处理来自用户的多个请求 简化并加速数据处理 数据结构对于有效,现实地解决问题至关重要.毕竟,我们组织数据的方式对性能和可用性有很大影响.实际上,

javascript数据结构与算法--二叉树(插入节点、生成二叉树)

javascript数据结构与算法-- 插入节点.生成二叉树 二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 /* *二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 * * * */ /*用来生成一个节点*/ function Node(data, left, right) { this.data = data;//节点存储的数据 this.left = left; this.right = right; this.show = show; } function sh

javascript数据结构与算法---列表

前言:在日常生活中,人们经常要使用列表,比如我们有时候要去购物时,为了购物时东西要买全,我们可以在去之前,列下要买的东西,这就要用的列表了,或者我们小时候上学那段时间,每次考完试后,学校都会列出这次考试成绩前十名的同学的排名及成绩单,等等这些都是列表的列子.我们计算机内也在使用列表,那么列表适合使用在什么地方呢?不适合使用在什么地方呢? 适合使用在:当列表的元素不是很多的情况下,可以使用列表,因为对列表中的元素查找或者排序时,效率还算非常高,反之:如果列表元素非常多的情况下,就不适合使用列表了.

数据结构--树(定义与存储结构)

树基本定义 树的定义 数是具有n个节点的有限集.如图即是一个树形结构. 节点分类 节点的度:一个节点拥有的子节点即成为节点的度,比如A节点,有B和C两个子节点,那么A节点的度=2. 叶节点(终端节点):没有子节点的节点,比如G.H.I.... 如图: 节点间关系 孩子节点:某一个节点的子节点称为孩子节点.比如B.C节点是A节点的孩子节点. 双亲节点:与孩子节点相反.比如,A节点是B.C的双亲节点. 兄弟节点:同一个双亲节点的孩子节点,之间称为兄弟节点.比如,B.C为兄弟节点. 如图: 树的存储结

JavaScript数据结构——队列的实现

前面楼主简单介绍了JavaScript数据结构栈的实现,http://www.cnblogs.com/qq503665965/p/6537894.html,本次将介绍队列的实现. 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的端称为队头. 队列的两种主要操作是:向队列中插入新元素和删除队列中的元素.插入操作也叫做入队,删除操作也叫做出队.入队操