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) 一.树的遍历 二叉树遍历分为:前序遍 ...
随机推荐
- 剑指Offer:树的子结构【26】
剑指Offer:树的子结构[26] 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 解题思路 分为两步: 第一步:在树A中找到和树B的根节点的值一 ...
- hihocoder #1122 二分图二•二分图最大匹配之匈牙利算法(*【模板】应用 )
梳理整个算法: 1. 依次枚举每一个点i: 2. 若点i尚未匹配,则以此点为起点查询一次交错路径. 最后即可得到最大匹配数. 在这个基础上仍然有两个可以优化的地方: 1.对于点的枚举:当我们枚举了所有 ...
- Java接口测试之使用有道翻译API
写接口测试框架,找了有道翻译API来当测试数据 package com.httpGetTest; import java.beans.Encoder; import java.net.URLEncod ...
- XML中CDATA和#PCDATA的区别
在XML文档中, 能看到“CDATA"的地方有三处: 1)在DTD中,指定标签中某个属性的类型为字符型时,使用CDATA.因为XML解析器会去分析这段字符内容,因而里面如果需要使用>, ...
- hdu 1711 Number Sequence(kmp找子串第一次出现的位置)
题意:裸kmp 思路:kmp模板 #include<iostream> #include<stdio.h> #include<string.h> using nam ...
- hdu 1047 Integer Inquiry(大数)
题意:整数大数加法 思路:大数模板 #include<iostream> #include<stdio.h> #include<stdlib.h> #include ...
- Django中使用静态资源/文件
Django中常需要引用js,css,小图像文件,一般我们把这一类文件称为静态文件,放置在static文件夹中,接下来,对Django中配置静态文件进行下傻瓜式的步骤介绍 在工程目录下新建static ...
- weex 创建项目坑2
安装成功weex 创建项目 weex create my-project 提示 需要安装 weexpack Installing 安装失败 后来卸载weex,重新安装weex 执行下面的命令: ...
- 在JS中将指定表单内的“具有name数据的表单元素的值”封装为Get形式的字符串
//封装post时候,表单中所有具有name数据的表单元素的值,并返回“n=1&p=a” function serialize(formid) { var arr = []; var ipts ...
- iOS中判断基础字符(大小写、数字等的判断)
函数:isdigit 用法:#include 功能:判断字符c是否为数字 说明:当c为数字0-9时,返回非零值,否则返回零. 函数:islower 用法:#include 功能:判断字符c是否为小写英 ...