二叉树的遍历(前序+中序+后序)
来源:互联网 发布:最新在线报名系统源码 编辑:程序博客网 时间:2024/06/16 18:04
#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;elsereturn 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 stackPush(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出栈的栈顶元素入栈S2BiTree 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);}
0 0
- 二叉树的遍历(前、中、后序)
- 二叉树的遍历(前序遍历、中序遍历、后序遍历)
- 二叉树的前序遍历,中序遍历和后序遍历(c#)
- 二叉树的遍历,二叉树的创建、前序遍历、中序遍历、后序遍历 (转)
- 二叉树的前序、中序、后序遍历
- 二叉树的遍历(前序,中序,后序)
- 二叉树的遍历:前序、中序、后序
- 二叉树的前序、中序、后序遍历
- 二叉树的前序、中序、后序遍历
- 二叉树的前序,中序,后序遍历
- 二叉树的前序、中序、后序遍历
- 二叉树的前序,中序,后序遍历
- 二叉树的前序、中序、后序遍历
- 二叉树的前序、中序、后序遍历
- 二叉树的前序、中序、后序遍历
- 二叉树的前序,中序,后序遍历
- 二叉树的前序,中序,后序遍历
- 二叉树的前序、中序、后序遍历
- 软考总计之白盒测试中的覆盖
- cc1plus.exe: out of memory allocating 3355443200 bytes
- [Java]交换排序
- 【AOP】借助容器将服务与代理类分离
- leetcode Maximum Gap
- 二叉树的遍历(前序+中序+后序)
- 使用Ibatis操作MySQL数据库
- Andriod SDK出现Failed to parse the output of 'adb version'问题
- leetcode 11 -- Container With Most Water
- USACO--3.3A Game+dp
- 我的Cocos2d-x学习笔记(十)定时调度器(scheduleUpdate、scheduleOnce、schedule)
- 《C Primer Plus(第5版)中文版》第7章编程练习第8题
- html+css注意事项
- 大二学生一枚 写下自己学51和PCB的感想 与各位刚开始学习的盆友共勉 一起加油