精华内容
下载资源
问答
  •  这也难怪,设计、开发人员在学校学习数据库时,理论书籍离实际开发较远——试问有几个人能够以可实践的方式把规范化的几条原则阐述清楚?在工作时,使用的数据库资料和书籍又往往是“手册型”,大多仅仅讲解特定...
  • 学习C++是一次探索之旅,因为这种语言容纳了好几种编程模式,其中包括面向对象编程、通用编程和 传统过程化编程。随着新特性不断添加,C++一度成为一个活动目标,不过现在有了2003年ISO/ ANSIC++标准第二...
  • 学习C++是一次探索之旅,因为这种语言容纳了好几种编程模式,其中包括面向对象编程、通用编程和 传统过程化编程。随着新特性不断添加,C++一度成为一个活动目标,不过现在有了2003年ISO/ ANSIC++标准第二...
  • 学习C++是一次探索之旅,因为这种语言容纳了好几种编程模式,其中包括面向对象编程、通用编程和 传统过程化编程。随着新特性不断添加,C++一度成为一个活动目标,不过现在有了2003年ISO/ ANSIC++标准第二...
  • js实现数据结构--树

    2018-11-29 20:34:42
    什么是树? 树是一分层数据的抽象模型。...下面介绍常见的树的术语。 根节点:位于树顶部的节点,它没有父节点 内部节点:至少有一个子节点的节点 外部节点:没有子节点的节点,也称为叶节点...

    什么是树?

    树是一种分层数据的抽象模型。现实生活中最常见的树的例子就是家谱,或是公司的组织架构。

    树的结构图:如下图

    树的结构图

    树的相关术语:

    一棵树包含一系列存在父子关系的节点。每个节点都有一个父节点(除了顶部的第一个节点)以及零个或多个子节点.下面介绍几个常见的树的术语。

    • 根节点:位于树顶部的节点,它没有父节点
    • 内部节点:至少有一个子节点的节点
    • 外部节点:没有子节点的节点,也称为叶节点
    • 子树:子树由节点和它的后代构成,如树的结构图中的子树
    • 节点的深度:节点的祖先节点的数量
    • 树的高度:所有节点深度的最大值

    二叉树和二叉搜索树:

    二叉树是一种特殊的树结构,二叉树中的节点最多只能有了两个子节点,一个是左侧节点,另一个是右侧节点。

    二叉搜索树(BST):二叉搜索树是二叉树的一种,但是它只允许你在左侧节点存储(比父节点)小的值,在右侧节点存储(比父节点)大(或者等于)的值,如上面的树结构就是典型的二叉搜索树。

    二叉搜索树的每一个节点也有两个指针,分别指向左侧子节点和右侧子节点。如下图:

    二叉搜索树数据结构的组织方式

    注意:规范来说,键是树的相关术语中对节点的称呼。

    js实现二叉搜索树的相关定义与方法:

    首先是定义一个树的类,因为树的每个节点都有左子树和右子树,所以在定义节点的时候需要指定两个指针。二叉树中的一些方法有向树中插入一个节点,以及寻找树中的最小值和最大值,代码如下:

     function BinarySearchTree() {
            var Node = function (key) {
                this.key = key;
                this.left = null;
                this.right = null
            };
            var root = null;
    
            //向树中插入一个新的键
            this.insert = function (key) {
                //创建一个用来表示新节点的Node实例
                var newNode = new Node(key);
                if (root === null){
                    root = newNode;
                } else {
                    insertNode(root, newNode);
                }
            }
    
            //私有函数:新节点找到要插入的位置,并插入树中
            var insertNode = function (node, newNode) {
                if (newNode.key < node.key){//当前节点为根结点
                    if (node.left === null){
                        //新节点的值小于当前节点,则如果当前节点没有左侧子节点,就把新节点插入到当前节点的左侧位置
                        node.left = newNode;
                    } else {
                        //如果当前节点有左侧子节点,则需要递归找到树的下一层,重复比较当前节点的左侧子节点和新节点大小
                        insertNode(node.left, newNode);
                    }
                } else {
                    //同上的分析,新节点的值大于当前节点
                    if (node.right === null){
                        node.right = newNode;
                    } else {
                        insertNode(node.right, newNode);
                    }
                }
            };
     //搜索树中的最小值
            this.min = function () {
                return minNode(root);
            }
            var minNode = function (node) {
                if (node){
                    while (node && node.left !== null){
                        node = node.left;
                    }
                    return node.key;
                }
                return null;
            }
    
            //搜索树中的最大值
            this.max = function () {
                return maxNode(root);
            }
            var maxNode = function (node) {
                if (node){
                    while (node && node.right !==null){
                        node = node.right;
                    }
                    return node.key
                }
                return null;
            }
    
            //搜索一个特定的值
            this.search = function (key) {
                return searchNode(root,key);
            }
            var searchNode = function (node, key) {
                if (node === null){
                    return false;
                }
                if (key < node.key){
                    return searchNode(node.left, key);
                } else if(key > node.key){
                    return searchNode(node.right, key);
                }else {
                    return true;
                }
            }
    }

    二叉树的遍历:

    二叉树的遍历是树结构的经典,主要有三种,分别是先序,中序和后序,代码如下:

           //树的中序遍历
            this.inOrderTraverse = function (callback) {
                inOrderTraverseNode(root, callback);
            }
    
            var inOrderTraverseNode = function (node, callback) {
                //这里的回调函数用来定义我们对遍历到的每个节点进行的操作
                if (node !== null){
                    inOrderTraverseNode(node.left, callback);
                    callback(node.key);
                    inOrderTraverseNode(node.right,callback);
                }
            }
    
            //先序遍历
            this.preOrderTraverse = function (callback) {
                preOrderTraverseNode(root, callback);
            }
    
            var preOrderTraverseNode = function (node , callback) {
                if (node !== null){
                    //先序遍历会先访问节点本身,然后再访问它的左侧子节点,最后是右侧子节点
                    callback(node.key);
                    preOrderTraverseNode(node.left, callback);
                    preOrderTraverseNode(node.right, callback);
                }
            }
    
            //后序遍历
            this.postOrderTraverse = function (callback) {
                postOrderTraverseNode(root, callback);
            }
    
            var postOrderTraverseNode = function (node , callback) {
                if (node !== null){
                    //后序遍历会先访问它的左侧子节点,再访问右侧子节点,最后是父节点本身
                    postOrderTraverseNode(node.left, callback);
                    postOrderTraverseNode(node.right, callback);
                    callback(node.key);
                }
            }

    最后是二叉树的删除节点,根据某个特定的值,找到树中的值相等的节点,并删除。这里面的情况比较复杂,需要分多种情况讨论,尤其是找到该节点后。删除了该节点还要考虑将该节点的父元素的指针转移,具体分析和代码如下:

    //移除一个节点
            this.remove = function (key) {
                root = removeNode(root,key);
            }
            var removeNode = function (node ,key) {//node表示当前访问的节点
                if(node === null){
                    return null
                }
                if (key < node.key){
                    //如果要移除的节点的值小于当前节点,则继续在当前结点的左侧子树中找,迭代
                    node.left = removeNode(node.left, key);
                    return node;
                } else  if(key > node.key){
                    node.right = removeNode(node.right , key);
                    return node;
                }else {//键等于node.key
                    /*第一种情况,相等的节点是一个叶子节点
                    移除了节点之后,需要将节点的父节点的指针赋予null值,当节点的值是null后,父节点指向它
                    的指针会接收到这个值,所以要在最后返回这个节点node;第二种情况,当前的节点只有左侧子
                    节点或者右侧子节点的时候,也需要将当前节点的父节点的指针指向当前节点的左侧子节点或者
                    右侧子节点;
                    第三种情况,如果当前节点既有左侧子节点又有右侧子节点时,这时首先需要找到当前结点的右边
                    子树中最小的节点,然后用这个最小的节点替换当前节点,同时移除原来的最小的节点,更新其
                    父节点的指针
                    */
                    if (node.left === null  && node.right === null){
                        node = null;
                        return node;
                    }
                    //第二种情况,相等的节点是只有一个子节点的节点
                    if (node.left === null){
                        node = node.right;
                        return node;
                    }else if (node.right === null){
                        node = node.left;
                        return node;
                    }
                    //第三种情况,相等的节点是有两个子节点的节点
                    var aux = findMinNode(node.right);
                    node.key = aux.key;//最小的值的节点替换当前节点
                    node.right = removeNode(node.right, aux.key);//移除原右子树的最小的节点
                    return node;//更改父节点的指针
                }
            }
            var findMinNode = function (node) {
                while (node && node.left !== null){
                    node = node.left;
                }
                return node;
            }
    

    树的使用:

    树的使用主要是调用以上的方法,具体代码和输出如下:

    var tree = new BinarySearchTree();
        tree.insert(11);
        tree.insert(7);
        tree.insert(15);
        tree.insert(5);
        tree.insert(3);
        tree.insert(9);
        tree.insert(8);
        tree.insert(10);
        tree.insert(13);
        tree.insert(12);
        tree.insert(14);
        tree.insert(20);
        tree.insert(18);
        tree.insert(25);
        tree.insert(6);
        function printNode(value) {
            console.log(value);
        }
        console.log('树中序遍历的结果为:')
        tree.inOrderTraverse(printNode);
        //输出为:3 5 6 7 8 9 10 11 12 13 14 15 18 20 25
    
        console.log('树先序遍历的结果为:')
        tree.preOrderTraverse(printNode);
        //输出为:11 7 5 3 6 9 8 10 15 13 12 14 20 18 25
    
        console.log('树后序遍历的结果为:')
        tree.postOrderTraverse(printNode);
        //输出为:3 6 5 8 10 9 7 12 14 13 18 25 20 15 11
    
        //找到树中最小值和最大值
        console.log('树中的最小值为:'+tree.min());//输出3
        console.log('树中的最大值为:'+tree.max());//输出25
    
        //搜索树种某个特定的值
        console.log(tree.search(12)? 'key 12 found': 'key 12 not found');//输出key 12 found
        console.log(tree.search(2)? 'key 2 found': 'key 2 not found');//输出key 2 ot found

     

    展开全文
  • 由于J2EE开源框架中提供了MVC模式实现框架Struts、对象关系模型中的Hibernate 框架及拥有事务管理和依赖注入Spring。利用现存框架可以更快开发系统。所以选择Java技术作为blog 开发工具。 为了增加系统...
  • 4.1.0 JAVA中的几种基本数据类型是什么,各自占用多少字节。 4.1.1 String类能被继承吗,为什么。 4.1.2 String,Stringbuffer,StringBuilder的区别。 4.1.3 ArrayList和LinkedList有什么区别。 4.1.4 讲讲类的...
  • 在XML文档中,上述几种语句语法都是错误。因为: 1.所有标记都必须要有一个相应结束标记; 2.所有XML标记都必须合理嵌套; 3.所有XML标记都区分大小写; 4.所有标记属性必须用""括起来; 所以上列...
  • 软件工程教程

    热门讨论 2012-07-06 23:10:29
    顺序图、协作图:单用例中几个对象行为 顺序图突出顺序,协作图着重对象间链接关系 项目三 项目市场调研 任务1. 系统研发背景 任务2. 软件开发计划 油画创作背景 波洛克 《1948年第五号》 1.4亿$,最昂贵画作...
  • 人们可能还会使用一具有图形用户界面工具来从文本文件把SQL语句组合起来,甚至根本不需要显示自己实际代码。  接下来阶段是编写新SQL代码,但仍然像使用自己最初熟悉语言那样来操作。这种思维模式...
  • C#数据结构

    2013-12-10 11:49:54
    对于许多常见的问题,工 具箱里的数据结构是理想的选择。就像.NET Framework Windows应用程序开 发的工具箱,程序员可以直接拿来或经过少许的修改就可以使用,非常方便。 第二个是讲授常用的算法,这和数据结构...
  • 3. 把实例与适当集合、函数或关系模型相联系,并在上下文解释相关操作和术语。 4. 解释基本计算原理,包括对角化和鸽洞原理应用。 DS2. 基本逻辑 (核心) 主题: 命题逻辑 逻辑联结词 真值表 范式...
  • 9.17 示例:领域模型中的属性 9.18 结论:领域模型是否正确 9.19 过程:迭代和进化式领域建模 9.20 参考资料 第10章 系统顺序图 10.1 示例:NextGen SSD 10.2 什么是系统顺序图 10.3 动机:为什么绘制SSD ...
  • 内容主要集中在大多数企业常见的问题之上,如安装和升级到oracle database 11g数据库软件、创建数据库、导出和导入数据、数据库的备份与恢复、性能调优,等等。  本书还提供了dba完成本职工作必备的基本的uniix...
  • 1.2 .NET的几个特性 7 1.3 万丈高楼平地起:面试者必会 9 1.3.1 C#介绍 10 1.3.2 命名空间 10 1.3.3 C#语法格式要点 10 1.3.4 变量 12 1.3.5 类型推断 12 1.3.6 变量的作用域 13 1.3.7 常量 16 1.3.8 流程控制 16 ...
  • 6.3.4 几种算法比较 220 6.4 半连接 221 6.4.1 测试环境 221 6.4.2 合并与展开 222 6.4.3 (NOT)IN和(NOT)EXISTS哲学思想 224 6.4.4 Exists和In 224 6.4.5 Not Exists 228 6.4.6 Not In 229 6.5...
  • 1.3.6 DBA与开发人员的关系 44 1.4 小结 45 第2章 体系结构概述 46 2.1 定义数据库和实例 47 2.2 SGA和后台进程 52 2.3 连接Oracle 54 2.3.1 专用服务器 54 2.3.2 共享服务器 56 2.3.3 TCP/IP连接基本原理...
  • 中文版Excel.2007图表宝典 2/2

    热门讨论 2012-04-06 19:01:36
    第12章 避免常见的制图错误/317 12.1 了解观众/317 12.2 图表精确度/318 12.2.1 根据上下文的数据绘图/319 12.2.2 夸大差异或者相似处/320 12.2.3 以百分比变化和实际变化的形式绘图/321 12.2.4 Bin大小不等的分组/...
  • CruiseYoung提供带有详细...这章是本书精华,而且也是理解Oracle关键所在。第9章讨论redo和undo,解释了它们分别是什么,并指出如何避免各种可能出现错误。第10章介绍了各种类型表,其中最重要是堆组织表...
  • Reversing:逆向工程揭密

    热门讨论 2010-06-21 17:00:47
    Cross在他们文章给出了如下定义:软件逆向工程是分析目标系统,认定系统组件及其交互关系,并且通过高层抽象或其他形式来展现目标系统过程。 经过十发展,软件逆向工程领域已有不少研究成果和商业...
  • 《Effective c++ 》

    千次下载 热门讨论 2013-02-25 22:13:11
    它们不但开展读者视野,也为读者提供各种C++/OOP常见问题解决模型。某些主题虽然在百科型C++ 语言书也可能提过,但此类书籍以深度探索方式让我们了解问题背后成因、最佳解法,以及其他可能牵扯。这些都...
  • Apache Sqoop: 是一个用来将Hadoop和关系型数据库中的数据相互转移工具,可以将一个关系型数据库(MySQL ,Oracle ,Postgres等)中的数据导进到HadoopHDFS,也可以将HDFS数据导进到关系型数据库 ...

空空如也

空空如也

1 2
收藏数 23
精华内容 9
关键字:

关系模型中常见的几种术语