Java–二叉树–链式存储
篇1:Java–顺序表:https://blog.csdn.net/qq_42701294/article/details/103756662
篇2:Java–单链表:https://blog.csdn.net/qq_42701294/article/details/103756678
方法接口
package pers.xu.ds2.btree;
/**二叉树接口
* 方便使用不同的存储结构实现,比如顺序结构,链式结构
* @author a_apple
* @create 2019-11-15 17:01
*/
public interface BinaryTree {
/**
* 是否空树
*/
public boolean isEmpty();
/**
* 树节点数量
*/
public int size();
/**
* 获取树的高度
*/
public int getHeight();
/**
* 查询指定值的节点
*/
public Node findKey(int value);
/**
* 前序遍历
*/
public void preOrderTraverse();
/**
* 中序遍历
*/
public void inOrderTraverse();
/**
* 后序遍历递归操作
*/
public void postOrderTraverse();
/**
* 后序遍历递归操作
* @param node 树根节点
*/
public void postOrderTraverse(Node node);
/**
* 中序遍历非递归操作
* 1)对于任意节点current,若该节点不为空则将该节点压栈,并将左子树节点置为current,重复此操作,直到
* 2)若左子树为空,栈顶节点出栈,访问节点后将该节点的右子树置为current
* 3)重复1、2步操作,直到current为空且栈内节点为空。
*/
public void inOrderByStack();
/**
* 前序遍历非递归操作
* 1)对于任意节点current,若该节点不为空则访问该节点后再将节点压栈,并将左子树节点置为current,重
* 2)若左子树为空,栈顶节点出栈,将该节点的右子树置为current
* 3)重复1、2步操作,直到current为空且栈内节点为空。
*/
public void preOrderByStack();
/**
* 后序遍历非递归操作
* 1)对于任意节点current,若该节点不为空则访问该节点后再将节点压栈,并将左子树节点置为current,重复
* 2)若左子树为空,取栈顶节点的右子树,如果右子树为空或右子树刚访问过,则访问该节点,并将preNode置为该干
* 3)重复1、2步操作,直到current为空且栈内节点为空。
*/
public void postOrderByStack();
/**
* 借助队列实现层次遍历
*/
public void levelOrderByQueue();
}
树节点
package pers.xu.ds2.btree;
/**二叉树节点
* @author a_apple
* @create 2019-11-15 16:53
*/
public class Node {
Object value;
Node left;
Node right;
public Node(Object value, Node left, Node right) {
this.value = value;
this.left = left;
this.right = right;
}
@Override
public String toString() {
return "Node{" +
"data=" + value +
", left=" + left +
", right=" + right +
'}';
}
}
二叉树类
package pers.xu.ds2.btree;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
/**
* @author a_apple
* @create 2019-11-15 17:15
*/
public class LinkedBinaryTree implements BinaryTree {
private Node root;
public LinkedBinaryTree(Node root) {
this.root = root;
}
@Override
public boolean isEmpty() {
return root == null;
}
@Override
public int size() {
System.out.print("节点个数:");
return this.size(root);
}
private int size(Node node){
if(node == null){
return 0;
}else {
//左子树高度
int lh = this.size(node.left);
//右子树高度
int rh = this.size(node.right);
//1 : 代表的是当前节点node
return lh+rh+1;
}
}
@Override
public int getHeight() {
System.out.print("高度:");
return this.getHeight(root);
}
private int getHeight(Node node) {
if(node == null){
return 0;
}else {
//左子树高度
int lh = getHeight(node.left);
//右子树高度
int rh = getHeight(node.right);
return lh>rh?lh+1:rh+1;
}
}
@Override
public Node findKey(int value) {
return this.findKey(value,root);
}
private Node findKey(Object value,Node root){
if(root == null){
return null;
}else if(root.value == value){
return root;
}else {
Node node1 = this.findKey(value,root.left);
Node node2 = this.findKey(value,root.right);
if(node1 != null && node1.value == value){
return node1;
}else if(node2 != null && node2.value == value){
return node2;
}else {
return null;
}
}
}
@Override
public void preOrderTraverse() {
System.out.println("前序遍历:");
preOrderTraverse(root);
System.out.println();
}
private void preOrderTraverse(Node node) {
if(node != null){
//先输出根节点
System.out.print(node.value+" ");
//然后递归左子树
preOrderTraverse(node.left);
//递归右子树
preOrderTraverse(node.right);
}
}
@Override
public void inOrderTraverse() {
System.out.println("中序遍历:");
inOrderTraverse(root);
System.out.println();
}
private void inOrderTraverse(Node node) {
if(node != null){
//遍历左
inOrderTraverse(node.left);
//输出根
System.out.print(node.value+" ");
//右子树
inOrderTraverse(node.right);
}
}
@Override
public void postOrderTraverse() {
System.out.println("后序遍历:");
postOrderTraverse(root);
System.out.println();
}
@Override
public void postOrderTraverse(Node node) {
if(node != null){
//遍历左
postOrderTraverse(node.left);
//遍历右
postOrderTraverse(node.right);
//输出根
System.out.print(node.value+" ");
}
}
@Override
public void inOrderByStack() {
System.out.println("非递归中序遍历:");
//创建栈
Deque<Node> stack = new LinkedList<>();
Node current = root;
while (current != null || !stack.isEmpty()){
while (current != null){
stack.push(current);
current = current.left;
}
if(!stack.isEmpty()){
current = stack.pop();
System.out.print(current.value+" ");
current = current.right;
}
}
System.out.println();
}
@Override
public void preOrderByStack() {
System.out.println("非递归前序遍历:");
this.preOrderByStack(root);
System.out.println();
}
private void preOrderByStack(Node node){
Deque<Node> stack = new LinkedList<>();
Node p = node;
while(!stack.isEmpty() || p != null){
if(p != null){
stack.push(p);
System.out.print(p.value+" ");
p = p.left;
}else {
p = stack.pop();
p = p.right;
}
}
}
@Override
public void postOrderByStack() {
System.out.println("非递归后序遍历:");
this.postOrderByStack(root);
System.out.println();
}
/**
* 双栈法
* @param node
*/
private void postOrderByStack(Node node) {
Deque<Node> s = new LinkedList<>(), s2 = new LinkedList<>();
Node p;
s.push(node);
while (!s.isEmpty()) {
p = s.pop();
s2.push(p);
if (p.left != null) {
//这里是先左再右 (非递归前序是先右再左)
s.push(p.left);
}
if (p.right != null) {
s.push(p.right);
}
}
while (!s2.isEmpty()) {
System.out.print(s2.pop().value + " ");
}
}
@Override
public void levelOrderByQueue() {
System.out.println("层次遍历:");
if(root == null) {
return;
}
Queue<Node> queue = new LinkedList<>();
//根节点入队---第一层
queue.add(root);
//对整个队列判空 -->直到最后一层节点出队
while (queue.size() != 0){
//按层次出队,输出 len:每层元素的个数
int len = queue.size();
//一层层出队,一层层进队
for (int i = 0; i < len; i++) {
Node temp = queue.poll();
assert temp != null;
System.out.print(temp.value+" ");
//父节点出队后,再将孩子添加到队列里(构成下一层节点)
if(temp.left != null){
queue.add(temp.left);
}
if(temp.right != null){
queue.add(temp.right);
}
}
System.out.print(" ");
}
System.out.println();
}
}
测试类
package pers.xu.ds2.btree;
/**
* @author a_apple
* @create 2019-11-15 17:16
*/
public class Test {
public static void main(String[] args) {
//前序创建:根-左-右 1 4 5 2 3 6 7
//1.创建二叉树
Node node7 = new Node(7,null,null);
Node node3 = new Node(3,null,null);
Node node6 = new Node(6,null,node7);
Node node2 = new Node(2,node3,node6);
Node node5 = new Node(5,null,null);
Node node4 = new Node(4,null,node5);
Node node1 = new Node(1,node4,node2);
LinkedBinaryTree btree = new LinkedBinaryTree(node1);
//2.判断树空
boolean empty = btree.isEmpty();
System.out.println("isEmpty:"+empty);
//3.前序 1452367
btree.preOrderTraverse();
//4.中序 4513267
btree.inOrderTraverse();
//5.后序 5437621
btree.postOrderTraverse();
System.out.println("-------------------------非递归遍历");
//3.前序,非递归
btree.preOrderByStack();
//4.中序,非递归
btree.inOrderByStack();
//5.后序,非递归
btree.postOrderByStack();
System.out.println("-------------------------");
// .层次遍历 1 42 536 7
btree.levelOrderByQueue();
//7.高度
System.out.println(btree.getHeight());
//8.节点个数
System.out.println(btree.size());
//9.查找节点
System.out.println(btree.findKey(6));
}
}
输出结果:
isEmpty:false
前序遍历:
1 4 5 2 3 6 7
中序遍历:
4 5 1 3 2 6 7
后序遍历:
5 4 3 7 6 2 1
-------------------------非递归遍历
非递归前序遍历:
1 4 5 2 3 6 7
非递归中序遍历:
4 5 1 3 2 6 7
非递归后序遍历:
5 4 3 7 6 2 1
-------------------------
层次遍历:
1 4 2 5 3 6 7
高度:4
节点个数:7
Node{data=6, left=null, right=Node{data=7, left=null, right=null}}