- 浏览: 539972 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
GGGGeek:
看完了博主的博文,如果没猜错的话应该是浙大吧?很多优秀的人因为 ...
转《D君的故事》 以时刻警示自己 -
游牧民族:
楼主写的不错,学习了,最近对爬虫比较感兴趣,也写了些爬虫相关的 ...
通用爬虫框架及heritrix爬虫介绍 -
jimmee:
jerome_s 写道ice 你怎么看? 粗略的看了一下ice ...
MessagePack, Protocol Buffers和Thrift序列化框架原理和比较说明 -
jerome_s:
ice 你怎么看?
MessagePack, Protocol Buffers和Thrift序列化框架原理和比较说明 -
jimmee:
nk_tocean 写道照着做了,但是不行啊,还是乱码.先确认 ...
hive编写udf处理非utf-8数据
3.树的说明
树:T={K,R}。K是包含n个结点的有穷集合(n>0),关系R满足以下条件:
(1)有且仅有一个结点k0∈K,它对于关系R来说没有前驱结点,结点k0称作树的根。
(2)除结点k0外,K中的每个结点对于关系R来说都有且仅有一个前驱结点。
(3)K中每个结点对于关系R来说可以有多个后继结点。
我这里主要讨论的是二叉树,因为这个是用的最广泛的,二叉树也称为二次树或二分树,它是有限的结点集合,这个集合或者是空,或者由一个根结点和两棵互不相交的称为左子树和右子树的二叉树组成。
二叉树的节点定义形式如下:
class TreeNode<E>{
Comparable<E> key;//节点的值
TreeNode<E> llink;//左子树的指针
TreeNode<E> rlink;//右子树的指针
}
假如我们有这样一棵树
2
/ \
4 5
/ \/ \
7 310 8
/\ /
1 9 6
1)树的遍历:就是访问所有的节点一遍。一般来说,有四种遍历的方式,前序遍历:先访问节点本身,在访问左子树,之后再访问右子树,例如上面的树,前序遍历的次序是2 4 7 1 9 3 6 5 10 8;中序遍历,就是先访问左子树,再访问节点本身,最后访问右子树,上面的树中序遍历的次序是1 7 9 4 6 3 2 10 5 8;后序遍历,就是先访问左子树,再访问右子树,最后访问节点,上面的树后序遍历的次序是1 9 7 6 3 4 10 8 5 2;层次遍历就是按层次访问树的节点,上面的树层次遍历的属次序是2 4 5 7 3 10 8 1 9 6
具体代码实现,可以采用递归的方式实现,也可以采用非递归的方式实现。
递归方式实现(注意,我写的大体过程,具体使用时大家根据实际情况修改一下):
前序遍历:
中序遍历:
后序遍历:
层次遍历:
我前面已经说过,使用递归只不过由系统在为我们维护一个调用栈,我们也可以具体明确的使用堆栈来非递归的实现树的遍历。
非递归实现树的遍历,我们先构建好一棵树,初始化一个栈,之后我们进入一个循环,我们不断弹出堆栈里的元素,直到堆栈为空,如果弹出的树节点表示一棵空树,我们就访问此节点,否则,我们根据下面的规则执行一系列的push操作。
对于前序:压入右子树,然后是左子树,再后是节点
对于中序:压入右子树,然后是节点,再后是左子树
对于后序:压入节点,然后是右子树,再后是左子树
当我们把一个节点的左右节点及本节点都入栈后,我们的节点本身就可以看成一棵空树了。为了标识这一特性,我们修改树节点为:
class TreeNode<E>{
Comparable<E> key;//节点的值
TreeNode<E> llink;//左子树的指针
TreeNode<E> rlink;//右子树的指针
boolean flag;//是否是空树
}
前序遍历的代码:
中序遍历的代码:
后序遍历的代码:
树:T={K,R}。K是包含n个结点的有穷集合(n>0),关系R满足以下条件:
(1)有且仅有一个结点k0∈K,它对于关系R来说没有前驱结点,结点k0称作树的根。
(2)除结点k0外,K中的每个结点对于关系R来说都有且仅有一个前驱结点。
(3)K中每个结点对于关系R来说可以有多个后继结点。
我这里主要讨论的是二叉树,因为这个是用的最广泛的,二叉树也称为二次树或二分树,它是有限的结点集合,这个集合或者是空,或者由一个根结点和两棵互不相交的称为左子树和右子树的二叉树组成。
二叉树的节点定义形式如下:
class TreeNode<E>{
Comparable<E> key;//节点的值
TreeNode<E> llink;//左子树的指针
TreeNode<E> rlink;//右子树的指针
}
假如我们有这样一棵树
2
/ \
4 5
/ \/ \
7 310 8
/\ /
1 9 6
1)树的遍历:就是访问所有的节点一遍。一般来说,有四种遍历的方式,前序遍历:先访问节点本身,在访问左子树,之后再访问右子树,例如上面的树,前序遍历的次序是2 4 7 1 9 3 6 5 10 8;中序遍历,就是先访问左子树,再访问节点本身,最后访问右子树,上面的树中序遍历的次序是1 7 9 4 6 3 2 10 5 8;后序遍历,就是先访问左子树,再访问右子树,最后访问节点,上面的树后序遍历的次序是1 9 7 6 3 4 10 8 5 2;层次遍历就是按层次访问树的节点,上面的树层次遍历的属次序是2 4 5 7 3 10 8 1 9 6
具体代码实现,可以采用递归的方式实现,也可以采用非递归的方式实现。
递归方式实现(注意,我写的大体过程,具体使用时大家根据实际情况修改一下):
前序遍历:
public static void preOrder(TreeNode root){ if(root==null) return; visit(root); preOrder(root.llink); preorder(root.rlink); }
中序遍历:
public static void inOrder(TreeNode root){ if(root==null) return; inOrder(root.link); visit(root); inOrder(root.rlink); }
后序遍历:
public static void postOrder(TreeNode root){ if(root==null) return; postOrder(root.llink); postOrder(root.rlink); visit(root); }
层次遍历:
public static void layerOrder(TreeNode root){ if(root==null) return; ListQueue<TreeNode> q=new ListQueue<TreeNode>(); q.insert(root); while(!q.empty()){ TreeNode temp=q.remove(); visit(temp); if(temp.llink!=null) q.insert(temp.llink); if(temp.rlink!=null) q.insert(temp.rlink); } }
我前面已经说过,使用递归只不过由系统在为我们维护一个调用栈,我们也可以具体明确的使用堆栈来非递归的实现树的遍历。
非递归实现树的遍历,我们先构建好一棵树,初始化一个栈,之后我们进入一个循环,我们不断弹出堆栈里的元素,直到堆栈为空,如果弹出的树节点表示一棵空树,我们就访问此节点,否则,我们根据下面的规则执行一系列的push操作。
对于前序:压入右子树,然后是左子树,再后是节点
对于中序:压入右子树,然后是节点,再后是左子树
对于后序:压入节点,然后是右子树,再后是左子树
当我们把一个节点的左右节点及本节点都入栈后,我们的节点本身就可以看成一棵空树了。为了标识这一特性,我们修改树节点为:
class TreeNode<E>{
Comparable<E> key;//节点的值
TreeNode<E> llink;//左子树的指针
TreeNode<E> rlink;//右子树的指针
boolean flag;//是否是空树
}
前序遍历的代码:
public static void preOrder(TreeNode<E> node){ if(node==null)return; ListStack<TreeNode<E>> stack=new ListStack<TreeNode<E>>(); stack.push(node); while(!stack.empty()){ TreeNode<E> t=stack.pop(); if(t.flag){ System.out.print(t.item+","); }else{ if(t.rlink!=null) stack.push(t.rlink); if(t.llink!=null) stack.push(t.llink); stack.push(t); t.flag=true; } } }
中序遍历的代码:
public static void preOrder(TreeNode<E> node){ if(node==null)return; ListStack<TreeNode<E>> stack=new ListStack<TreeNode<E>>(); stack.push(node); while(!stack.empty()){ TreeNode<E> t=stack.pop(); if(t.flag){ System.out.print(t.item+","); }else{ if(t.rlink!=null) stack.push(t.rlink); stack.push(t); if(t.llink!=null) stack.push(t.llink); t.flag=true; } } }
后序遍历的代码:
public static void preOrder(TreeNode<E> node){ if(node==null)return; ListStack<TreeNode<E>> stack=new ListStack<TreeNode<E>>(); stack.push(node); while(!stack.empty()){ TreeNode<E> t=stack.pop(); if(t.flag){ System.out.print(t.item+","); }else{ stack.push(t); if(t.rlink!=null) stack.push(t.rlink); if(t.llink!=null) stack.push(t.llink); t.flag=true; } } }
发表评论
-
moses安装记录
2016-12-11 11:00 01. moses的安装说明地址(注意,一定要安装好相应的bo ... -
翻译算法
2016-12-09 07:50 0翻译的概率T=argsMaxP(T|S)=P(T)P(S|T ... -
JPEG 简易文档 V2.15【转载】
2016-04-10 16:35 635JPEG 简易文档 V2.15 ------------- ... -
Java 并发之 ConcurrentSkipListMap 简述
2015-09-20 20:24 1125JCIP 提到了在 Java 6 中引入了两个新的并发集合类 ... -
最简单的平衡树(红-黑树)的实现
2015-09-04 08:04 1190在二叉搜索树(BST)的基础上,要实现一颗平衡树,可以使用 ... -
lucene索引创建的理解思路
2014-06-29 23:12 1485虽然lucene4很早就出来,但是这里仍然以lucene3. ... -
lucene的拼写检查的实现原理
2014-06-08 18:19 13161. 建索引时, 使用ngram的方式创建索引 Sp ... -
字符串相似算法-(3) NGram Distance
2014-06-08 17:54 4902就是N-Gram version of edit dista ... -
字符串相似算法-(2) Levenshtein distance
2014-06-08 16:32 2231编辑距离概念描述: ... -
字符串相似算法-(1) Jaro-Winkler Distance
2014-06-08 12:05 6759Jaro-Winkler Distance 算法 ... -
Lucene的数字范围搜索 (Numeric Range Query)原理
2014-04-05 16:08 135550. 全文索引的核心就是倒排索引. 1. 若 ... -
UDT协议-基于UDP的可靠数据传输协议的实现分析(7)-流量和拥塞控制
2014-04-02 20:53 4143流量控制 对于一个带宽1Gbps, RTT为100ms的网络 ... -
UDT协议-基于UDP的可靠数据传输协议的实现分析(6)-链接的建立和关闭
2014-04-01 22:47 20491. 模式有client/server mode(客户端, ... -
协议-基于UDP的可靠数据传输协议的实现分析(5)-可靠性怎么保证
2014-03-31 23:08 3782发送方的处理:1) 包发送确认后,由于还没有收到确认,先缓存 ... -
UDT协议-基于UDP的可靠数据传输协议的实现分析(4)-发送和接收的算法
2014-03-30 10:09 71530. 计时器udt有四种计时器: ACK, NAK, E ... -
UDT协议-基于UDP的可靠数据传输协议的实现分析(3)-包结构说明
2014-03-29 17:24 3202udt的包结构1. 数据包,基本结构如下: 0 ... -
UDT协议-基于UDP的可靠数据传输协议的实现分析(2)-为什么要用udt
2014-03-28 08:00 37640. AIMD算法的简单回顾 (1) 慢开始 ... -
UDT协议-基于UDP的可靠数据传输协议的实现分析(1)-准备工作
2014-03-27 12:52 38191. 协议实现方案: Yunhong Gu提出的rfc的草 ... -
mapreduce的一些算法设计,优化等(2)
2014-01-28 15:50 14731. 反序(order inversion ... -
mapreduce的一些算法设计,优化等(1)
2014-01-27 17:15 2076本系列是根据书籍《Da ...
相关推荐
### 数据结构 C语言版 第三版习题答案解析 #### 习题1解析 ##### 1.1 选择题解析 题目中给出的选择题答案较为简单,主要考察学生对基本概念的理解。例如: - **第1题** 考察的是数据结构的基本分类。 - **第2题** ...
在这个名为“数据结构JAVA实现”的压缩包中,我们可以看到作者提供了三种重要的数据结构——链表、有序二叉树和队列的Java代码实现。 首先,让我们详细探讨链表。链表是一种线性数据结构,与数组不同,它不连续存储...
本项目聚焦于“串”的基本操作,这是一种常见的线性数据结构,通常用于存储文本信息。在这里,我们将深入探讨串的基本操作,以及如何通过编程实现这些操作。 串是由字符组成的序列,通常在许多编程语言中被表示为...
联众HIS1.0版数据结构说明书详细阐述了该医疗信息系统的数据组织方式,为理解和操作该系统提供了基础。HIS(Hospital Information System)是医院信息系统,它整合了医院内的各种信息资源,实现了医疗业务流程的自动...
在这个《数据结构课程设计》项目中,我们专注于二叉树的基本操作,通过两个源文件(file1.cpp 和 file2.cpp)以及一个头文件(head.h)实现了一系列的二叉树操作。以下是这些操作的详细说明: 1. **创建二叉树**:...
1. **数据结构基础**:首先,我们需要理解基本的数据结构类型,如数组、链表、栈、队列等。数组是最基础的数据结构,提供随机访问;链表允许动态插入和删除,但访问效率较低;栈遵循“后进先出”(LIFO)原则,常...
作者采用了独特的方法将数据结构分成说明和实现两部分,并充分利用了已有的数据结构库(Java集合类API)。本书分为四个部分:第一部分讨论适合大多数应用的集合类API的一个子集,并覆盖基本的算法分析技术、递归和...
本资源提供了数据结构题集的完整答案,涵盖了数据结构的基本概念、抽象数据类型、存储结构、数据类型等方面的知识点。下面是对资源中提到的知识点的详细解释: 1. 数据结构的基本概念 根据题目,数据是对客观事物...
《数据结构与算法分析C++描述第三版》一书,不仅深入浅出地介绍了数据结构与算法的核心概念,还以C++为载体,将理论与实践紧密结合,为读者提供了一个全面学习的平台。 在这本教材中,数据结构的基础知识被细致讲解...
课程内容重点介绍了算法和数据结构的基本概念、理论及其在实际应用中的重要性。王教授的课程不仅深入浅出地讲述了理论知识,而且还注重实践应用,帮助学生掌握如何将复杂问题转化为计算机可处理的形式,并通过合理...
2. **数据结构选择**:说明所选用的数据结构,比如可能选择链表实现队列,二叉树实现搜索结构等,解释选择的理由。 3. **算法设计**:详细描述用于操作数据结构的算法,如排序、查找等,可以包括插入、删除、查找等...
作者采用了独特的方法将数据结构分成说明和实现两部分,并充分利用了已有的数据结构库(Java集合类API)。本书分为四个部分:第一部分讨论适合大多数应用的集合类API的一个子集,并覆盖基本的算法分析技术、递归和...
接下来,我将详细说明算法文档和基本数据结构中的一些关键知识点。 算法文档的写作通常遵循以下结构: 1. 引言:这部分一般会解释算法的背景,应用场景以及算法的目的和功能。 2. 算法描述:这是算法文档的核心...
首先,我们需要理解数据结构的基本概念。数据结构是研究数据的逻辑结构、物理结构以及它们之间的相互关系。在计算机程序中,数据往往不是无序的,而是具有一定的结构,比如电话号码查询系统中的名字与电话号码对应...
数据结构作业通常会涵盖这些基本数据结构的操作,例如,用C++实现栈的基本操作、链表的反转、二叉树的遍历等,以提升对数据结构的实际运用能力。 四、数据结构学习指导 学习数据结构时,应理解每个结构的特性和适用...
本书对每一种数据结构都给出了相应的抽象数据类型规范说明和实现方法,使得学生能够掌握每种数据结构的逻辑结构和存储结构,并能够分析和比较不同算法的性能。 该书采用类C语言描述数据结构和算法,考虑到C语言的...
第一部分:数据结构与算法的基本概念 考核内容: 算法、算法正确性、复杂性; 算法的时间与空间复杂性级别; 数据类型、数据结构和表示、实现; 抽象数据类型的说明、高级语言对抽象数据类型的支持 考核要求: 理解...
基于C语言实现的基本数据结构定义以及简单的解题应用项目源码.zip基于C语言实现的基本数据结构定义以及简单的解题应用项目源码.zip基于C语言实现的基本数据结构定义以及简单的解题应用项目源码.zip基于C语言实现的...