1、链式存储结构
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
2、遍历
(1)先序遍历
//递归
void PreOrder1(BiTree T){
if(T!=NULL){
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
//非递归
void PreOrder2(BiTree T){
InitStack(S); BiTree p=T; //初始化栈S,p是遍历指针
while(p || !isEmpty(S)){ //栈不空或p不空时循环
if(p){ //一路向左走
visit(p); //访问当前结点
Push(p); //入栈
p=p->lchild; //左孩子不空,一直往左走
}
else{ //出栈,并转向出栈结点的右子树
Pop(S,p); //出栈
p=p->rchild; //向右子树走,p赋值为当前结点的右孩子
}
}
}
(2)中序遍历
//递归
void InOrder1(BiTree T){
if(T!=NULL){
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
//非递归
void InOrder2(BiTree T){
InitStack(S); BiTree p=T; //初始化栈S,p是遍历指针
while(p || !isEmpty(S)){ //栈不空或p不空时循环
if(p){ //一路向左走
Push(p); //入栈
p=p->lchild; //左孩子不空,一直往左走
}
else{ //出栈,并转向出栈结点的右子树
Pop(S,p); //出栈
visit(p); //访问当前结点
p=p->rchild; //向右子树走,p赋值为当前结点的右孩子
}
}
}
(3)后序遍历
//递归
void PostOrder1(BiTree T){
if(T!=NULL){
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
//非递归
void PostOrder2(BiTree T){
InitStack(S); BiTree p=T; r=NULL;
while(p || !isEmpty(S)){
if(p){ //走到最左
Push(p);
p=p->lchild;
}
else{ //向右
GetPop(S,p); //读栈顶结点(非出栈)
if(p->rchild && p->rchild!=r){ //若右子树存在,且未访问
p=p->rchild; //转向右
Push(S,p); //入栈
p=p->lchild; //再走到最左
}
else{ //否则,弹出结点并访问
Pop(S,p); //将结点弹出
visit(p->data);
r=p; //记录最近访问过的结点
p=NULL; //结点访问完后,重置p指针
}
}//else
}//while
}while
(4)层序遍历
void LevelOrder(BiTree T){
InitQueue(Q);
BiTree p;
EnQueue(Q,T); //根结点入队
while(!isEmpty(Q)){ //队不空则循环
DeQueue(Q,p);
visit(p);
if(p->lchild!=NULL)
EnQueue(Q,p->lchild); //左子树不空,则左子树根结点入队
if(p->rchild!=NULL)
EnQueue(Q,p->rchild); 左子树不空,则左子树根结点入队
}
}
2、求树高度
//递归
public static int high1(Node root){
return root=null?0:Math.max(high(root.left)+1,high(root.right)+1);
}
//非递归
public static int high2(Node root){
if(root==null) return 0;
int high=0,k; //k值存放每层的大小
Queue<Node> queue=new LinkedList<~>();
queue.add(root);
while(!queue.isEmpty()){
high++;
k=queue.size()
for(int i=0;i<k;i++){
Node tmp=queue.poll();
if(tmp.left!=NULL){
queue.add(tmp.left);
}
if(tmp.right!=NULL){
queue.add(tmp.right);
}
}
}
return high;
}
3、求树最大宽度
public static int maxWidth(Node root){
if(root==null) return 0;
int width=0,k;
Queue<Node> queue=new LinkedList<~>();
queue.add(root);
while(!queue.isEmpty()){
if(width<queue.size()){
width=queue.size();
}
k=queue.size();
for(int i=0;i<k;i++){
Node tmp=queue.poll();
if(tmp.left!=NULL){
queue.add(tmp.left);
}
if(tmp.right!=NULL){
queue.add(tmp.right);
}
}
}
return width;
4、设一棵二叉树各结点的值互不相同,其先序遍历序列和中序遍历序列分别存于两个一维数组A[1…n]和B[1…n]中,试编写算法建立该二叉树的二叉链表
BiTree PreInCreat(ElemType A[],ElemType B[],int l1,int h1,int l2,int h2){
//l1,h1为先序的第一个和最后一个结点下标,l2,h2为后序的第一个和最后一个结点下标
//初始调用时,l1=l2=1,h1=h2=n
root=(BiTNode*)malloc(sizeof(BiTNode)); //建根结点
root->data=A[l1]; //根结点
for(i=l2;B[i]!=root->data;i++); //根结点在中序序列中的划分
llen=i-l2; //左子树长度
rlen=h2-i; //右子树长度
if(llen) //递归建立左子树
root->lchild=PreInCreat(A,B,l1+1,l1+llen,l2,l2+llen-1);
else //左子树为空
root->lchild=NULL;
if(rlen) //递归建立右子树
root->rchild=PreInCreat(A,B,h1-rlen+1,h1,h2-rlen+1,h2);
else //右子树为空
root->rchild=NULL;
return root; //返回根结点
}