-
SQL Server 2008数据库设计与实现(关系数据库实现的通关宝典)--随书源代码
2013-02-06 12:04:00这也难怪,设计、开发人员在学校中学习数据库时,理论书籍离实际开发较远——试问有几个人能够以可实践的方式把规范化的几条原则阐述清楚?在工作时,使用的数据库资料和书籍又往往是“手册型”,大多仅仅讲解特定... -
最权威的C++教程_C++_Primer_Plus中文第五版+C++_Primer中文第四版(都含源码+习题)(共4分卷)分卷1
2010-06-23 17:33:55学习C++是一次探索之旅,因为这种语言容纳了好几种编程模式,其中包括面向对象编程、通用编程和 传统的过程化编程。随着新特性的不断添加,C++一度成为一个活动目标,不过现在有了2003年的ISO/ ANSIC++标准第二... -
最权威的C++教程_C++_Primer_Plus中文第五版+C++_Primer中文第四版(都含源码+习题)(共4分卷)分卷2
2010-06-23 17:47:19学习C++是一次探索之旅,因为这种语言容纳了好几种编程模式,其中包括面向对象编程、通用编程和 传统的过程化编程。随着新特性的不断添加,C++一度成为一个活动目标,不过现在有了2003年的ISO/ ANSIC++标准第二... -
最权威的C++教程_C++_Primer_Plus中文第五版+C++_Primer中文第四版(都含源码+习题)(共4分卷)分卷3
2010-06-23 18:03:39学习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框架的个人博客系统项目毕业设计论文(源码和论文)
2011-03-12 10:44:33由于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轻松学习手册--XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解
2008-12-05 08:39:07在XML文档中,上述几种语句的语法都是错误的。因为: 1.所有的标记都必须要有一个相应的结束标记; 2.所有的XML标记都必须合理嵌套; 3.所有XML标记都区分大小写; 4.所有标记的属性必须用""括起来; 所以上列... -
软件工程教程
2012-07-06 23:10:29顺序图、协作图:单用例中几个对象的行为 顺序图突出顺序,协作图着重对象间链接关系 项目三 项目市场调研 任务1. 系统的研发背景 任务2. 软件开发计划 油画创作背景 波洛克 《1948年第五号》 1.4亿$,最昂贵画作... -
SQL沉思录(世界级SQL专家经典著作)--详细书签版
2013-02-04 13:08:03人们可能还会使用一种具有图形用户界面的工具来从文本文件中把SQL语句组合起来,甚至根本不需要显示自己的实际代码。 接下来的阶段是编写新的SQL代码,但仍然像使用自己最初熟悉的语言那样来操作。这种思维模式的... -
C#数据结构
2013-12-10 11:49:54对于许多常见的问题,工 具箱里的数据结构是理想的选择。就像.NET Framework 中Windows应用程序开 发中的工具箱,程序员可以直接拿来或经过少许的修改就可以使用,非常方便。 第二个是讲授常用的算法,这和数据结构... -
计算机要学哪些东西----(还有附赠哦)
2010-11-21 12:50:473. 把实例与适当的集合、函数或关系模型相联系,并在上下文中解释相关的操作和术语。 4. 解释基本的计算原理,包括对角化和鸽洞原理的应用。 DS2. 基本逻辑 (核心) 主题: 命题逻辑 逻辑联结词 真值表 范式... -
UML和模式应用(架构师必备).part01.rar
2010-04-02 14:11:239.17 示例:领域模型中的属性 9.18 结论:领域模型是否正确 9.19 过程:迭代和进化式领域建模 9.20 参考资料 第10章 系统顺序图 10.1 示例:NextGen SSD 10.2 什么是系统顺序图 10.3 动机:为什么绘制SSD ... -
Oracle Database 11g数据库管理艺术--详细书签版
2012-09-30 01:09:45书中内容主要集中在大多数企业常见的问题之上,如安装和升级到oracle database 11g数据库软件、创建数据库、导出和导入数据、数据库的备份与恢复、性能调优,等等。 本书还提供了dba完成本职工作必备的基本的uniix... -
亮剑.NET深入体验与实战精要2
2013-04-02 16:05:241.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 ... -
Oracle DBA突击:帮你赢得一份DBA职位--详细书签版
2013-02-06 15:56:406.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... -
Oracle Database 9i10g11g编程艺术:深入数据库体系结构(第2版)--详细书签版
2013-02-03 11:42:531.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大小不等的分组/... -
Oracle 9i & 10g编程艺术:深入数据库体系结构(09年度畅销榜TOP50)(08年度畅销榜TOP50)--详细书签版
2013-02-06 18:24:20CruiseYoung提供的带有详细...这几章是本书的精华,而且也是理解Oracle的关键所在。第9章讨论redo和undo,解释了它们分别是什么,并指出如何避免各种可能出现的错误。第10章介绍了各种类型的表,其中最重要的是堆组织表... -
Reversing:逆向工程揭密
2010-06-21 17:00:47Cross在他们的文章中给出了如下定义:软件逆向工程是分析目标系统,认定系统的组件及其交互关系,并且通过高层抽象或其他的形式来展现目标系统的过程。 经过十几年的发展,软件逆向工程领域已有不少研究成果和商业... -
《Effective c++ 》
2013-02-25 22:13:11它们不但开展读者的视野,也为读者提供各种C++/OOP常见问题的解决模型。某些主题虽然在百科型C++ 语言书中也可能提过,但此类书籍以深度探索的方式让我们了解问题背后的成因、最佳解法,以及其他可能的牵扯。这些都... -
Apache Sqoop: 是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中 ...
收藏数
23
精华内容
9
-
信息安全管理与信息安全体系实践.ppt
-
公安系统集成项目标准汇总
-
基于51单片机的洗衣机控制器设计.rar
-
使用 Linux 平台充当 Router 路由器
-
uniapp组件-uni-tag标签
-
华为1+X——网络系统建设与运维(中级)
-
自动化测试Python3+Selenium3+Unittest
-
信息安全风险评估服务手册.doc
-
项目经理成长之路
-
三级网络技术知识点小礼包.pdf
-
如何开通流量主
-
用Go语言来写区块链(一)
-
linux c MD5加密 程序源代码 和 测试程序
-
ubuntu20.04上搭建linux内核驱动调试环境
-
Win8.1 Apps应用部署v2.6
-
2021-03-02
-
MMM 集群部署实现 MySQL 高可用和读写分离
-
linux c 通过FTP 协议上传文件 源码 亲测可用
-
Xshell连接VMware虚拟机
-
Vue项目城市选择页-页面的动态数据渲染(8-5)