非递归创建二叉树 先序 中序 后序遍历
2015-11-22 17:11
441 查看
思想:用”栈”来消除递归。
主要是建立的过程,刚开始卡到了如果遇到’#’,那么在else中间出栈之后还需要读一个元素,这样在遇到连续的”#”之后,退栈并不能达到合适的位置,最后听了“巅峰”的建议,还是设置了flag,解决了问题,下面解释下建立过程的思想:1:正常情况下以先序的方式输入串。一个一个字符读取;如果第一个字符不为“#”,先将它入栈,即我们的根。
2:初始化flag = 0,如果没有读到“#”,就开辟节点,获取栈顶元素,将字符存入栈顶元素的lchild,并且将它入栈。
3:要是读到”#”,就将flag = 1;重新读取一个元素,若不为“#”,就将它存入栈顶元素的rchild,然后将flag = 0;如果读到“#”后接下来又读到”#”,那么就出栈一个元素,并且判断当前栈顶的rchild是不是刚才出栈的元素。如果是刚才出栈的元素并且栈不为空,那就说明当前栈顶元素的左右子树都已经建立完毕,那就再出一个,再判断,直到不是才说明我们的将此时根的左边才完全建立好了,要是一直出到栈为空,那就说明完全建立完毕。
下面附上代码:
#include<stdio.h> #include<stdlib.h> #include "my_stack.h" Tree creat(Head); void PreOrder(Tree,Head); void InOrder(Tree,Head); void LastOrder(Tree,Head); void LastOrder(Tree root,Head head) { Tree q = NULL; while(root || head->top != -1 ) { if(root) { push(head,root); root = root->lchild; } //每次需要先走到最左边 else { root = gettop(head); if((root->rchild == NULL )|| (root->rchild == q)) { //取栈顶判断 //如果邮孩子为空或者右孩子刚被访问过,说明上一个元素的公恩两个已经结束了,那就访问根, root = pop(head); printf("%c ",root->data); q = root; //这一步保存当前根的位置,以便下一次判断 root = NULL; //下一次直接判断 } else { root = root->rchild; //否则左边完毕就往右边走。 } } } } void InOrder(Tree root,Head head) { while(root || head->top != -1) { if(root) { push(head,root); root = root->lchild; } else { root = pop(head); printf("%c ",root->data); root = root->rchild; } } } void PreOrder(Tree root,Head head) { while(root || head->top != -1) { if(root) { printf("%c ",root->data); push(head,root); root = root->lchild; } else { root = pop(head); root = root->rchild; } } } Tree creat(Head head) { Tree p,q; Tree root = NULL; char ch; int flag = 0; ch = getchar(); if(ch == '#') { return 0; } root = (Tree)malloc(sizeof(tree)); //为第一个节点申请空间并且入栈 p = root; p->data = ch; push(head,p); while(head->top != -1 || ch != '#') { ch = getchar(); if(ch == '#' && flag == 0) { //如果给右孩子填过值,那下面就走左边 flag = 1; } else if(ch == '#' && flag == 1) { //连续读到两个#,那就边判断边将右孩子和栈顶右孩子一样的出栈, //说明右边这些部分已经结束 p = pop(head); while(head->top != -1 && gettop(head)->rchild == p) { p = pop(head); } } else { q = (Tree)malloc(sizeof(tree)); q->data = ch; if(flag == 0) { //正常情况先访问左边 p = gettop(head); push(head,q); p->lchild = q; } if(flag == 1) { //要是读到'#'就来这一句。 p = gettop(head); p->rchild = q; push(head,q); flag = 0; } } } return root; } int main(int argc,char *argv[]) { Tree root = NULL; Head head = initstack(head); printf("非递归建树:\n"); root = creat(head); printf("非递归先序遍历:\n"); PreOrder(root,head); printf("\n"); printf("非递归中序遍历:\n"); InOrder(root,head); printf("\n"); printf("非递归后序遍历:\n"); LastOrder(root,head); printf("\n"); }
相关文章推荐
- mqh sendmessageA的命令
- 2015Beijing区域赛(Kejin Game-最小割)
- Jade之Plain Text
- CF#301 C:Ice Cave(简单BFS)
- C++ Vector 最大 最小值 索引 位置
- 简单工厂模式
- zzulioj 1782: 和尚特烦恼8——找零钱 (完全背包)
- android 设置锁屏壁纸
- BZOJ 2661: [BeiJing wc2012]连连看(简单费用流)
- iPhone上使用原生ViewController实现Popover
- 分布式监控系统Ganglia学习------(1)基本原理
- Objective-C学习-NSSet(集合),NSMutableSet(可变集合) NSCountSet(计数集合)
- Jade之Mixins
- 15个必须知道的chrome开发者技巧
- Objective-C:神在细节之中
- Android学习(二)
- opencv2.4.9中ann_mlp.cpp学习
- ns3 dce error
- A hard puzzle
- 手势是由基本事件构成(郭挺)