重温数据结构:树 及 Java 实现(转)
转自:http://blog.csdn.net/u011240877/article/details/53193877
读完本文你将了解到:
- 什么是树
- 树的相关术语
- 根节点父亲节点孩子节点叶子节点如上所述
- 节点的度
- 树的度
- 节点的层次
- 树的高度
- 树的深度
- 树的两种实现
- 数组表示
- 链表表示的节点
- 树的几种常见分类及使用场景
数据结构,指的是数据的存储形式,常见的有线性结构(数组、链表,队列、栈),还有非线性结构(树、图等)。
今天我们来学习下数据结构中的 树。
什么是树
线性结构中,一个节点至多只有一个头节点,至多只有一个尾节点,彼此连接起来是一条完整的线。
比如链表和数组:
而树,非线性结构的典型例子,不再是一对一,而变成了一对多(而图则可以是 多对多),如下图所示:
可以看到:
- 图中的结构就像一棵倒过来的树,最顶部的节点就是“根节点 (root 节点)”
- 每棵树至多只有一个根节点
- 根节点生出多个孩子节点,每个孩子节点只有一个父节点,每个孩子节点又生出多个孩子
- 父亲节点 (parent) 和孩子节点 (child) 是相对的
- 没有孩子节点的节点成为叶子节点 (leaf)
树的相关术语
根节点、父亲节点、孩子节点、叶子节点如上所述。
节点的度
一个节点直接含有的子树个数,叫做节点的度。比如上图中的 3 的度是 2,10 的度是 1。
树的度
一棵树中 最大节点的度,即哪个节点的子节点最多,它的度就是 树的度。上图中树的度为 2 。
节点的层次
从根节点开始算起,根节点算第一层,往后底层。比如上图中,3 的层次是 2,4 的层次是 4。
树的高度
树的高度是从叶子节点开始,自底向上增加。
树的深度
与高度相反,树的深度从根节点开始,自顶向下增加。
整个树的高度、深度是一样的,但是中间节点的高度 和 深度是不同的,比如上图中的 6 ,高度是 2 ,深度是 3。
树的两种实现
从上述概念可以得知,树是一个递归的概念,从根节点开始,每个节点至多只有一个父节点,有多个子节点,每个子节点又是一棵树,以此递归。
树有两种实现方式:
- 数组
- 链表
数组表示:
我们可以利用每个节点至多只有一个父节点这个特点,使用 父节点表示法 来实现一个节点:
public class TreeNode {
private Object mData; //存储的数据
private int mParent; //父亲节点的下标
public TreeNode(Object data, int parent) {
mData = data;
mParent = parent;
}
public Object getData() {
return mData;
}
public void setData(Object data) {
mData = data;
}
public int getParent() {
return mParent;
}
public void setParent(int parent) {
mParent = parent;
}
}
上述代码中,使用 角标 来指明父亲节点的位置,使用这个节点组成的数组就可以表示一棵树。
public static void main(String[] args){
TreeNode[] arrayTree = new TreeNode[10];
}
用数组实现的树表示下面的树,(其中一种 )结果就是这样的:
数组实现的树节点使用角标表示父亲的索引,下面用链表表示一个节点和一棵树:
链表表示的节点:
public class LinkedTreeNode {
private Object mData; //存储的数据
private LinkedTreeNode mParent; //父亲节点的下标
private LinkedTreeNode mChild; //孩子节点的引用
public LinkedTreeNode(Object data, LinkedTreeNode parent) {
mData = data;
mParent = parent;
}
public Object getData() {
return mData;
}
public void setData(Object data) {
mData = data;
}
public Object getParent() {
return mParent;
}
public void setParent(LinkedTreeNode parent) {
mParent = parent;
}
public LinkedTreeNode getChild() {
return mChild;
}
public void setChild(LinkedTreeNode child) {
mChild = child;
}
}
使用引用,而不是索引表示父亲与孩子节点。
使用一个 List, 元素是 LinkedTreeNode,就可以表示一棵链表树:
public static void main(String[] args){
LinkedList<LinkedTreeNode> linkedTree = new LinkedList<>();
}
这样只需知道 根节点就可以遍历整个树。知道某个节点也可以获取它的父亲和孩子。
树的几种常见分类及使用场景
树,为了更好的查找性能而生。
常见的树有以下几种分类:
- 二叉树
- 平衡二叉树
- B 树
- B+ 树
- 哈夫曼树
- 堆
- 红黑树
接下来陆续介绍完回来补使用场景。
重温数据结构:树 及 Java 实现(转)的更多相关文章
- 数据结构与抽象 Java语言描述 第4版 pdf (内含标签)
数据结构与抽象 Java语言描述 第4版 目录 前言引言组织数据序言设计类P.1封装P.2说明方法P.2.1注释P.2.2前置条件和后置条件P.2.3断言P.3Java接口P.3.1写一个接口P.3. ...
- Trie 树 及Java实现
来源于英文“retrieval”. Trie树就是字符树,其核心思想就是空间换时间. 举个简单的例子. 给你100000个长度不超过10的单词.对于每一个单词,我们要判断他出没出现过,如果出现 ...
- AVL树之 Java的实现
AVL树的介绍 AVL树是高度平衡的而二叉树.它的特点是:AVL树中任何节点的两个子树的高度最大差别为1. 上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1:而右边的不 ...
- AVL树的JAVA实现及AVL树的旋转算法
1,AVL树又称平衡二叉树,它首先是一颗二叉查找树,但在二叉查找树中,某个结点的左右子树高度之差的绝对值可能会超过1,称之为不平衡.而在平衡二叉树中,任何结点的左右子树高度之差的绝对值会小于等于 1. ...
- 数据结构与算法Java描述 队列
package com.cjm.queue; /** * 数据结构与算法Java实现 队列 * * @author 小明 * */ public class Myqueue { private Nod ...
- 双数组Trie树(DoubleArrayTrie)Java实现
http://www.hankcs.com/program/java/%E5%8F%8C%E6%95%B0%E7%BB%84trie%E6%A0%91doublearraytriejava%E5%AE ...
- 2-3-4树的java实现
一.什么是2-3-4树 2-3-4树和红黑树一样,也是平衡树.只不过不是二叉树,它的子节点数目可以达到4个. 每个节点存储的数据项可以达到3个.名字中的2,3,4是指节点可能包含的子节点数目.具体而言 ...
- 数据结构——单链表java简易实现
巩固数据结构 单链表java实现 单链表除了表尾 每个几点都有一个后继 结点有数据和后继指针组成 通过构建表头和表尾(尾部追加需要)两个特殊几点 实现单链表的一些操作,代码如下 package co ...
- ACM数据结构-树状数组
模板: int n; int tree[LEN]; int lowbit(int x){ return x&-x; } void update(int i,int d){//index,del ...
- Python入门篇-数据结构树(tree)的遍历
Python入门篇-数据结构树(tree)的遍历 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.遍历 迭代所有元素一遍. 二.树的遍历 对树中所有元素不重复地访问一遍,也称作扫 ...
随机推荐
- luogu P2511 [HAOI2008]木棍分割
传送门 第一问是一道经典的二分,二分答案\(ans\),然后从前往后扫,判断要分成几段救星了 第二问设\(f_{i,j}\)表示前\(i\)个数分成\(j\)段,每段之和不超过第一问答案的方案,转移就 ...
- IE8以下浏览器设置Title的问题
ie8不支持网页title的如下写法 $('title').text('标题'); $('title').html('标题'); 在ie8中,正确写法: document.title = &quo ...
- mysql 开源~canal维护相关问题
一 简介:咱们来讨论下canal的一些技巧 二 场景 场景1 canal过滤指定库后,后端java调用读取相关数据时候出现大量的空事务,为何会出现空事务呢,空事务是由于配置了指定的过滤规则,导致了其他 ...
- linux 串口0x03,0x13的问题【转】
linux 串口0x03,0x13的问题 本人最近在调linux串口的时候,发现其他数据接收正常,但是0x13怎么也接收不到,后面发现了这篇文章,两天的bug终于解决了,原来是linux底层uart配 ...
- C#使用RabbitMQ
1. 说明 在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的地方, ...
- odoo - context
得到整个context self.context_get() self.env['res.users'].context_get() 得到context里面对应的值 eg:得到flag的值 self. ...
- 一步步实现windows版ijkplayer系列文章之七——终结篇(附源码)
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- centos命令行变成了-bash-4.1$的解决办法
在使用root用户是先建立了用户yunva的家目录,然后添加yunva用户,切换到yunva用户后发现 命令行变成了-bash-4.1$ ①方法一(临时生效,不推荐) 1. bashrc 在当前目录下 ...
- [How to]HBase集群备份方法--Replication机制
1.简介 HBase备份的方法在[How to]HBase集群备份方法文章中已经有些介绍,但是这些方法都不是HBase本身的特性在支持,都是通过MR计算框架结合HBase客户端的方式,或者直接拷贝HB ...
- redhat5 设置静态ip
Last login: Sat Oct 14 16:19:13 2017 # 进入ip凭证文件设置地方 [root@oracle ~]# cd /etc/sysconfig/network-scrip ...