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) 一.树的遍历 二叉树遍历分为:前序遍 ...
随机推荐
- 如何配置DSI时钟频率
[DESCRIPTION] 计算DSI数据速率的方式,以及如何配置时钟clk的方式 [KEYWORD] dsi.data rate.mipi clk [SOLUTION] 1.DSI vdo mode ...
- Appium——连接真机,adb devices获取不到设备号
连接真机后,使用 adb devices获取不到设备号. 1.检查usb接口是否正常,是否正常链接到电脑 2.手机开发者模式是否开启,usb调试是否开启 3.检查驱动是否正常 4.如果驱动显示黄叹号, ...
- TCP与HTTP连接管理
一. HTTP事务时延原因(HTTP权威指南 P86) 1.客户端首先需要根据URI确定WEB服务器的IP和端口号, 那么DNS解析上花的时间会很多(大多数HTTP客户端会有一个小的DNS缓存) ...
- struts2中<s:if>标签的使用
转载:http://blog.sina.com.cn/s/blog_5f9938640100v2kr.html A:<s:if>判断字符串的问题: 1.判断单个字符:<s:if te ...
- css 浏览器兼容性问题集合
http://www.xidayun.com/index.php/2016/05/16/941/ 文章取自前端蜂小客
- http://www.cnblogs.com/yaozhenfa/archive/2015/06/14/4574898.html
笔者这里采用的是mongoDB官网推荐使用.net驱动: http://mongodb.github.io/mongo-csharp-driver/2.0/getting_started/quick_ ...
- v-for指令用法二
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- SPOJ Find the max XOR value(二进制,贪心即可)
You have two integers L and R, and you are required to find the max xor value of a and b where L < ...
- excel 基本用法
- BZOJ_2850_巧克力王国_KDTree
BZOJ_2850_巧克力王国_KDTree Description 巧克力王国里的巧克力都是由牛奶和可可做成的.但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜 欢过于甜的巧克力.对于每一块 ...