#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define STACK_INIT_SIZE 100 //栈初始化分配量
#define STACKINCREMENT 10 //存储空间的分配增量
#define MAXQSIZE 20;
typedef int Status ;
//-------------二叉树的二叉链表----------------------
typedef struct BiTNode{
char data; //数据域
struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
/*====================================================
----------二叉树非递归遍历的辅助结构栈-----
=====================================================*/
//前序非递归遍历和后序非递归遍历都是用栈作为辅助结构
typedef struct {
BiTree *base ;
BiTree *top ;
int stacksize ;
}SqStack;
//--------栈的初始化----------------------------
Status InitStack(SqStack &S){
S.base = (BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTree));
if(!S.base) exit(OVERFLOW);
S.top = S.base ;
S.stacksize = STACK_INIT_SIZE;
return OK ;
}
Status Push(SqStack &S ,BiTree P){
//首先判断栈是否已满
if((S.top-S.base) >= S.stacksize){
S.base = (BiTree*)realloc(S.base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(BiTree));
if(!S.base) exit(OVERFLOW);
S.top = S.base +S.stacksize ;
S.stacksize +=STACKINCREMENT ;
}
*S.top = P ;
S.top ++ ;
return OK ;
}
BiTree Pop(SqStack &S){
//判断栈是否已空
if(S.base==S.top) return ERROR ;
S.top = S.top-1 ;
BiTree P = *S.top;
return P ;
}
Status isEmpty(SqStack S){
if(S.base==S.top)
return OK ;
return ERROR ;
}
BiTree GetTop(SqStack S){
if(S.top==S.base) return NULL;
return *(--S.top);
}
int StackLength(SqStack S){
int length = 0;
if(S.base==S.top) return 0 ;
while(S.base!=S.top){
length++ ;
S.top-- ;
}
return length ;
}
/*===================队列=============================*/
typedef struct QNode
{
BiTree data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front,rear; /* 队头、队尾指针 */
}LinkQueue;
Status InitQueue(LinkQueue *Q)
{ /* 构造一个空队列Q */
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
if(!(*Q).front)
exit(OVERFLOW);
(*Q).front->next=NULL;
return OK;
}
Status DestroyQueue(LinkQueue *Q)
{ /* 销毁队列Q(无论空否均可) */
while((*Q).front)
{
(*Q).rear=(*Q).front->next;
free((*Q).front);
(*Q).front=(*Q).rear;
}
return OK;
}
Status ClearQueue(LinkQueue *Q)
{ /* 将Q清为空队列 */
QueuePtr p,q;
(*Q).rear=(*Q).front;
p=(*Q).front->next;
(*Q).front->next=NULL;
while(p)
{
q=p;
p=p->next;
free(q);
}
return OK;
}
Status QueueEmpty(LinkQueue Q)
{ /* 若Q为空队列,则返回TRUE,否则返回FALSE */
if(Q.front==Q.rear)
return true;
else
return false;
}
int QueueLength(LinkQueue Q)
{ /* 求队列的长度 */
int i=0;
QueuePtr p;
p=Q.front;
while(Q.rear!=p)
{
i++;
p=p->next;
}
return i;
}
Status GetHead_Q(LinkQueue Q,BiTNode *e) /* 避免与bo2-6.c重名 */
{ /* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */
QueuePtr p;
if(Q.front==Q.rear)
return ERROR;
p=Q.front->next;
*e=p->data;
return OK;
}
Status EnQueue(LinkQueue *Q,BiTNode e)
{ /* 插入元素e为Q的新的队尾元素 */
QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
if(!p) /* 存储分配失败 */
exit(OVERFLOW);
p->data=e;
p->next=NULL;
(*Q).rear->next=p;
(*Q).rear=p;
return OK;
}
Status DeQueue(LinkQueue *Q,BiTNode *e)
{ /* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
QueuePtr p;
if((*Q).front==(*Q).rear)
return ERROR;
p=(*Q).front->next;
*e=p->data;
(*Q).front->next=p->next;
if((*Q).rear==p)
(*Q).rear=(*Q).front;
free(p);
return OK;
}
Status QueueTraverse(LinkQueue Q,void(*vi)(QElemType))
{ /* 从队头到队尾依次对队列Q中每个元素调用函数vi()。一旦vi失败,则操作失败 */
QueuePtr p;
p=Q.front->next;
while(p)
{
vi(p->data);
p=p->next;
}
printf("\n");
return OK;
}
///
/*====================================================
前序创建一个二叉链表
=====================================================*/
//前序递归创建
int CreateBiTree(BiTree &T){
char data ;
//按照次序输入二叉树中节点的值(一个字符),
//'#'表示空树
scanf("%c",&data);
if(data=='#'){
T=NULL ;
}else{
T = (BiTree) malloc(sizeof(BiTNode));
if(!T) return -1 ;
//生成根结点
T->data = data ;
//构造右子树
CreateBiTree(T->lchild);
//构造右子树
CreateBiTree(T->rchild);
}
return 0 ;
}
//注意要想改成中序或是后序递归调用时:仅仅需改
/*
//生成根结点
T->data = data ;
//构造右子树
CreateBiTree(T->lchild);
//构造右子树
CreateBiTree(T->rchild);
*/
//的次序即可
Status BiTreeEmpty(BiTree T){
/*初始条件:树T存在. 操作结果:若树T为空则返回true,不空返回false*/
if(T) return true;
return false ;
}
char Root(BiTree T){
if(!BiTreeEmpty(T))
return NULL;
else
return T->data;
}
char Value(BiTree p){
/*树T存在,p是树中某个结点的指针,返回该指针的值*/
return p->data;
}
void Assign(BiTree p,char value)
{ /* 给p所指结点赋值为value */
p->data=value;
}
/*====================================================
二叉树的递归遍历(先,中,后)
=====================================================*/
void Visit(BiTree &T){
if(T->data!='#'){
printf("%c",T->data);
}
}
void preOrder(BiTree &T){
if(T==NULL) return ;
Visit(T);
preOrder(T->lchild);
preOrder(T->rchild);
return ;
}
void inOrder(BiTree &T){
if(T==NULL) return ;
inOrder(T->lchild);
Visit(T);
inOrder(T->rchild);
return ;
}
void postOrder(BiTree &T){
if(T==NULL)return ;
postOrder(T->lchild);
postOrder(T->rchild);
Visit(T);
}
/*====================================================
二叉树的非递归遍历(先,中,后)
=====================================================*/
/*----------- 前序非递归遍历实现 -----------------*/
//二叉树的非递归前序遍历的思路:访问T->data后,将T入栈,遍历左子树;
//遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
void preTraverse(BiTree T){
BiTree P = T; //工作指针(遍历指针)
SqStack S ; //工作栈,用来存放当前访问节点
InitStack(S);
//p不为空或栈不为空是循环
while(P || !isEmpty(S)){
if(P){
// P store stack
Push(S,P);
printf("%c",P->data);
P=P->lchild ;
}else{
P=Pop(S);
P= P->rchild;
}
}
}
//第二种实现方式
void preTraverse1(BiTree T){
SqStack stack ;
InitStack(stack);
Push(stack , T);
while(!isEmpty(stack)){
BiTree P = Pop(stack);
printf("%c",P->data);
if(P->rchild!=NULL)Push(stack, P->rchild);
if(P->lchild!=NULL)Push(stack,P->lchild);
}
}
/*----------- 中序非递归遍历实现 -----------------*/
//主要思想:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
//先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
void InTraverse(BiTree T){
BiTree P = T ; //工作指针
SqStack S ; //工作栈,用来存放当前访问节点
InitStack(S); //初始化栈
while(P || !isEmpty(S)){
if(P){
Push(S,P);
P=P->lchild ;
}else{
P=Pop(S);
printf("%c",P->data);
P=P->rchild;
}
}
}
/*----------- 后序非递归遍历实现 -----------------*/
//visiting occurs only when current has no right child or last visited is his right child
//后序非递归遍历是最难的一个遍历方式,但是我们可以从遍历的特点可以看出来,最先访问的节点最后遍历,因此符合栈的特点
void PostTraverse(BiTree T){
BiTree root = T ;
SqStack S1,S2; //辅助栈,S1用来存储树入栈,S2用来存储后序遍历序列
//初始化
InitStack(S1);
InitStack(S2) ;
Push(S1,root); //1.首先根节点入栈
while(!isEmpty(S1)){ //当栈S1不为空时:1.先S1出栈 2.将从S1出栈的栈顶元素入栈S2
BiTree P=Pop(S1);
Push(S2,P);
if(P->lchild !=NULL) Push(S1,P->lchild);
if(P->rchild !=NULL) Push(S1,P->rchild) ;
}
while(!isEmpty(S2)){
printf("%c",(*(--S2.top))->data);
}
}
/*--------1.(先序)统计二叉树的叶子个数----------------*/
int CountLeaf(BiTree T ,int &count){
if(T){
if((!T->lchild)&&(!T->rchild))
count++ ;
CountLeaf(T->lchild,count);
CountLeaf(T->rchild,count);
}
return count ;
}
/*--------------2.(后序)二叉树的深度---------------*/
int TreeHight(BiTree T){
int height = 0;
if(!T) return 0 ;
else{
int leftHeight = TreeHight(T->lchild);
int rightHeight = TreeHight(T->rchild);
return 1+(leftHeight>rightHeight?leftHeight:rightHeight);
}
}
//按树状打印二叉树
void PrintTree(BiTree T,int nlayer){
if(T==NULL){
return ;
}
PrintTree(T->rchild,nlayer+1);
for(int i=0;i<nlayer;i++){
printf(" ");
}
printf("%c \n",T->data);
PrintTree(T->lchild,nlayer+1);
}
/*--------------3.(后序)二叉树的复制---------------*/
void main(){
BiTree T ;
if(BiTreeEmpty(T)){
printf("Tree is NULL\n");
}
CreateBiTree(T);
if(BiTreeEmpty(T)){
printf("Tree is not NULL\n");
}
printf("root is =%c\n",Root(T));
printf("c is parent =%c",Parent(T,'c'));
/*++++++++++先序遍历++++++++++++*/
printf("先序递归遍历如下\n");
preOrder(T);
printf("\n");
printf("先序非递归遍历\n");
preTraverse(T);
printf("\n");
printf("第二种方式的先序非递归\n");
preTraverse1(T) ;
printf("\n");
/*+++++++中序遍历+++++++++*/
printf("中序递归遍历如下\n");
inOrder(T);
printf("\n");
printf("中序非遍历如下\n");
InTraverse(T);
printf("\n");
/*++++++后序遍历+++++++++++++*/
printf("后序递归遍历如下\n");
postOrder(T);
printf("\n");
printf("后序非递归遍历如下\n");
PostTraverse(T);
printf("\n");
/*++++++++++++++++++++++++++++*/
/*-----------应用-------------*/
int count =0 ;
CountLeaf(T,count) ;
printf("二叉树的叶子个数为=%d\n",count);
printf("二叉树的深度为:%d\n",TreeHight(T));
int nlayer = 1 ;
PrintTree(T,nlayer);
}
二叉树的遍历(前序+中序+后序)
最新推荐文章于 2024-06-21 12:58:27 发布