java数据结构----树
1.树:树通常结合了有序数组和链表的优点,在树中查找数据项的速度和在有序数组中查找一样快,并且插入数据项和删除数据项的速度也和链表一样快。
2.树由边连接的节点而构成。节点一般代表着一些实体,节点间的直线表示关联节点间的路径,java中通常用引用来表示路径(c等一般是指针),
2-1.树的图:
3.树有很多种,这里讨论一种特殊的树---二叉树,二叉树的节点最多有两个子节点。更普遍的树中子节点的个数可以多于两个。这种树称为多路树。
3.1.树的术语:
路径:设想一个沿着连接节点的边从一个节点走到另一个节点,所经过个节点的顺序排列就称为‘路径’。
关键字:可以看到,对象中通常有一个数据域被指定位关键字值,这个值通常用于查询或其他操作。在树的图形中,如果用圆来保存数据项的节点,那么一般将这个数据项的关键字值显示在这个圆中。
4.二叉树:如果树中每个节点最多只能有两个子节点,这样的树就称为二叉树。二叉树在学术上称为二叉搜索树(一个节点的左子节点的关键字值小于这个节点,右子节点的关键字值大于或等于这个父节点)。
5.二叉树的遍历(拿8.2图来说)
5.1.前序遍历:A--B--D--H--E--C--F--I--J--G
5.2.中序遍历:最常用,即将二叉搜索树按照关键字值升序访问。D--H--B--E--A--I--F--J--C--G
5.3.后序遍历:H--D--E--B--I--J--F--G--C--A
6.二叉树代码对象引用方式:
6.1.Node.java
package com.cn.tree;
/**
* 树的节点类
* @author Administrator
*
*/
public class Node {
int iData;
double fData;
Node leftchild;
Node rightchild;
public void displayNode(){
System.out.println("当前节点:"+iData+"\t左孩子:"+(leftchild == null?null:leftchild.iData)+"\t右孩子:"+(rightchild == null?null:rightchild.iData));
}
}
6.2.Tree.java
package com.cn.tree;
/**
* 树的代码
* @author Administrator
*
*/
public class Tree {
private Node root;
//查找关键字所在的节点
public Node find(int key){
Node current = root;
while (current.iData != key){
if (key < current.iData)
current = current.leftchild;
else
current = current.rightchild;
if (current == null)
return null;
}
return current;
}
//中序遍历
public void inorder(Node localroot){
if (localroot != null){
inorder(localroot.leftchild);
System.out.print(localroot.iData+" ");
inorder(localroot.rightchild);
}else{
System.out.println("");
}
}
//插入节点
public void insert(int id,double dd){
Node newnode = new Node();
newnode.iData = id;
newnode.fData = dd;
if (root == null)
root = newnode;
else{
Node current = root;
Node parent;
while (true){
parent = current;
if (id < current.iData){
current = current.leftchild;
if (current == null){
parent.leftchild = newnode;
return;
}
}
else{
current = current.rightchild;
if (current == null){
parent.rightchild = newnode;
return;
}
}
}
}
}
//获取树中的最小值节点
public Node min(){
Node current,last = null;
current = root;
while (current != null){
last = current;
current = current.leftchild;
}
return last;
}
//获取树中的最大值节点
public Node max(){
Node current,last = null;
current = root;
while (current != null){
last = current;
current = current.rightchild;
}
return last;
}
//删除节点
public boolean delete(int key){
Node current = root;
Node parent = root;
boolean isleftchild = true;
//寻找待删除关键字值所在节点
while (current.iData != key){
parent = current;
if (key < current.iData){
isleftchild = true;
current = current.leftchild;
}
else{
isleftchild = false;
current = current.rightchild;
}
if (current == null)
return false;
}
//如果要删除的节点没有孩子节点
if (current.leftchild == null && current.rightchild == null){
if (current == root)
root = null;
else if (isleftchild)
parent.leftchild = null;
else
parent.rightchild = null;
}
//如果待删除的节点只有左孩子节点
else if (current.rightchild == null)
if (current == root)
root = current.leftchild;
else if (isleftchild)
parent.leftchild = current.leftchild;
else
parent.rightchild = current.leftchild;
//如果待删除节点只有右孩子节点
else if (current.leftchild == null)
if (current == root)
root = current.rightchild;
else if (isleftchild)
parent.leftchild = current.rightchild;
else
parent.rightchild = current.leftchild;
//如果左右孩子节点都存在
else{
Node successor = getSuccessor(current);
if (current == root)
root = successor;
else if (isleftchild)
parent.leftchild = successor;
else
parent.rightchild = successor;
successor.leftchild = current.leftchild;
}
return true;
}
//获取要删除节点的后继节点
private Node getSuccessor(Node delnode){
Node successorparent = delnode;
Node successor = delnode;
Node current = delnode.rightchild;
while (current != null){
successorparent = successor;
successor = current;
current = current.leftchild;
}
if (successor != delnode.rightchild){
successorparent.leftchild = successor.rightchild;
successor.rightchild = delnode.rightchild;
}
return successor;
}
}
6.3.TTest.java
package com.cn.tree;
public class TTest {
public static void main(String[] args) {
Tree t = new Tree();
t.insert(4, 4.0);
t.insert(1, 1.0);
t.insert(3, 3.0);
t.insert(2, 2.0);
t.insert(6, 6.0);
t.insert(5, 5.0);
Node node = t.find(4);
node.displayNode();
// node.displayNode();
t.inorder(node);
// System.out.println(t.max().iData);
// System.out.println(t.min().iData);
t.delete(1);
t.inorder(node);
}
}
7.二叉树的效率:如果是满二叉树,常见操作的效率为O(logN),如果树不满,就不好确定了。
8.红黑树:他是二叉树的升级版,主要针对二叉搜索树在插入有序数据(正序或逆序)时,树其实就成为链表。二叉树就会失去平衡,成为非平衡树。对于非平衡树,它的查找(添加,删除)指定数据项的能力就丧失了。红黑树的平衡是在它的插入(删除也是)过程中取得的。对于一个要插入的数据项,插入例程要检查不会破坏树一定的特征。如果破坏了,程序就会进行修正,根据需要更改树的结构。通过维持树的特征,保持树的平衡。
9.红黑树的特征:①节点都有颜色 ②在插入和删除的过程中,要遵循保持这些颜色的不同排列的规则。
10.红黑规则:当插入(或删除)一个新节点时,必须要遵循一定的规则,我们称之为红黑规则,如果遵循这些规则,树就是平衡的。
①每一个节点不是红色就是黑色;
②跟总是黑色的;
③如果节点是红色的,则它的子节点必须是黑色的(反之不一定必须为真);
④从根到叶子节点或空子节点的每条路径,必须包含相同数目的黑色节点(从根到叶节点路径上的黑色高度必须相同)。
空子节点:非叶节点可以接子节点的位置。换句话说就是一个有右子节点的节点可能接左子节点的位置。或者是有左子节点的节点可能接右子节点的位置。
重复关键字值的处理:如果有多余一个数据项的关键字值相同,需要把有相同关键字的数据项分配到其他也有相同关键字的数据项两侧,也就是说如果有50,50,50,要把第 二个50放到第一个50的右边,并且把第三个50放到第一个50的左边,否则树将不平衡。目前只讨论不含有相同数据项的序列。
11.修正违规的情况:①改变节点颜色 ②执行旋转操作。
11.1.变色:
11.2.旋转:
12.黑色高度:
13.具体的删除插入详情请查看《java数据结构与算法》一书。
java数据结构----树的更多相关文章
- Java数据结构——树的三种存储结构
(转自http://blog.csdn.net/x1247600186/article/details/24670775) 说到存储结构,我们就会想到常用的两种存储方式:顺序存储和链式存储两种. 先来 ...
- Java数据结构——树、二叉树的理论知识汇总
通用树的理论知识 一.树的定义 由一个或多个(n>=0)节点组成的有限集合T,有且仅有一个节点称为根(root),当n>1时,其7余的节点为m(m>=0)个互不相交的有限集合T1,T ...
- Java数据结构和算法(四)赫夫曼树
Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...
- Java数据结构之树和二叉树(2)
从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...
- Java数据结构之树和二叉树
从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...
- Java数据结构和算法 - 什么是2-3-4树
Q1: 什么是2-3-4树? A1: 在介绍2-3-4树之前,我们先说明二叉树和多叉树的概念. 二叉树:每个节点有一个数据项,最多有两个子节点. 多叉树:(multiway tree)允许每个节点有更 ...
- Java数据结构和算法(七)B+ 树
Java数据结构和算法(七)B+ 树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 我们都知道二叉查找树的查找的时间复杂度是 ...
- Java数据结构和算法(一)树
Java数据结构和算法(一)树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 前面讲到的链表.栈和队列都是一对一的线性结构, ...
- Java数据结构和算法(二)树的基本操作
Java数据结构和算法(二)树的基本操作 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 一.树的遍历 二叉树遍历分为:前序遍 ...
随机推荐
- oracle rac常用的网络检查命令
oracle的集群管理软件和数据库对私网依赖性很大,很多集群问题最后都可以归结到网络层面. 当集群出现问题时检查网络信息是必要的. 1.查看MTU的大小,确认所有节点的公网和私网网卡的MTU大小相同 ...
- 不使用库函数,编写函数int strcmp(char *source, char *dest) 相等返回0,不等返回-1【转】
本文转载自:http://www.cppblog.com/mmdengwo/archive/2011/04/14/144253.aspx #include <stdio.h>#includ ...
- zoj 2313 Chinese Girls' Amusement 解题报告
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1313 题目意思:有 N 个人(编号依次为1~N)围成一个圆圈,要求求 ...
- Mongodb GridFS——适合大小超过16MB的文件
一.概述 GridFS是基于mongodb存储引擎是实现的“分布式文件系统”,底层基于mongodb存储机制,和其他本地文件系统相比,它具备大数据存储的多个优点.GridFS适合存储超过16MB的大型 ...
- 记SCOI2017
Day1完挂,OI再见. 居然卡进去了. UESTC的评测机见鬼啊,我本地不到1s.时限是3s的两道题都T了,然后就少了50pt. Day1 T1看完首先O(n^2)DP是裸的,然后感觉n选k好像不能 ...
- IO多路复用模型之epoll实现机制
设想一下如下场景:有100万个客户端同时与一个服务器进程保持着TCP连接.而每一时刻,通常只有几百上千个TCP连接是活跃的(事实上大部分场景都是这种情况).如何实现这样的高并发? 在select/po ...
- springmvc源码分析----入门看springmvc的加载过程
接上一篇我们写的入门---http://www.cnblogs.com/duanxiaojun/p/6591448.html 今天从这个门里进去我们看springmvc是如何在容器启动的时候将各个模块 ...
- Even Three is Odd
题意: 问题是对于所有的长度为n,且$1<=ai<=n$的整数序列求 $\prod_{i=1}^{n-2}{max \{w_i,w_{i+1},w_{i+2}}\}$ 之和. 解法: 首先 ...
- JAVA 数组的常用操作
目录: 声明数组: 初始化数组: 查看数组长度: 遍历数组: int数组转成string数组: 从array中创建arraylist: 数组中是否包含某一个值: 将数组转成set集合: 将数组转成li ...
- http://www.cnblogs.com/dasenglin/p/5821987.html
一安装maven 先安装jdk,配置JAVA_HOME 把下载的maven bin包,解压到指定目录,比如:D:\apache-maven-3.3.9-bin 配置maven的系统变量M2_HOME和 ...