C语言数据结构之二叉树的操作

输入完全二叉树的先序序列,用#代表虚结点(空指针),如ABD###CE##F##,建立二叉树的二叉链表。已知二叉树的先序遍历序列和中序遍历序列,或者已知二叉树的中序遍历序列和后序遍历序列,建立二叉树的二叉链表。将一棵二叉树的所有结点存储在一维数组中,虚结点用#表示,利用二叉树的性质5,建立二叉树的二叉链表。例如用数组a存储的二叉树的结点如下(0单元不用写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。写出对用二叉链表存储的二叉树进行层次遍历算法。求二叉树的所有叶子及结点总数。

#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode
{
	int data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

void CreateBiTree(BiTree &bt)//按先序遍历创建一个二叉树
{
	int tmp;
	scanf("%d",&tmp );
	if(tmp==-1)
		bt=NULL;
	else
	{	
		bt=(BiTree)malloc(sizeof(BiTNode));
		if(!bt) return;
		bt->data =tmp;
		CreateBiTree(bt->lchild );
		CreateBiTree(bt->rchild );
	}
} 	

void InOrderTraverse(BiTree bt)//中序递归遍历
{
	if(bt==NULL) return;
	else
	{
		InOrderTraverse(bt->lchild );
		printf("%d  ",bt->data );
		InOrderTraverse(bt->rchild );
	}
}
void PreOrderTraverse(BiTree bt)     //先序遍历二叉树
{
   if ( bt )
   {   printf(“%4d”, bt->data);
       PreOrderTraverse(bt->lchild);
       PreOrderTraverse(bt->rchild);
   }
}
void PostOrderTraverse(BiTree bt)     //后序遍历二叉树
{
   if ( bt )
   {   
       PostOrderTraverse(bt->lchild);
       PostOrderTraverse(bt->rchild);
       printf(“%4d”, bt->data);
   }
}


#define MAXSTACK  15
typedef struct {    //定义栈的存储结构
BiTree *base;
int  top;
}SqStack;

//栈操作的相关函数
void InitStack(SqStack &S)
{  S.base=(BiTree*)malloc(sizeof(BiTNode));
   if( !S.base )   exit(0);
   S.top=0;
}

void Push(SqStack &S, BiTree e)
{  
   if( S.top== MAXSTACK )
      exit(0);
S.base[S.top] = e;
   S.top++;
}

void Pop(SqStack &S, BiTree &e)
{
   if( S.top==0)
     exit(0);
   S.top--;
   e=S.base[S.top];
}

int GetTop(SqStack S, BiTree &e)
{
   if( S.top== 0 )
     return 0;
   e=S.base[S.top-1];
   return 1;
}

int StackEmpty(SqStack S )
{
   if ( S.top == 0 )
     return 1;
   else return 0;
}

void InOrderTraverse1(BiTree bt)//中序非递归遍历----用到栈
{
   SqStack S;
   BiTree p;
   if ( bt )
   {   InitStack( S );  Push( S, bt );
       while( !StackEmpty( S ))
       {   
           while(GetTop( S, p ) && p )
              Push( S, p->lchild );  
           Pop( S, p );
           if( !StackEmpty( S ))
           {  
              Pop( S, p );    printf("%d   ", p->data );   
              Push( S, p->rchild );
           }
       }
   }//if

}

void PreOrderTraverse1(BiTree bt)     //先序遍历二叉树的非递归算法
{
   SqStack S;
   BiTree p;
   if ( bt )
   {   InitStack( S );  Push( S, bt );
       while( !StackEmpty( S ))
       {   
           while(GetTop( S, p ) && p )
           {   printf(“%4d”, p->data );   Push( S, p->lchild );  }
           Pop( S, p );
           if( !StackEmpty( S ))
           {  Pop( S, p );   Push( S, p->rchild );   }
       }
   }//if
}
void PostOrderTraverse1(BiTree bt)     //后序遍历二叉树的非递归算法
{
   SqStack S;
   BiTree p, q;
   if ( bt )
   {   InitStack( S );  Push( S, bt );
       while( !StackEmpty( S ))
       {   
           while(GetTop( S, p ) &&  p )
              Push( S, p->lchild );  
           Pop( S, p );
           if( !StackEmpty( S ))
           {  
              GetTop( S, p ); 
              Push( S, p->rchild );
              if(GetTop( S, p ) && !p )
              {  Pop( S, p );     //空结点出栈
                 Pop( S, p );    
printf(“%4d”, p->data );
                 while( !StackEmpty(S) && GetTop( S, q) && q->rchild == p)
                 {   Pop( S, p );   printf(“%4d”, p->data );    }
                 if( !StackEmpty(S) )
                 {   GetTop( S, p );    Push( S, p->rchild );  }
              }//if(!p)
           }//if(!StackEmpty(S))
       }//whie
   }//if
}


#define MAXQSIZE 100   //最大队列长度
typedef struct {
       BiTree     *base;    //初始化动态分配空间
       int	   front;
       int	   rear;
} SqQueue;

int InitQueue(SqQueue &Q){
//构造一个空队列
    Q.base = (BiTree *)malloc(MAXQSIZE * sizeof(BiTNode));
    if ( ! Q.base)   return 0;
    Q.front = Q.rear = 0;
    return 1;
} //InitQueue

int EnQueue(SqQueue &Q, BiTree e){
//插入元素e为Q的新的队尾元素
    if ((Q.rear+1)%MAXQSIZE == Q.front) 
        return 0;
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear+1) % MAXQSIZE;
    return 1;
}

