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 ...
随机推荐
- git 版本控制库的用法及其介绍
版本控制 说到版本控制,脑海里总会浮现大学毕业是写毕业论文的场景,你电脑上的毕业论文一定出现过这番景象! 1 2 3 4 5 6 7 8 9 10 11 毕业论文_初稿.doc 毕业论文_修改1.do ...
- c# DataTable join 两表连接
转:https://www.cnblogs.com/xuxiaona/p/4000344.html JlrInfodt和dtsource是两个datatable,通过[姓名]和[lqry]进行关联 v ...
- 【记录】利用Jquery 在 textarea 内实现文字动态换行
背景: 最近在做前端时候遇到一种情况,需要用js动态输入内容到textarea, 比如实时聊天功能,用户A每次发送信息都需要另起一行. 问题: 根据以往经验,以为用$('#textArea').htm ...
- 单实例安装elastic和启动报错解决
下载 先到官网https://www.elastic.co/cn/downloads/past-releases/elasticsearch-5-5-2下载,我安装的是5.5.2的版本,其他版本直接访 ...
- Vuex白话教程第六讲:Vuex的管理员Module(实战篇)
写在前面 这一讲是 Vuex 基础篇的最后一讲,也是最为复杂的一讲.如果按照官方来的话,对于新手可能有点难以接受,所以想了下,决定干脆多花点时间,用一个简单的例子来讲解,顺便也复习一下之前的知识点. ...
- KindEditor在eclipse里的配置方法
KindEditor介绍: kindEditor是一款国产富文本编辑器,类似fckeditor和目前比较流行的百度Ueditor.其产品官方网站为http://kindeditor.net/ Kind ...
- element 的时间快捷键
1. <div> <el-date-picker v-model="value4" type="month" :picker-options= ...
- throws/throw Exception 异常应用
throws通常用于方法的声明,当方法中发生异常的时候,却不想在方法中对异常进行处理的时候,就可以在声明方法时, 使用throws声明抛出的异常,然后再调用该方法的其他方法中对异常进行处理(如使用tr ...
- css 垂直居中、水平居中
在父元素.子元素未知的情况下居中有两种方法: 第一种方法: .partent{ display:flex; justify-content:center; align-items:center; } ...
- Kubernetes 弹性伸缩HPA功能增强Advanced Horizontal Pod Autoscaler -介绍部署篇
背景 WHAT(做什么) Advanced Horizontal Pod Autoscaler(简称:AHPA)是kubernetes中HPA的功能增强. 在兼容原生HPA功能基础上,增加预测.执行模 ...