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) 一.树的遍历 二叉树遍历分为:前序遍 ...
随机推荐
- progressbar请求数据 加载demo1
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout ...
- Codeforces Round #374 (Div. 2) C. Journey —— DP
题目链接:http://codeforces.com/contest/721/problem/C C. Journey time limit per test 3 seconds memory lim ...
- SystemV和BSD的区别
目前,Unix操作系统不管其内核如何,其操作风格上主要分为SystemV(目前一般采用其第4个版本SVR4)和BSD两种.其代表操作系统本别是Solaris和FreeBSD.当然,在SunOS4(So ...
- TestNG测试用例编写和执行
编写TestNG用例测试基本上包括以下步骤: 编写业务逻辑 针对业务逻辑中涉及的方法编写测试类,在代码中插入TestNG的注解 直接执行测试类或者添加一个testng.xml文件 运行 TestNG. ...
- html5--6-1 引入外部样式表
html5--6-1 引入外部样式表 实例 学习要点 掌握引入外部样式表方法 插入样式的三种方法 内联样式表(行内) 内部样式表(style中) 外部样式表 创建一个外部样式表 在head中使用lin ...
- php的CURL使用及例子
使用PHP的cURL库可以简单和有效地去抓网页.你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了.无论是你想从从一个链接上取部分数据,或是取一个XML文件并把 ...
- php字符串啊的heredoc格式
Heredoc技术,在正规的PHP文档中和技术书籍中一般没有详细讲述,只是提到了这是一种Perl风格的字符串输出技术.它也出现unix/linux的shell编程里面.但是现在的一些论坛程序,和部分文 ...
- docker安装mysql挂载宿主本地目录资源后无法启动的问题
可能是权限问题,添加--privileged=true参数: docker run -p : --name zsmysql -v $PWD/data:/var/lib/mysql -v $PWD/lo ...
- 自定义带图标input样式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- June 25,2014---->Binder(IPC),Dalvik ,DEX/ODEX
1.Binder(IPC) Linux进程之间要能够互相通信,从而共享资源和信息.所以,操作系统内核必须提供进程间的通信机制(IPC,Inter-Process Communication). IPC ...