int DeQueue(SqQueue &Q, BiTree &e){
// 删除Q的队头元素, 并用e返回其值
    if(Q.front == Q.rear) return 0;
    e = Q.base[Q.front];
    Q.front = (Q.front+1) % MAXQSIZE;
    return 1;
} 

int EmptyQueue(SqQueue Q)//判队空
{
	if(Q.front ==Q.rear )
		return 1;
	else return 0;
}

void LevelOrderTraverse(BiTree bt) 
{   //按层次遍历二叉树算法——用到队列这种数据结构
	SqQueue Q;
	BiTree p;
	if( !bt )   return ;  //空树
    InitQueue(Q);//初始化空队列Q  
	//p=bt;
    EnQueue(Q, bt);        //根入队
    while( !EmptyQueue(Q))
	 {
          DeQueue(Q, p);    //队头p出队
          printf("%d    ",p->data );  //访问p
		  if(p->lchild) EnQueue(Q,p->lchild); //p的左孩子入队
          if(p->rchild) EnQueue(Q,p->rchild); //p的右孩子入队
      }
}

void LeavesCount(BiTree bt,int &count)//求二叉树的叶子结点数
{
	SqQueue Q;
	BiTree p;
	//p=bt;
	if(!bt) count=0;
	else
	{
		InitQueue(Q);
		EnQueue(Q,bt);
		while( !EmptyQueue(Q)) 
		{
			DeQueue(Q, p);
			if(!p->lchild && !p->rchild)count++;
			if(p->lchild) EnQueue(Q,p->lchild); //p的左孩子入队
			if(p->rchild) EnQueue(Q,p->rchild); //p的右孩子入队
		}
	}
}


void main()
{
	BiTree bt;
	printf("建立二叉树:\n");
	CreateBiTree(bt);
	printf("中序递归遍历二叉树:\n");
	InOrderTraverse(bt);
	printf("\n");
	printf("中序非递归遍历二叉树:\n");
	InOrderTraverse1(bt);
	printf("\n");
	printf("层次遍历二叉树:\n");
	LevelOrderTraverse(bt);
	printf("\n");
	int count=0;
	LeavesCount(bt,count);
	printf("叶子结点数为:%d\n",count);
}


posted @ 2015-11-02 13:02  Joe.Smith  阅读(310)  评论(0编辑  收藏  举报