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) 一.树的遍历 二叉树遍历分为:前序遍 ...
随机推荐
- 模拟等待事件:db file sequential read
相关知识: db file sequential read 单块读 optimizer_index_cost_adj 这个初始化参数代表一个百分比,取值范围在1到10000之间.该参数表示索引扫描和 ...
- js的单线程与异步
一. js 是单线程和异步 1. js 是单线程的,js 的宿主环境(浏览器)是多线程的,实现异步. 2.js是单线程语言,浏览器值分配给js一个主线程,用来执行任务(函数),但一次只能执行一个任务, ...
- hdu 1040 As Easy As A+B(排序)
题意:裸排序 思路:排序 #include<iostream> #include<stdio.h> #include<algorithm> using namesp ...
- blog.codedream.ren
博客将转到 CodeDream ,新的链接是 http://blog.codedream.ren
- codeforces 701D D. As Fast As Possible(数学)
题目链接: D. As Fast As Possible time limit per test 1 second memory limit per test 256 megabytes input ...
- [IOI 2018] Werewolf
[题目链接] https://www.luogu.org/problemnew/show/P4899 [算法] 建出原图的最小/最大生成树的kruskal重构树然后二维数点 时间复杂度 ...
- flask logger
Flask uses standard Python logging. All Flask-related messages are logged under the 'flask' logger n ...
- Linux中进程控制块PCB-------task_struct结构体结构
Linux中task_struct用来控制管理进程,结构如下: struct task_struct { //说明了该进程是否可以执行,还是可中断等信息 volatile long state; // ...
- DAG上的DP
引例:NYOJ16 矩形嵌套 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可 ...
- Module:template
ylbtech-Module: 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylbtech. ...