To actually define a binary tree in general, we must allow for the possibility that only one of the children may be empty. An artifact, which in some textbooks is called an extended binary tree is needed for that purpose. An extended binary tree is thus recursively defined as:
1.the empty set is an extended binary tree
2.if T1 and T2 are extended binary trees, then denote by T1 • T2 the extended binary tree obtained by adding a root r connected to the left to T1 and to the right to T2 by adding edges when these sub-trees are non-empty.
就是说考虑空集也是“扩展二叉树”,通过一个树节点节点将两个“扩展二叉树”分别作为左右子节点后,以该树节点为根节点构成一棵“扩展二叉树”。
1.节点和引用,这个自不必说。
2.数组:二叉树以隐式广度优先搜索顺序存储在数组中,这种方法节省两个左右子节点引用的内存。
对于以0为索引开头的数组,数组索引值为i的节点,它的左右子节点的索引分别为2i+1,2i+2,而它的父节点数组索引[(i-1)/2]
对于以1为索引开头的数组,数组索引值为i的节点,它的左右子节点的索引分别为2i,2i+1,而它的父节点数组索引[i/2]
存储稠密并且更好的本地引用(数组索引速度快),然而这种存储方法耗费的空间复杂度为O(2^h-n)(深度h,节点数为n的树)
直接上代码:
//二叉树的二叉链表树用根节点来表示
public class BinaryTree{
public BinaryNode root;
public BinaryTree()
{
this.root=null;
}
public BinaryTree(BinaryNode root)
{
this.root=root;
}
/*
先根遍历和中根遍历两种次序可以唯一确定二叉树,perlist和inlist长度为n,序号为0~n-1
先根遍历序列prelist的perlist[0]为根节点,在中根遍历序列的inlist中寻找值为perlist[0]的节点,序号为i
在inlist中i左边0,i-1为左子树,i+1,n为右子树
左子树的先根遍历序列为prelist[1],...,prelist[i]
左子树的中根遍历序列为inlist[0],...inlist[i-1]
右子树的先根遍历序列为prelist[i+1],...prelist[n-1]
右子树的中根遍历序列inlist[i+1],...,inlist[n-1]
*/
public BinaryTree(T[] prelist,T[] inlist)
{
this.root=create(prelist,inlist,0,0,prelist.length);
}
public BinaryNode create(T[] prelist,T[] inlist,int preStart,int inStart,int n )
{
if(n<=0)
return null;
T e=prelist[preStart];
BinaryNode p=new BinaryNode(e);
int i=0;
while(i p)
{
if(p==null)
return 0;
return 1+count(p.left)+count(p.right);
}
@Override
public int height() {
// TODO Auto-generated method stub
return height(this.root);
}
//递归调用height求当前节点的高度
public int height(BinaryNode p)
{
if(p==null)
return 0;
int lcount=height(p.left);
int rcount=height(p.right);
return (lcount>=rcount)?lcount+1:rcount+1;
}
@Override
public void preOrder() {
//先根次序遍历:访问根节点,遍历左子树,遍历右子树 TODO Auto-generated method stub
System.out.print("先根次序遍历二叉树");
preOrder(root);
System.out.println();
}
public void preOrder(BinaryNode p)
{
if(p!=null)
{
System.out.print(p.data.toString()+" ");
preOrder(p.left);
preOrder(p.right);
}
}
/*用非递归先根遍历以node为根节点的(子)树
*在二叉树先序遍历非递归算法中,先将根结点压栈,在栈不为空的时候执行循环:让栈顶元素p出栈,访问栈顶元素p,
*如果p的右孩子不为空,则让其右孩子先进栈,如果p的左孩子不为空,则再让其左孩子进栈
*(注意:进栈顺序一定是先右孩子,再左孩子)。
*/
public void preOrderNoRecursive(BinaryNode node)
{
LinkedStack> stack=new LinkedStack>();
BinaryNode p=node;
//停止while循环的条件是栈为空并且p指向null
while(!stack.isEmpty() || p!=null)
{
while(p!=null)
{
System.out.print(p.data);
stack.push(p);//入栈操作表示访问该节点
p=p.left;
}
if(!stack.isEmpty())
{
p=stack.getTop();
stack.pop();
p=p.right;
}
}
}
public void preOrderNoRecursive2(BinaryNode node)
{
LinkedStack> stack=new LinkedStack>();
BinaryNode p=node;
while(!stack.isEmpty() || p!=null)
{
if(p!=null)
{
System.out.print(p.data);
stack.push(p);
p=p.left;
}
else
{
p=stack.getTop();
stack.pop();
p=p.right;
}
}
}
@Override
public void inOrder() {
//中根次序遍历:遍历左子树,访问根节点,遍历右子树 TODO Auto-generated method stub
System.out.print("中根次序遍历二叉树");
inOrder(root);
System.out.println();
}
public void inOrder(BinaryNode p)
{
if(p!=null)
{
preOrder(p.left);
System.out.print(p.data.toString()+" ");
preOrder(p.right);
}
}
//用非递归中根遍历以node为根节点的(子)树
public void inOrderNoRecursive(BinaryNode node)
{
System.out.println("非递归中根遍历: ");
LinkedStack> stack=new LinkedStack>();
BinaryNode p=node;
while(!stack.isEmpty() || p!=null )
{
if(p!=null)
{
stack.push(p);
p=p.left;
}
else
{
p=stack.pop();
System.out.print(p.data+" ");
p=p.right;
}
}
}
@Override
public void postOrder() {
// 后根次序遍历:遍历左子树,遍历右子树,访问根节点TODO Auto-generated method stub
System.out.print("后根次序遍历二叉树");
postOrder(root);
System.out.println();
}
public void postOrder(BinaryNode p)
{
if(p!=null)
{
postOrder(p.left);
postOrder(p.right);
System.out.print(p.data.toString()+" ");
}
}
//对于非递归后根遍历,使用顺序栈比
public void postOrderNoRecursive(BinaryNode node)
{
System.out.println("非递归后根遍历: ");
SeqStack> stack=new SeqStack>();
BinaryNode p=node;
int[] tag=new int[this.count()];
//停止while循环的条件是栈为空并且p指向null
while(!stack.isEmpty() || p!=null)
{
while(p!=null)
{
stack.push(p);
tag[stack.getTopIndex()]=0;
p=p.left;
}
while(!stack.isEmpty() && tag[stack.getTopIndex()]==1)
{
System.out.print(stack.pop());
}
if(!stack.isEmpty())
{
p=stack.getTop();
tag[stack.getTopIndex()]=1;
p=p.right;
}
}
}
public void postOrderNoRecursive2(BinaryNode node)
{
if(node==null)
return;
LinkedStack> stack=new LinkedStack>();
stack.push(node);
BinaryNode lastPop=node;
while(!stack.isEmpty())
{
BinaryNode top =stack.getTop();
if(top.left!=null && top.left!=lastPop && top.right!=lastPop)
stack.push(top.left);
else if(top.right!=null && top.right!=lastPop && (top.left==lastPop || top.left==null))
{
stack.push(top.right);
}
else
{
stack.pop();
lastPop=top;
System.out.print(top.data);
}
}
}
public String toGenListString()
{
return "二叉树的广义表形式"+this.toGenListString(this.root);
}
public String toGenListString(BinaryNode node)
{
if(node==null)
return "^";
String str=node.data.toString();
if(node.left!=null || node.right!=null)
str+="("+this.toGenListString(node.left)+","+this.toGenListString(node.right)+")";
return str;
}
public void levelOrder(BinaryNode node) {
// TODO Auto-generated method stub
LinkedQueue> q=new LinkedQueue>();
BinaryNode p=node;
q.enqueue(p);
while(!q.isEmpty())
{
p=q.dequeu();
System.out.print(p.data.toString());
if(p.left!=null)
q.enqueue(p.left);
if(p.right!=null)
q.enqueue(p.right);
}
}
@Override
public void levelOrder()
{
levelOrder(this.root);
}
@Override
public BinaryNode search(T key) {
// TODO Auto-generated method stub
return search(this.root,key);
}
public BinaryNode search(BinaryNode p,T key)
{
if(p==null||key==null)
return null;
if(p.data.equals(key))
return p;
BinaryNode find=search(p.left,key);
if(find==null)
find=search(p.right,key);
return find;
}
@Override
public BinaryNode getParent(BinaryNode node) {
// TODO Auto-generated method stub
return getParent(this.root,node);
}
//查找以p为根的子树中节点node的父节点
public BinaryNode getParent(BinaryNode p,BinaryNode node)
{
if(p==null)
return null;
if(p.left==node||p.right==node)
return p;
BinaryNode find=getParent(p.left,node);
if(find==null)
find=getParent(p.right,node);
return find;
}
@Override
public void insertRoot(T x) {
// TODO Auto-generated method stub
BinaryNode new_root=new BinaryNode(x);
new_root.left=this.root;
}
//插入x作为节点p的左(右)子节点,如果p节点已经存在对应的左(右)节点,则原左(右)节点作为插入节点的左(右)子节点
@Override
public BinaryNode insertChild(BinaryNode p, T x, boolean leftChild) {
// TODO Auto-generated method stub
if(p==null || x==null)
return null;
BinaryNode new_node=new BinaryNode(x);
if(leftChild)
{
if(p.left==null)
p.left=new_node;
else
{
new_node.left=p.left;
p.left=new_node;
}
}
else
{
if(p.right==null)
p.right=new_node;
else
{
new_node.right=p.right;
p.right=new_node;
}
}
return new_node;
}
//删除节点p的左(右)子节点,这里规定将以p的左(右)子节点为根节点的树全部删去
@Override
public void removeChild(BinaryNode p, boolean leftChild) {
// TODO Auto-generated method stub
if(p!=null)
{
if(leftChild)
p.left=null;
else
p.right=null;
}
}
@Override
public void removeAll() {
// TODO Auto-generated method stub
this.root=null;
}
public static void main(String[] args)
{
BinaryNode n7=new BinaryNode("H");
BinaryNode n6=new BinaryNode("G");
BinaryNode n5=new BinaryNode("F");
BinaryNode n4=new BinaryNode("E");
BinaryNode n3=new BinaryNode("D",n7,null);
BinaryNode n2=new BinaryNode("C",n5,n6);
BinaryNode n1=new BinaryNode("B",n3,n4);
BinaryNode n0=new BinaryNode("A",n1,n2);
BinaryTree tree=new BinaryTree(n0);
System.out.println(tree.height());
System.out.println(tree.count());
tree.preOrder();
tree.inOrder();
tree.postOrder();
tree.preOrderNoRecursive(n0);
System.out.println();
tree.preOrderNoRecursive2(n0);
System.out.println();
tree.postOrderNoRecursive(n0);
System.out.println();
tree.postOrderNoRecursive(n2);
System.out.println();
tree.postOrderNoRecursive2(n0);
System.out.println();
System.out.println(tree.toGenListString());
System.out.println();
tree.levelOrder();
}
}
打印结果如下:
4
8
先根次序遍历二叉树A B D H E C F G
中根次序遍历二叉树B D H E A C F G
后根次序遍历二叉树H D E B F G C A
ABDHECFG
ABDHECFG
非递归后根遍历:
HDEBFGCA
非递归后根遍历:
FGC
HDEBFGCA
二叉树的广义表形式A(B(D(H,^),E),C(F,G))
ABCDEFGH