数据结构与算法(Java)之二叉树
Posted 达少Rising
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法(Java)之二叉树相关的知识,希望对你有一定的参考价值。
二叉树
package com.weeks.tree;
/**
* @author 达少
* @version 1.0
*
* 实现二叉树数据结构
*/
public class BinaryTreeDemo {
public static void main(String[] args) {
//定义二叉树
BinaryTree binaryTree = new BinaryTree();
//定义二叉树的节点对象
HeroNode node1 = new HeroNode(1, "宋江");
HeroNode node2 = new HeroNode(2, "吴用");
HeroNode node3 = new HeroNode(3, "卢俊义");
HeroNode node4 = new HeroNode(4, "林冲");
HeroNode node5 = new HeroNode(5, "关胜");
//这里先使用手动创建二叉树,以后可以使用递归方式创建
binaryTree.setRoot(node1);
node1.setLeft(node2);
node1.setRight(node3);
node3.setRight(node4);
node3.setLeft(node5);
//测试前序遍历
// System.out.println("前序遍历");
// binaryTree.preOrder();//1,2,3,5,4
//测试中序遍历
// System.out.println("中序遍历");
// binaryTree.infixOrder();//2,1,5,3,4
//测试后续遍历
// System.out.println("后续遍历");
// binaryTree.postOrder();//2,5,4,3,1
//测试前序查找
// HeroNode resNode = binaryTree.preOrderSearch(5);
// HeroNode resNode = binaryTree.infixOrderSearch(5);
// HeroNode resNode = binaryTree.postOrderSearch(5);
// if(resNode != null){
// System.out.printf("找到了结点id = %d, name = %s\\n", resNode.getNo(), resNode.getName());
// }else{
// System.out.println("没有找到要查找的结点!!!");
// }
System.out.println("删除前的二叉树(前序遍历)");
binaryTree.preOrder();
//删除no=5的结点
binaryTree.delNode(5);
System.out.println("删除后的二叉树(前序遍历)");
binaryTree.preOrder();
}
}
//定义二叉树类
class BinaryTree{
private HeroNode root;//根结点
public HeroNode getRoot() {
return root;
}
public void setRoot(HeroNode root) {
this.root = root;
}
//前序遍历
public void preOrder(){
if(root == null){
return;
}
root.preOrder();
}
//中序遍历
public void infixOrder(){
if(root == null){
return;
}
root.infixOrder();
}
//后序遍历
public void postOrder(){
if(root == null){
return;
}
root.postOrder();
}
//前序查找
public HeroNode preOrderSearch(int no){
if(root == null){
return null;
}
return root.preOrderSearch(no);
}
//中序查找
public HeroNode infixOrderSearch(int no){
if(root == null){
return null;
}
return root.infixOrderSearch(no);
}
//后序查找
public HeroNode postOrderSearch(int no){
if(root == null){
return null;
}
return root.postOrderSearch(no);
}
//删除结点
public void delNode(int no){
//判断二叉树是否为空
if(root == null){
return;
}
//判断根节点是否符合删除条件,符合则将整棵树置空后返回
if(root.getNo() == no){
root = null;
return;
}else{//否则执行HeroNode中的delNode操作
root.delNode(no);
}
}
}
//定义树的结点对象类
class HeroNode{
private int no;
private String name;
private HeroNode left;
private HeroNode right;
public HeroNode(int no, String name){
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = right;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\\'' +
'}';
}
//前序遍历
public void preOrder(){
//先输出当前结点
System.out.println(this);
//递归遍历左子树
if(this.left != null){
this.left.preOrder();
}
//递归遍历右子树
if(this.right != null){
this.right.preOrder();
}
}
//中序遍历
public void infixOrder(){
//递归遍历左子树
if(this.left != null){
this.left.infixOrder();
}
//输出当前结点
System.out.println(this);
//递归遍历右子树
if(this.right != null){
this.right.infixOrder();
}
}
//后序遍历
public void postOrder(){
//递归遍历左子树
if(this.left != null){
this.left.postOrder();
}
//递归遍历右子树
if(this.right != null){
this.right.postOrder();
}
//输出当前结点
System.out.println(this);
}
//前序查找
/**
*
* @param no 需要查找的编号
* @return 找到就返回该结点,否则返回null
*/
public HeroNode preOrderSearch(int no){
//判断该结点是否为查找的结点
if(this.no == no){
return this;//找到就返回该结点
}
HeroNode resNode = null;
//如果不是当前结点就递归左子树查找
if(this.left != null){
resNode = this.left.preOrderSearch(no);
}
//如果在左子树找到就返回
if(resNode != null){
return resNode;
}
//在左子树没有找到,那么向右子树查找
if(this.right != null){
resNode = this.right.preOrderSearch(no);
}
//无论找没找到最后返回
return resNode;//返回不为空就是找打了,返回空就是没有找到
}
//中序查找
public HeroNode infixOrderSearch(int no){
HeroNode resNode = null;
//向左子树递归查找
if(this.left != null){
resNode = this.left.infixOrderSearch(no);
}
//如果在左子树找到则返回
if(resNode != null){
return resNode;
}
//判断该节点是否为查找的结点
if(this.no == no){
return this;
}
//向左右子树遍历查找
if(this.right != null){
resNode = this.right.infixOrderSearch(no);
}
return resNode;
}
//后序查找
public HeroNode postOrderSearch(int no){
HeroNode resNode = null;
//向左子树递归查找
if(this.left != null){
resNode = this.left.postOrderSearch(no);
}
//如果在左子树找到则返回
if(resNode != null){
return resNode;
}
//向左右子树遍历查找
if (this.right != null){
resNode = this.right.postOrderSearch(no);
}
//判断该节点是否为查找的结点
if(this.no == no){
return this;
}
return resNode;
}
//删除结点
/**
* 约定:
* 如果删除的是叶子结点,则直接删除
* 如果不是也只结点直接删除以该节点为父节点的子树
*/
public void delNode(int no){
/**
* 1.因为要现在创建的二叉树是单向的,要删除只能找到父节点分别判断左右结点是否符合
* 删除的条件,所以首先判断左子树是否有符合删除的条件的结点,递归实现
* 2.接下来是递归判断右子树中是否有符合删除条件的结点
*/
//判断该节点是否有左子树并判断左子树是否符合删除条件
if(this.left != null && this.left.no == no){
//如果左子树符合删除条件,将左子树置空,并返回
this.left = null;
return;
}
//判断该节点是否有右子树并判断右子树是否符合删除条件
if(this.right != null && this.right.no == no){
//如果右子树符合删除条件,将右子树置空,并返回
this.right = null;
return;
}
//递归判断左子树
if(this.left != null){
this.left.delNode(no);
}
//递归判断右子树
if(this.right != null){
this.right.delNode(no);
}
}
}
顺序存储二叉树
package com.weeks.tree;
import java.util.ArrayList;
/**
* @author 达少
* @version 1.0
*
* 顺序存储二叉树
*/
public class ArrayBinaryTreeDemo {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7};
ArrayBinaryTree arrayBinaryTree = new ArrayBinaryTree(arr);
// arrayBinaryTree.preOrder();
// arrayBinaryTree.infixOrder();
arrayBinaryTree.postOrder();
}
}
//顺序存储二叉树,就是使用数组存储二叉树,并保留前中后序遍历的特点
class ArrayBinaryTree{
private int[] arr;
public ArrayBinaryTree(int[] arr){
this.arr = arr;
}
//前序遍历
/**
*
* @param index 从数组的index下标开始遍历
*/
public void preOrder(int index){
//判断数组是否为空,为空则返回
if(arr == null){
return;
}
//输出当前结点的值
System.out.println(arr[index]);
//递归遍历左子树,在数组中左子树的下标是(2 * index + 1)
if((2 * index + 1) < arr.length){//要判断下标是否越界数组
preOrder(2 * index + 1);
}
//递归遍历左子树,在数组中左子树的下标是(2 * index + 2)
if((2 * index + 2) < arr.length){
preOrder(2 * index + 2);
}
}
//我们一般都是从根节点开始遍历,所以一般index = 0
//重载preOrder函数方便调用,不用传入参数
public void preOrder(){
preOrder(0);
}
//仿照前序遍历,写出中序遍历
public void infixOrder(int index){
if(arr == null){
return;
}
if((2 * index + 1) < arr.length){
infixOrder(2 * index + 1);
}
System.out.println(arr[index]);
if((2 * index + 2) < arr.length){
infixOrder(2 * index + 2);
}
}
public void infixOrder(){
infixOrder(0);
}
//后序遍历
public void postOrder(int index){
if(arr == null){
return;
}
if((2 * index + 1) < arr.length){
postOrder(2 * index + 1);
}
if((2 * index + 2) < arr.length){
postOrder(2 * index + 2);
}
System.out.println(arr[index]);
}
public void postOrder(){
postOrder(0);
}
}
线索二叉树
package com.weeks.tree.threadedbinarytree;
/**
* @author 达少
* @version 1.0
* 线索化二叉树
*/
public class ThreadedBinaryTreeDemo {
public static void main(String[] args) {
HeroNode node1 = new HeroNode(1, "tom");
HeroNode node2 = new HeroNode(3, "jack");
HeroNode node3 = new HeroNode(6, "smith");
HeroNode node4 = new HeroNode(8, "milan");
HeroNode node5 = new HeroNode(10, "adair");
HeroNode node6 = new 以上是关于数据结构与算法(Java)之二叉树的主要内容,如果未能解决你的问题,请参考以下文章