Java 二叉树遍历相关操作
BST二叉搜索树节点定义:
/**
* BST树的节点类型
* @param <T>
*/
class BSTNode<T extends Comparable<T>>{
private T data; // 数据域
private BSTNode<T> left; // 左孩子域
private BSTNode<T> right; // 右孩子域 public BSTNode(T data, BSTNode<T> left, BSTNode<T> right) {
this.data = data;
this.left = left;
this.right = right;
} public T getData() {
return data;
} public void setData(T data) {
this.data = data;
} public BSTNode<T> getLeft() {
return left;
} public void setLeft(BSTNode<T> left) {
this.left = left;
} public BSTNode<T> getRight() {
return right;
} public void setRight(BSTNode<T> right) {
this.right = right;
}
}
BST的实现:
/**
* BST树的实现
* @param <T>
*/
class BST<T extends Comparable<T>> {
public BSTNode<T> root; // 指向根节点 /**
* BST树的初始化
*/
public BST() {
this.root = null;
}
}
BST的插入操作:
/**
* BST树的非递归插入操作
*
* @param data
*/
public void non_insert(T data) {
// 1.判断如果root是null,如果root是null,直接生成根节点,让root指向,结束
if (root == null) {
this.root = new BSTNode<>(data, null, null);
return;
}
// 2.如果root不为空,从根节点开始搜索一个合适的位置,放新节点
BSTNode<T> cur = this.root;
BSTNode<T> parent = null; // this.root
while (cur != null) {
if (cur.getData().compareTo(data) > 0) {
parent = cur;
cur = cur.getLeft();
} else if (cur.getData().compareTo(data) < 0) {
parent = cur;
cur = cur.getRight();
} else {
return;
}
}
// 3.生成新节点,把节点的地址,写入父节点相应的地址域
if (parent.getData().compareTo(data) > 0) {
parent.setLeft(new BSTNode<T>(data, null, null));
} else {
parent.setRight(new BSTNode<T>(data, null, null));
}
}
/**
* 递归插入
*
* @param data
*/
public void insert(T data) {
this.root= insert(data, root);
} private BSTNode<T> insert(T data, BSTNode<T> root) {
if (root == null) {
return new BSTNode<T>(data, null, null);
}
if (root.getData().compareTo(data) > 0) {
root.setLeft(insert(data,root.getLeft()));
} else if (root.getData().compareTo(data) < 0) {
root.setRight(insert(data, root.getRight()));
}else {
;
}
return root;
}
删除操作:
/**
* 非递归实现BST树的删除操作
*
* @param data
*/
public void non_remove(T data) {
if (this.root == null) {
return;
}
// 1. 先搜索BST树,找到待删除的节点
BSTNode<T> cur = this.root;
BSTNode<T> parent = null;
while (cur != null) {
if (cur.getData().compareTo(data) > 0) {
parent = cur;
cur = cur.getLeft();
} else if (cur.getData().compareTo(data) < 0) {
parent = cur;
cur = cur.getRight();
} else {
break;
}
}
if (cur == null) {// 表示BST树中没有值为data的节点
return;
}
// 2. 判断删除节点是否有两个孩子,如果有,用前驱的值代替,直接删除前驱
if (cur.getLeft() != null && cur.getRight() != null) {
BSTNode<T> old = cur;
parent = cur;
cur = cur.getLeft();
while (cur != null) {
parent = cur;
cur = cur.getRight();
}
old.setData(cur.getData());// 前驱节点的值代替待删节点的值
}
// 3. 删除有一个孩子的节点,或者没有孩子的节点(看作有一个孩子,孩子是null)
BSTNode<T> child = cur.getLeft();
if (child == null) {
child = cur.getRight();
}
if (parent == null) {// 删除的就是根节点
this.root = child;
} else {
if (parent.getLeft() == cur) {
parent.setLeft(child);
} else {
parent.setRight(child);
}
}
}
/**
* 递归实现删除值val的节点
*
* @param val
*/
public void remove(T val) {
this.root = remove(val, root);
}
private BSTNode<T> remove(T val, BSTNode<T> root) {
if(root==null){
return null;
}
if(root.getData().compareTo(val)>0){
root.setLeft(remove(val,root.getLeft()));
}else if(root.getData().compareTo(val)>0){
root.setRight(remove(val,root.getRight()));
}else {
if(root.getLeft()!=null&&root.getRight()!=null){
BSTNode<T> old=root;
root=root.getLeft();
while (root.getRight()!=null){
root=root.getRight();
}
old.setData(root.getData());
old.setLeft(remove(root.getData(),root.getLeft()));
}else if(root.getLeft()!=null){
return root.getLeft();
}else if(root.getRight()!=null){
return root.getRight();
}else {
return null;
}
}
return root;
}
判断有无data值:
/**
* 判断有无data值
*
* @param data
* @return
*/
public boolean non_query(T data) {
BSTNode<T> cur = root;
if (root == null) {
return false;
}
while (cur != null) {
if (cur.getData().compareTo(data) > 0) {
cur = cur.getLeft();
} else if (cur.getData().compareTo(data) < 0) {
cur = cur.getRight();
} else {
return true;
}
}
return false;
}
/**
* 递归实现判断有无data
* @param data
* @return
*/
public boolean query(T data){
return query(data,root);
} private boolean query(T data, BSTNode<T> root) {
if(root==null){
return false;
}
if(root.getData().compareTo(data)>0){
return query(data,root.getLeft());
}
if(root.getData().compareTo(data)<0){
return query(data,root.getRight());
}
else {
return true;
}
}
前序遍历:
/**
* 前序遍历BST树
*/
public void preOrder() {
System.out.print("前序遍历");
preOrder(this.root);
} private void preOrder(BSTNode<T> root) {
if (root != null) {
System.out.print(root.getData() + " ");
preOrder(root.getLeft());
preOrder(root.getRight());
}
}
中序遍历:
/**
* 中序遍历
*/
public void inOrder() {
System.out.println();
System.out.print("中序遍历");
inOrder(this.root);
System.out.println();
} private void inOrder(BSTNode<T> root) {
if (root != null) {
inOrder(root.getLeft());
System.out.print(root.getData() + " ");
inOrder(root.getRight());
}
}
后序遍历:
/**
* 后序遍历
*/
public void postOrder() {
System.out.println("后序遍历");
postOrder(this.root);
System.out.println();
} private void postOrder(BSTNode<T> root) {
if (root != null) {
postOrder(root.getLeft());
postOrder(root.getRight());
System.out.print(root.getData() + " ");
}
}
层序遍历:
/**
* BST的层序遍历
*/
public void levelOrder() {
System.out.println("递归层序遍历");
for (int i = 0; i < this.level(); i++) {
levelOrder(this.root, i);
}
} /**
* 层序遍历的递归实现
*
* @param root
* @param i
*/
private void levelOrder(BSTNode<T> root, int i) {
if (root != null) {
if (i == 0) {
System.out.print(root.getData() + " ");
return;
}
levelOrder(root.getLeft(), i - 1);
levelOrder(root.getRight(), i - 1);
}
}
返回BST节点的个数:
/**
* 返回BST树的所有节点个数的API
*
* @return
*/
public int number() {
return number(root);
} /**
* 以root为根节点计算BST树的节点个数
*
* @param root
* @return
*/
private int number(BSTNode<T> root) {
if (root == null) {
return 0;
} else {
return number(root.getLeft()) + number(root.getRight()) + 1;
}
}
返回BST的高度:
/**
* 返回BST树的高度的API
*
* @return
*/
public int level() {
return level(this.root);
} private int level(BSTNode<T> root) {
if (root == null) {
return 0;
} else {
int left = level(root.getLeft());
int right = level(root.getRight());
return left > right ? left + 1 : right + 1;
}
}
BST的镜像反转:
/**
* 求BST树的镜像翻转API
*/
public void mirror() {
mirror(this.root);
} /**
* 求BST镜像翻转的递归实现
*
* @param root
*/
private void mirror(BSTNode<T> root) {
if (root == null) {
return;
}
BSTNode<T> tmp = root.getLeft();
root.setLeft(root.getRight());
root.setRight(tmp); mirror(root.getLeft());
mirror(root.getRight());
}
返回BST树第K小的元素:
/**
* 返回中序遍历倒数第k个节点的值
*
* @param k
* @return
*/
public T getOrderValue(int k){
getOrderValue(this.root, k);
return cur;
}
private int i=0;
private T getOrderValue(BSTNode<T> root, int k) {
if(root == null){
return null;
} T val = getOrderValue(root.getLeft(), k);
if(val != null){
return val;
} if(i++ == k)
{
return root.getData();
} return getOrderValue(root.getRight(), k);
}
根据前序和中序数组,重建搜索二叉树:
/**
* 根据参数传入的pre和in数组,重建二叉树
* @param pre
* @param in
*/
public void rebuild(T[]pre,T[]in){
this.root=rebuild(pre,0,pre.length-1,in,0,in.length-1);
} private BSTNode<T> rebuild(T[] pre, int i, int j, T[] in, int m, int n) {
if(i>j||m>n){
return null;
}
BSTNode<T> node=new BSTNode<T>(pre[i],null,null);
for (int k=m;k<=n;k++){
if(pre[i].compareTo(in[k])==0){
node.setLeft(rebuild(pre,i+1,i+k-m,
in,m,k-1));
node.setRight(rebuild(pre,i+(k-m)+1,j,
in,k+1,n));
break;
}
}
return node;
}
Java 二叉树遍历相关操作的更多相关文章
- 二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)
将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: typedef struct TreeNode{ int data; struct TreeNode *le ...
- java文件夹相关操作 演示样例代码
java文件夹相关操作 演示样例代码 package org.rui.io; import java.io.File; import java.io.FilenameFilter; import ja ...
- java 二叉树遍历
package com.lever; import java.util.LinkedList;import java.util.Queue; /** * 二叉树遍历 * @author lckxxy ...
- java实现二叉树的相关操作
import java.util.ArrayDeque; import java.util.Queue; public class CreateTree { /** * @param args */ ...
- java 发送邮件 email相关操作代码测试,生成复杂格式邮件,发送邮件相关操作
项目源码下载:http://download.csdn.net/detail/liangrui1988/6720047 效果图: 相关代码: test1 package com.mail; impor ...
- java虚拟机栈 相关操作
针对JVM虚拟栈 和栈帧的操作 虚拟机栈: 栈元素是栈帧.方法调用,栈帧入栈,反之出栈. 栈帧:一个方法的运行空间. 1.局部变量表:方法定义的局部变量.方法的参数存在该表. 实例方法中有个隐含参数“ ...
- Java 二叉树遍历右视图-LeetCode199
题目如下: 题目给出的例子不太好,容易让人误解成不断顺着右节点访问就好了,但是题目意思并不是这样. 换成通俗的意思:按层遍历二叉树,输出每层的最右端结点. 这就明白时一道二叉树层序遍历的问题,用一个队 ...
- java二叉树遍历——深度优先(DFS)与广度优先(BFS) 递归版与非递归版
介绍 深度优先遍历:从根节点出发,沿着左子树方向进行纵向遍历,直到找到叶子节点为止.然后回溯到前一个节点,进行右子树节点的遍历,直到遍历完所有可达节点为止. 广度优先遍历:从根节点出发,在横向遍历二叉 ...
- Java中JSONObject相关操作
maven项目pom配置: <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>js ...
随机推荐
- LeetCode Array Easy 27. Remove Element 解题
Given an array nums and a value val, remove all instances of that value in-place and return the new ...
- 【CSS】选择器优先级
CSS的选择器优先级的权重 在 Selectors Level 3 规范中,一个选择器的优先级(权重)由依次串联的a.b.c三个标记来计算 a: ID选择器 如#header b: class选择器如 ...
- mybatis xml中大于号小于号的代替
第一种写法(1): 原符号 < <= > >= & ' "替换符号 < <= > >= & ' " ...
- RabbitMQ:从零开始
目录 一.介绍 二.安装 三.基本配置 四.Java Demo 五.基础API使用 六.ACK机制 七.消息的持久化 八.消息的公平分发 九.消息的优先级 十.消息的路由分发 十一.Spring集成 ...
- daragrid 简单认识
@{ ViewBag.Title = "EasyUI"; Layout = null; } <script src="~/jquery-easyui-1.5.5.2 ...
- linux IPC的信号量
信号量相关函数原型 获得一个信号量ID #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h&g ...
- BZOJ 3238: [Ahoi2013]差异((单调栈+后缀数组)/(后缀树))
[传送门[(https://www.lydsy.com/JudgeOnline/problem.php?id=3238) 解题思路 首先原式可以把\(len\)那部分直接算出来,然后通过后缀数组求\( ...
- docker包含哪些内容(1)
包含哪些内容? 如下图,三大块: 下面分别介绍各部分包含的内容. 启程 “启程”会介绍容器的生态系统,让大家先从整体上了解容器都包含那些技术,各种技术之间的相互关系是什么,然后再来看我们的教程都会涉及 ...
- 获取客户端IP地址-----以及--------线上开启redis扩展
/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ function get_cl ...
- 在Python的列表中利用remove()方法删除元素的教程
在Python的列表中利用remove()方法删除元素的教程 这篇文章主要介绍了在Python的列表中利用remove()方法删除元素的教程,是Python入门中的基础知识,注意其和pop()方法的区 ...