关于二叉树的基本概念
- 一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
二叉树的特点:
- 每个结点最多有两棵子树,即二叉树不存在度大于 2 的结点。
- 二叉树的子树有左右之分,其子树的次序不能颠倒。
下面是二叉树关于的基本操作,递归实现!
二叉树的接口定义
import java.util.List;
public interface Tree {
public List<Node> createBinTree(int[] arr);
public void preOrderTraverse(Node node);
public void inorderTraversal(Node node);
public void postorderTraversal(Node node);
public int size(Node node);//求所有节点
public int getLeafSize(Node node);//求叶子节点
public int getKLevelSize(Node node, int k);//第k层的节点
}
节点类
public class Node {
private int date;
private Node leftChild;
private Node rightChild;
public Node(int newdate){
this.date = newdate;
leftChild = null;
rightChild = null;
}
public int getDate() {
return date;
}
public void setRightChild(Node rightChild) {
this.rightChild = rightChild;
}
public Node getRightChild() {
return rightChild;
}
public void setLeftChild(Node leftChild) {
this.leftChild = leftChild;
}
public Node getLeftChild() {
return leftChild;
}
}
二叉树的接口实现类
import java.util.*;
public class BinaryTree implements Tree{
@Override
public List<Node> createBinTree(int[] arr) {
List<Node> nodeList = new LinkedList<Node>( );
for (int nodeIndex = 0; nodeIndex < arr.length; nodeIndex++){
nodeList.add(new Node(arr[nodeIndex]));
}
//对父节点 - 1 个创建二叉树关系
for (int parentIndex = 0; parentIndex < arr.length / 2 - 1; parentIndex++) {
//左孩子
nodeList.get(parentIndex).setLeftChild(nodeList.get(parentIndex * 2 + 1));
//右孩子
nodeList.get(parentIndex).setRightChild(nodeList.get(parentIndex * 2 + 2));
}
//最后一个父节点可能只有左孩子
int lastParentIndex = arr.length / 2 - 1;
nodeList.get(lastParentIndex).setLeftChild(nodeList.get(lastParentIndex * 2 + 1));
if (arr.length % 2 == 1) {
nodeList.get(lastParentIndex).setRightChild(nodeList.get(lastParentIndex * 2 + 2));
}
return nodeList;
}
@Override
public void preOrderTraverse(Node node) {
if (node == null) {
return;
}
System.out.print(node.getDate() + " ");
preOrderTraverse(node.getLeftChild());
preOrderTraverse(node.getRightChild());
}
@Override
public void inorderTraversal(Node node) {
if (node == null) {
return;
}
inorderTraversal(node.getLeftChild());
System.out.print(node.getDate() + " ");
inorderTraversal(node.getRightChild());
}
@Override
public void postorderTraversal(Node node) {
if (node == null) {
return;
}
postorderTraversal(node.getLeftChild());
postorderTraversal(node.getRightChild());
System.out.print(node.getDate()+ " ");
}
@Override
public int size(Node node) {
if (node == null) {
return 0;
}
//求节点个数
return 1 + size(node.getLeftChild()) + size(node.getRightChild());
}
@Override
public int getLeafSize(Node node) {
if (node == null) {
return 0;
}
if (node.getLeftChild() == null && node.getRightChild() == null) {
return 1;
}
return getLeafSize(node.getLeftChild()) + getLeafSize(node.getRightChild());
}
@Override
public int getKLevelSize(Node node, int k) {
if (node == null) {
return 0;
}
if (k == 1) {
return 1;
}
//第k层节点数,是第k-1层的左子树相加,以及右子数相加
return getKLevelSize(node.getLeftChild(),k-1) + getKLevelSize(node.getRightChild(),k-1);
}
}
测试类
import java.util.List;
public class Test {
public static void main(String[] args){
Tree tree = new BinaryTree();
int[] arr = {1,2,3,4,5,6,7,8,9};
List<Node> nodeList = tree.createBinTree(arr);
System.out.println("先序遍历:");
tree.preOrderTraverse(nodeList.get(0));
System.out.println();
System.out.println("中序遍历");
tree.inorderTraversal(nodeList.get(0));
System.out.println();
System.out.println("后续遍历");
tree.postorderTraversal(nodeList.get(0));
System.out.println();
System.out.println("所有节点");
System.out.println( tree.size(nodeList.get(0)));
System.out.println("叶子节点");
System.out.println(tree.getLeafSize(nodeList.get(0)));
System.out.println("第k层节点");
System.out.println(tree.getKLevelSize(nodeList.get(0),3));
}
}
测试结果