JAVA数据结构基础–二叉树
定义:
是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。
二叉树的递归定义为:
二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树
二叉树特类型:
1:满二叉树:
只有度为0的结点和度为2的结点,并且度为0的结点在同一层上的二叉树。
2:完全二叉树:
深度为k,有n个结点的二叉树当且仅当其每一个结点都与深度为k,有n个结点的满二叉树中编号从1到n的结点一一对应时
二叉树完全代码
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class BinaryTree {
class Node{//节点
private Object data;
private Node leftChlid;
private Node rightChild;
public Node(){
}
public Node(Object data){
this.data = data;
leftChlid = null;
rightChild = null;
}
public void setRoot(Object data) {//设置根结点
this.data = data;
this.leftChlid = null;
this.rightChild = null;
}
public void setLChlid(Object data) {//设置左孩子
this.leftChlid = new Node(data);
}
public void setRChlid(Object data) {//设置右孩子
this.rightChild = new Node(data);
}
public Node getLChlid() {//获得左孩子
return leftChlid;
}
public Node getRChlid() {//获得右孩子
return rightChild;
}
}
private Node root = new Node();//根结点
public Node getRoot() {//获取根结点
return root;
}
private boolean IsEmpty() {//判空
return root == null?true:false;
}
public int getHeight() {//获得高度
return getHeight(root);
}
private int getHeight(Node node) {//高度
if(node == null) {
return 0;
}
int left = getHeight(node.leftChlid);
int right = getHeight(node.rightChild);
return left>right?left+1:right+1;
}
public int getSize() {//获取节点数量
return getSize(root);
}
private int getSize(Node node) {
if(node == null) {
return 0;
}
int left = getSize(node.leftChlid);
int right = getSize(node.rightChild);
return left+right+1;
}
public void PostOrder() {//后续遍历
PostOrder(root);
}
private void PostOrder(Node node) {
if(node != null) {
PostOrder(node.leftChlid);
PostOrder(node.rightChild);
visit(node);
}
}
public void InOrder() {//中序遍历
InOrder(root);
}
private void InOrder(Node node) {
if(node != null) {
InOrder(node.leftChlid);
visit(node);
InOrder(node.rightChild);
}
}
public void PreOrder() {//前序遍历
PreOrder(root);
}
private void PreOrder(Node node) {
if(node != null) {
visit(node);
PreOrder(node.leftChlid);
PreOrder(node.rightChild);
}
}
private void visit(Node node) {
System.out.print(node.data);
}
static int i = 0;
public void PreCreat() {//前序创建
Scanner scan = new Scanner(System.in);
String str = scan.next();
String []s = str.trim().split("-");
root = creat(root,s);
}
private Node creat(Node node,String[] s) {
if(i>=s.length) {
return null;
}
String temp = s[i++];
if(temp.equals("#")) {
return null;
}else {
node = new Node(temp);
node.leftChlid=creat(node.leftChlid,s);
node.rightChild=creat(node.rightChild,s);
}
return node;
}
}
函数详解:
class Node{//节点
private Object data;//存储数据
private Node leftChlid;//左孩子
private Node rightChild;//右孩子
}
二叉树结点:
1,存放数据的data
2,指向左孩子的结点leftChlid
3,指向右孩子的结点rightChlid
根结点
private Node root = new Node();
在创建二叉树时初始化创建一个空的根结点
获得二叉树高度
public int getHeight() {//获得高度
return getHeight(root);
}
private int getHeight(Node node) {//高度
if(node == null) {
return 0;
}
int left = getHeight(node.leftChlid);
int right = getHeight(node.rightChild);
return left>right?left+1:right+1;
}
递归思想:
1,getHeight(Node node):
此函数功能为获取以node为根结点的二叉树高度。
2,if(node == null) {return 0;}:
若碰到叶节点,此路径高度计算结束,返回0表示高度增加0;
3,int left = getHeight(node.leftChlid);
计算表左子树高度
4,int right = getHeight(node.rightChild);
计算表右子树高度
5,return left>right?left+1:right+1;
若左子树大于右子树,则左子树高度+1,否则右子树高度+1。
计算结点个数:
public int getSize() {//获取节点数量
return getSize(root);
}
private int getSize(Node node) {
if(node == null) {
return 0;
}
int left = getSize(node.leftChlid);
int right = getSize(node.rightChild);
return left+right+1;
}
递归思想:
1,getSize(Node node):
此函数功能为获得以node为根结点的二叉树的结点个数。
2,if(node == null) {return 0;}
若为叶节点,返回0,表示结点数量增加0.
3,int left = getSize(node.leftChlid);
获取左子树的结点个数
4,int right = getSize(node.rightChild);
获得右子树的结点个数
5,return left+right+1;
返回左子树和右子树的结点数量和,+1表示正在遍历的node结点
前序遍历:
public void PreOrder() {//前序遍历
PreOrder(root);
}
private void PreOrder(Node node) {
if(node != null) {
visit(node);
PreOrder(node.leftChlid);
PreOrder(node.rightChild);
}
}
private void visit(Node node) {//输出操作
System.out.print(node.data);
}
递归思想:
1, PreOrder(Node node):
此函数功能为前序遍历以node为根结点的二叉树
2,if(node != null)
在不遇到叶节点后中止当前结点的遍历
3,前序遍历:先遍历根结点,依次遍历左结点和右结点
visit(node);//遍历操作,先遍历根结点
PreOrder(node.leftChlid);//前序遍历根结点的左子树
PreOrder(node.rightChild);//前序遍历根结点的右子树
前序遍历,中序遍历和后续遍历递归思想相同,只是遍历顺序不同了
前序遍历
visit(node);//先根结点
PreOrder(node.leftChlid);//后根结点的左孩子
PreOrder(node.rightChild);//在根结点的右孩子
中序遍历
InOrder(node.leftChlid);//先左孩子
visit(node);//根结点的访问在中间
InOrder(node.rightChild);//后右孩子
后续遍历
PostOrder(node.leftChlid);//先左孩子
PostOrder(node.rightChild);//后右孩子
visit(node);//根结点访问在最后
可以想象
1:前序遍历是在第一次碰见结点就输出
2:中序遍历是在第二次碰见结点就输出
3:后序遍历是在第三次碰见结点就输出
以中序遍历为例子,首先进入A结点(根结点),第一次碰见不输出,在访问A结点的左结点B,第一次碰见B结点不输出,在访问B结点的左结点,为NULL,返回后访问B结点,第二次碰见B结点,输出B。访问B结点的右结点为空,返回访问B结点,第三次碰见。返回访问A结点,第二次碰见A结点,输出A。访问A的右节点C,第一次碰见C结点不输出,访问C的左结点,为NULL,返回访问C第二次碰见C,输出C。访问C结点的右结点为空,返回访问C结点,第三次碰见。最后返回访问A,第三次碰见A。
前序创建二叉树
static int i = 0;//表示字符串下标
public void PreCreat() {//前序创建
Scanner scan = new Scanner(System.in);
String str = scan.next();
String []s = str.trim().split("-");//trim去点字符串开头,末尾的空格,split按“-”分隔字符串为数组
root = creat(root,s);
}
private Node creat(Node node,String[] s) {
if(i>=s.length) {//当字符串下标大于等于字符长度结束返回null,表示叶节点
return null;
}
String temp = s[i++];//获取字符串的字符后,下标+1
if(temp.equals("#")) {//若字符串为#,表示空结点
return null;
}else {
node = new Node(temp);//初始化当前结点
node.leftChlid=creat(node.leftChlid,s);//前序创建左子树
node.rightChild=creat(node.rightChild,s);//前序创建右子树
}
return node;//返回创建后的根结点
}
二叉树的创建也是利用了递归思想,与遍历思想类似。
感谢收看,有问题欢迎提问。