java数据结构——二叉树(BinaryTree)
前面我们已经学习了一些线性结构的数据结构和算法,接下来我们开始学习非线性结构的内容。
二叉树
前面显示增、删、查、遍历方法,完整代码在最后面。
/**
* 为什么我们要学习树结构。
* 1、有序数组插入数据项和删除数据项太慢。
* 2、链表查找数据太慢。
* 3、在树中能非常快速的查找、插入、删除数据,结合了有序数组和链表的优点
* 4、暂时还不知道
*/
结点打包类
public class BinaryTree {
//数据项(对象什么都可以)
public long data;
//左孩子
public BinaryTree leftChiled;
//右孩子
public BinaryTree rightChiled;
public BinaryTree(int value) {
this.data = value;
}
}
public void add(int value) {
// 封装结点
BinaryTree newnode = new BinaryTree(value);
BinaryTree parent;// 引用父节点
BinaryTree current = root;// current引用根结点
if (root == null) {// 如果root为null,也就是第一次插入
root = newnode;
return;
} else {
while (true) {
parent = current;// 父节点指向指向当前节点,保存上一个结点
if (current.data > value) {
current = current.leftChiled;
if (current == null) {
parent.leftChiled = newnode;
return;
}
} else {
current = current.rightChiled;
if (current == null) {
parent.rightChiled = newnode;
return;
}
}
}
}
}
添加方法
一、删除节点是二叉树操作中最复杂的。在删除之前首先要查找要删的节点。找到节点后,这个要删除的节点可能会有三种情况需要考虑。
public boolean delete(long value) {// 删除
BinaryTree current = root;// current保存根结点
BinaryTree parent = root;// parent保存parent的父节点
boolean isLeftchild = true;
while (current.data != value) {
parent = current;
// 进行比较,比较当前值和查找值的大小
if (current.data > value) {
current = current.leftChiled;
isLeftchild = true;// true为左子树
} else {
current = current.rightChiled;
isLeftchild = false;
}
if (current == null) {
return false;
}
}
if (current.leftChiled == null && current.rightChiled == null) {// 第1种情况
if (isLeftchild) {
parent.leftChiled = null;
} else {
parent.rightChiled = null;
}
} else if (current.rightChiled == null) {// 第2种情况
if (current == root) {
root = current.leftChiled;
} else if (isLeftchild) {
parent.leftChiled = current.leftChiled;
} else {
parent.rightChiled = current.leftChiled;
}
} else if (current.leftChiled == null) {
if (current == root) {
root = current.rightChiled;
} else if (isLeftchild) {
parent.leftChiled = current.rightChiled;
} else {
parent.rightChiled = current.rightChiled;
}
} else {// 第3种情况
BinaryTree successor = getSuccessor(current);// 根结点开始,successor存放中序后继结点
if (current == root) {// 替换工作
root = successor;
} else if (isLeftchild) {// 要删除的父节点的左子节点
parent.leftChiled = successor;
} else {// 要删除的父节点的右子节点
parent.rightChiled = successor;
}
successor.leftChiled = current.leftChiled;// 中序后继结点引用删除的左边的结点
}
return true;
}
public BinaryTree getSuccessor(BinaryTree delBin) {// 找中序后继结点方法
// delBin为要删除的结点
BinaryTree successor = delBin;// successor为查找的中序后继结点
BinaryTree successorParent = delBin; // successor的父节点
BinaryTree current = delBin.rightChiled; // 当前开始遍历的结点
while (current != null) {// 这里完成elBin.rightChiled是叶子结点
successorParent = successor;// successorParent保存上一个successor的引用
successor = current;// 循环完成以后,successor保存的就是中序后继结点
current = current.leftChiled;
}
// 中序后继结点有两种情况,就是delBin.rightChiled是否为叶子结点的两种情况
if (successor != delBin.rightChiled) {// elBin.rightChiled不是叶子结点,中序后继结点是左边的
successorParent.leftChiled = successor.rightChiled;// 中序后继结点后面肯定只有右子节点
successor.rightChiled = delBin.rightChiled;// 中序后继结点的右子节点指向要删除的右边的结点
// successor.rightChiled指向要删除的rightChiled
// 交换成功
}
return successor;
}
删除方法
二、
public BinaryTree find(int value) {// 查找
// 引用当前结点,从根结点开始
BinaryTree current = root;
// 循环,只要查找值不等于当前结点的数据项
while (current.data != value) {
// 进行比较,比较当前值和查找值的大小
if (current.data > value) {
current = current.leftChiled;
} else {
current = current.rightChiled;
}
if (current == null) {
return null;
}
}
return current;
}
查找方法
遍历二叉树,有3种遍历方法。其中,中序遍历最为常用,因为可以让特定的数据排序输出,前面我们已经学习了递归方法,接下来我们也使用递归方法实现。
(1)访问根结点
(2)前序遍历左子树
(3)前序遍历右子树
public void frontOrder(BinaryTree localBin) {// 前序
if (localBin != null) {// 递归结束条件
System.out.println(localBin.data);
frontOrder(localBin.leftChiled);
frontOrder(localBin.rightChiled);
}
}
前序遍历
中序遍历。
(1)中序遍历左子树
(2)访问根结点
(3)中序遍历右子树
public void middleOrder(BinaryTree localBin) {// 前序
if (localBin != null) {// 递归结束条件
middleOrder(localBin.leftChiled);
System.out.println(localBin.data);
middleOrder(localBin.rightChiled);
}
}
中序遍历
后序遍历。
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点
public void endOrder(BinaryTree localBin) {// 前序
if (localBin != null) {// 递归结束条件
endOrder(localBin.leftChiled);
endOrder(localBin.rightChiled);
System.out.println(localBin.data);
}
}
后序遍历
前辈的头发秃光不是没有原因的,哈哈哈。
package binarytree;
public class TestTree {
// 根结点
public BinaryTree root;
public static void main(String[] args) {
TestTree tt = new TestTree();
tt.add(10);
tt.add(5);
tt.add(4);
tt.add(6);
tt.add(12);
tt.add(11);
tt.add(14);
tt.add(13);
tt.middleOrder(tt.root);
tt.delete(10);
System.out.println();
tt.middleOrder(tt.root);
}
public void frontOrder(BinaryTree localBin) {// 前序
if (localBin != null) {// 递归结束条件
System.out.print(localBin.data + " ");
frontOrder(localBin.leftChiled);
frontOrder(localBin.rightChiled);
}
}
public void middleOrder(BinaryTree localBin) {// 中序
if (localBin != null) {// 递归结束条件
middleOrder(localBin.leftChiled);
System.out.print(localBin.data + " ");
middleOrder(localBin.rightChiled);
}
}
public void endOrder(BinaryTree localBin) {// 后序
if (localBin != null) {// 递归结束条件
endOrder(localBin.leftChiled);
endOrder(localBin.rightChiled);
System.out.print(localBin.data + " ");
}
}
public void add(int value) {
// 封装结点
BinaryTree newnode = new BinaryTree(value);
BinaryTree parent;// 引用父节点
BinaryTree current = root;// current引用根结点
if (root == null) {// 如果root为null,也就是第一次插入
root = newnode;
return;
} else {
while (true) {
parent = current;// 父节点指向指向当前节点,保存上一个结点
if (current.data > value) {
current = current.leftChiled;
if (current == null) {
parent.leftChiled = newnode;
return;
}
} else {
current = current.rightChiled;
if (current == null) {
parent.rightChiled = newnode;
return;
}
}
}
}
}
public BinaryTree find(int value) {// 查找
// 引用当前结点,从根结点开始
BinaryTree current = root;
// 循环,只要查找值不等于当前结点的数据项
while (current.data != value) {
// 进行比较,比较当前值和查找值的大小
if (current.data > value) {
current = current.leftChiled;
} else {
current = current.rightChiled;
}
if (current == null) {
return null;
}
}
return current;
}
public boolean delete(long value) {// 删除
BinaryTree current = root;// current保存根结点
BinaryTree parent = root;// parent保存parent的父节点
boolean isLeftchild = true;
while (current.data != value) {
parent = current;
// 进行比较,比较当前值和查找值的大小
if (current.data > value) {
current = current.leftChiled;
isLeftchild = true;// true为左子树
} else {
current = current.rightChiled;
isLeftchild = false;
}
if (current == null) {
return false;
}
}
if (current.leftChiled == null && current.rightChiled == null) {// 第1种情况
if (isLeftchild) {
parent.leftChiled = null;
} else {
parent.rightChiled = null;
}
} else if (current.rightChiled == null) {// 第2种情况
if (current == root) {
root = current.leftChiled;
} else if (isLeftchild) {
parent.leftChiled = current.leftChiled;
} else {
parent.rightChiled = current.leftChiled;
}
} else if (current.leftChiled == null) {
if (current == root) {
root = current.rightChiled;
} else if (isLeftchild) {
parent.leftChiled = current.rightChiled;
} else {
parent.rightChiled = current.rightChiled;
}
} else {// 第3种情况
BinaryTree successor = getSuccessor(current);// 根结点开始,successor存放中序后继结点
if (current == root) {// 替换工作
root = successor;
} else if (isLeftchild) {// 要删除的父节点的左子节点
parent.leftChiled = successor;
} else {// 要删除的父节点的右子节点
parent.rightChiled = successor;
}
successor.leftChiled = current.leftChiled;// 中序后继结点引用删除的左边的结点
}
return true;
}
public BinaryTree getSuccessor(BinaryTree delBin) {// 找中序后继结点方法
// delBin为要删除的结点
BinaryTree successor = delBin;// successor为查找的中序后继结点
BinaryTree successorParent = delBin; // successor的父节点
BinaryTree current = delBin.rightChiled; // 当前开始遍历的结点
while (current != null) {// 这里完成elBin.rightChiled是叶子结点
successorParent = successor;// successorParent保存上一个successor的引用
successor = current;// 循环完成以后,successor保存的就是中序后继结点
current = current.leftChiled;
}
// 中序后继结点有两种情况,就是delBin.rightChiled是否为叶子结点的两种情况
if (successor != delBin.rightChiled) {// elBin.rightChiled不是叶子结点,中序后继结点是左边的
successorParent.leftChiled = successor.rightChiled;// 中序后继结点后面肯定只有右子节点
successor.rightChiled = delBin.rightChiled;// 中序后继结点的右子节点指向要删除的右边的结点
// successor.rightChiled指向要删除的rightChiled
// 交换成功
}
return successor;
}
}
complete code
java数据结构——二叉树(BinaryTree)的更多相关文章
- (2)Java数据结构--二叉树 -和排序算法实现
=== 注释:此人博客对很多个数据结构类都有讲解-并加以实例 Java API —— ArrayList类 & Vector类 & LinkList类Java API —— BigDe ...
- Java数据结构——二叉树
前序遍历——根 左 右 中序遍历——左 根 右 后序遍历——左 右 根 //================================================= // File Name ...
- Java数据结构——二叉树 增加、删除、查询
//二叉树系统 public class BinarySystem { public static void main(String[] args) { BinaryDomain root = nul ...
- Java数据结构——二叉树的遍历(汇总)
二叉树的遍历分为深度优先遍历(DFS)和广度优先遍历(BFS) DFS遍历主要有: 前序遍历 中序遍历 后序遍历 一.递归实现DFSNode.java: public class Node { pri ...
- java数据结构(二叉树)
Node节点: public class Node { public long data; public String sData; public Node leftChild; public Nod ...
- Java数据结构——二叉树节点的增删改查、获取深度及最大最小值
一.查找最大值 // 查找最大值 public static Node maxNode() { Node node = root; Node maxNode = node; while (node ! ...
- 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.图形或者网状结构 接下来的 ...
随机推荐
- MySQL主从配置图文详解
#环境配置#master IP:192.168.46.137 slave IP:192.168.46.138 database:v1 1.在两台机器,分别安装mysql数据库,分别添加远程连接权限 2 ...
- HTML+JavaScript自己动手做日历
当我们需要在页面中显示某月的事项,或是选择某一段日期时,常常要使用到日历组件.这一组件同样有着许多现成的类库,然而亲自动手开发一个日历,从中了解其实现原理也是非常必要的.在本例中我们就将制作一款非常经 ...
- CSAPP - Ch 1 - 计算机系统漫游
目录 0 序言及摘要 1 信息就是位+上下文 2 程序被其他程序翻译成不同的格式 3 了解编译系统如何工作是大有益处的 0 序言及摘要 (1) 序言: CS:APP -- Computer Syste ...
- C#开发BIMFACE系列14 服务端API之批量获取转换状态详情
系列目录 [已更新最新开发文章,点击查看详细] 上一篇<C#开发BIMFACE系列13 服务端API之获取转换状态>中介绍了根据文件ID查询单个文件的转换状态. 本文介绍批量获取转 ...
- HDU 6364 Ringland
Ringland 题意: 在一个环上有n个男生, n个女生, 现在要求每一个男生与女生配对, 求总代价最小. 题解: 如果2个男生到女生的路交叉了, 那么我们交换这2个男生的路, 总代价是一定会变得小 ...
- hdu 3709 Balanced Number(数位dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题意:给定区间[a,b],求区间内平衡数的个数.所谓平衡数即有一位做平衡点,左右两边数字的力矩相 ...
- poj 2406 Power Strings(kmp next的应用)
题目链接:http://poj.org/problem?id=2406 题意:就是求一个字符串最多有几个相同的小字符串组成. 题解:直接求一下next然后找到长度,长度就是len-1-next[len ...
- 【Offer】[8] 【中序遍历的下一个结点】
题目描述 思路分析 Java代码 代码链接 题目描述 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. ...
- 【LeetCode】DFS 总结
DFS(深度优先搜索) 常用来解决可达性的问题. 两个要点: 栈:用栈来保存当前节点信息,当遍历新节点返回时能够继续遍历当前节点.可以使用递归栈. 标记:和 BFS 一样同样需要对已经遍历过的节点进行 ...
- spring cloud config使用mysql存储配置文件
spring cloud config使用mysql存储配置文件 1.结构图 2.pom.xml: <?xml version="1.0" encoding="UT ...