朋友们如果看了我的上几篇博客,应该都会记得我利用工厂类和静态方法创建二叉树的方式,我们今天就介绍一种更加“面向对象“的二叉树创建方式,这种利用内部类创建的二叉树访问起来更加方便,代码如下
public class BinaryTree {
private Node root;
/**
*
* 内部节点类
* @author yyd
*/
private class Node{
private Node left;
private Node right;
private int data;
public Node(int data){
this.left = null;
this.right = null;
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
public BinaryTree(){
root = null;
}
/**
* 递归创建排序二叉树
* @param node 父亲节点
* @param data 子节点的数据
*/
public void buildTree(Node node,int data){
if(root == null){
root = new Node(data);
}else{
if(data < node.data){
if(node.left == null){
node.left = new Node(data);
}else{
buildTree(node.left,data);
}
}else{
if(node.right == null){
node.right = new Node(data);
}else{
buildTree(node.right,data);
}
}
}
}
/**
* 根据一个数组来创建二叉树
* @param a n+1个数据组成的数组,其中a[0]=-1不参与树的创建,a[1]~a[n]代表数的节点,a[2*i]是a[i]的左子结点,a[2*i+1]是右子节点
*/
public void buildTreeByArray(int[] a,int n){
Node[] p=new Node[n+1];
p[0]=null;
for(int i=1;i<=n;i++){
if(a[i]==-1){
p[i]=null;
}
else{
p[i]=new Node(a[i]);
}
}
for(int i=1;i<=n/2;i++){
if(a[i]!=-1){
if((2*i<=n)&&a[2*i]!=-1){
p[i].setLeft(p[2*i]);
}
if((2*i+1<=n)&&(a[2*i+1]!=-1)){
p[i].setRight(p[2*i+1]);
}
}
}
root=p[1];
}
/**
* 根据一个先序遍历数组和一个中序遍历数组建立一棵二叉树
*/
public Node createBTreeByOrder(int[] pre,int[] in,int prelow,int prehigh,int inlow,int inhigh){
if((prehigh-prelow>=0)&&(inhigh-inlow>=0)){
Node n=new Node(pre[prelow]);
int k=inlow;
for(int i=inlow;i<=inhigh;i++){
if(pre[prelow]==in[i]){
k=i;
break;
}
}
n.left=createBTreeByOrder(pre,in,prelow+1,prelow+k-1,inlow,k-1);
n.right=createBTreeByOrder(pre, in, prelow+k, prehigh, k+1, inhigh);
return n;
}
else
return null;
}
/**
* 检测一棵树是不是完全二叉树
* 这里采用层次遍历在遍历到某节点的子节点空时将flag置为1,之后若有其他节点的子节点存在则返回false
* @param node
* @return
*/
public boolean checkIfCompleteTree(Node node){
Node[] queue=new Node[255];
int tail=0;
int head=0;//队头指针与队尾指针
Node p=node;
int flag=1;
if(p!=null){
queue[tail++]=node;//将节点加入队列中
while(head!=tail){ //即队不空
Node temp=queue[head++];
if(temp.left!=null){
if (flag==0)
return false;
else{
queue[tail++]=temp.left;
}
}
else{
flag=0;
}
if(temp.right!=null){
if(flag==0){
return false;
}
else{
queue[tail++]=temp.right;
}
}
else{
flag=0;
}
}
}
return true;
}
/**
* 前序遍历
* @param node
*/
public void preOrder(Node node){
if(node != null){
System.out.print(node.data+" ");
preOrder(node.left);
preOrder(node.right);
}
}
/**
* 中序遍历
* @param node
*/
public void inOrder(Node node){
if(node != null){
inOrder(node.left);
System.out.print(node.data+" ");
inOrder(node.right);
}
}
/**
* 后序遍历
* @param node
*/
public void postOrder(Node node){
if(node != null){
postOrder(node.left);
postOrder(node.right);
System.out.print(node.data+" ");
}
}
/**
* 层次遍历
* @param node
*/
public void levelOrder(Node node){
Node[] queue=new Node[255];
int tail=0;
int head=0;//队头指针与队尾指针
Node p=node;
if(p!=null){
queue[tail++]=node;//将节点加入队列中
while(head!=tail){//即队不空
Node temp=queue[head++];
System.out.print(temp.getData()+" ");
if(temp.left!=null){
queue[tail++]=temp.left;
}
if(temp.right!=null){
queue[tail++]=temp.right;
}
}
}
}
/**
* 从以node为根的树中找出值为x的节点,若找到就返回该节点,否则返回null
* @param x
* @param node
*/
public Node find(int x,Node node){
if(node!=null){
if(node.getData()==x){
return node;
}
else{
Node t=find(x,node.getLeft());
if(t!=null)
return t;
else
return find(x,node.getRight());
}
}
else{
return null;
}
}
/**
* 给出一个节点判断它在树中的高度
* @param node
* @return
*/
public int getDepth(Node node){
if(node==null)
return 0;
else{
int lh=getDepth(node.getLeft());
int rh=getDepth(node.getRight());
return lh>=rh?lh+1:rh+1;
}
}
/**
* 得出一棵树的高度(非递归算法)
*/
public int getHeight(Node node){
Node[] qu=new Node[255];
Node p=node;
int tail=0;
int head=0;
int level=0;
int point;//用来指示每一层的最后一个节点
if(node!=null){
qu[tail++]=p;
point=tail;
while(head!=tail){
p=qu[head++];
if(p.left!=null){
qu[tail++]=p.left;
}
if(p.right!=null){
qu[tail++]=p.right;
}
if(head==point){
level++;
point=tail;
}
}
}
return level;
}
/**
* 给出根节点和一个节点的值,找出这个节点的所有祖先节点并且将他们打印出来
*/
public boolean ancestor(Node node,int x){
if (node==null){
return false;
}
else{
if(node.getData()==x)
return true;
else{
boolean b1=ancestor(node.left,x);
boolean b2=ancestor(node.right,x);
if(b1||b2)
System.out.print(node.getData()+" ");
return b1||b2;
}
}
}
public static void main(String[] args) {
int[] a={-1,2,4,6,7,-1,-1,-1};
BinaryTree bTree = new BinaryTree();
bTree.buildTreeByArray(a, 7);
bTree.ancestor2(bTree.root, 7);
}
}
在main函数中我们演示了怎样初始化一棵二叉树,并为他赋值的过程.