用栈实现二叉树的遍历(非递归)
来源:互联网 发布:黎活明 java 编辑:程序博客网 时间:2024/06/05 18:45
先实现栈
#include <stdio.h>
#include <stdlib.h>#include <string.h>
typedef char ElemType;
#define STACKSIZE 20
typedef struct st
{
ElemType *data;
int top;
int MaxSize;
}stack;
void Init_stack(stack *p);//初始化栈
bool Is_Empty(stack *p);//判断是否为空栈
bool Is_Full(stack *p);//判断栈是否为满栈
int GetLength(stack *p);//获取栈内元素个数
bool push(stack *p, ElemType value);//入栈
ElemType top(stack *p);//弹出栈顶元素
ElemType pop(stack *p);//出栈
void show_stack(stack *p);//展示栈内元素
void Init_stack(stack *p)
{
if (p == NULL)
return;
p->top = -1;
p->MaxSize = STACKSIZE;
p->data = (ElemType *)malloc(sizeof(ElemType)*p->MaxSize);
memset(p->data, 0, sizeof(ElemType)*p->MaxSize);
}
bool Is_Empty(stack *p)
{
if (p->top = -1 || p == NULL)
{
return true;
}
return false;
}
bool Is_Full(stack *p)
{
if (p->top + 1 == p->MaxSize || p == NULL)
{
return true;
}
return false;
}
int GetLength(stack *p)
{
return p->top+1;
}
bool push(stack *p, ElemType value)
{
bool res = false;
if (!Is_Full(p))
{
p->data[++p->top] = value;
res = true;
}
return res;
}
//出栈操作分为两步,是为了保证出栈精确
ElemType top(stack *p)
{
if ( p != NULL )
{
return p->data[p->top];}
}
ElemType pop(stack *p)
{
if (p->top >= 0 && p != NULL)
{
p->top--;
}
}
void show_stack(stack *p)
{
int count = p->top;
while (count != -1)
{
printf("%c ", p->data[count]);
count--;
}
}
假设二叉树的结构为:
则其前序遍历为:ABCDEFGH. 中序遍历为:CBEDFAGH . 后序遍历为:CEFDBHGA
用栈实现中序遍历的思想:让二叉树左-中-右遍历,若不为空则入栈,若为空出栈
过程如下所示:
将其转化为代码,如下:
void NiceInOrder ( BtNode *ptr )
{
if ( NULL == ptr ) return ;
stack st;
Init_Stack ( &st ) ;
while ( ptr !=NULL || ! Is_empty ( &st ) )
{
while ( ptr !=NULL )
{
push ( & st , ptr -> data ) ;
ptr = ptr -> LiftChild ;
}
ptr = top ( &st ) ; pop( &st ) ; // 遇到空直接出栈
printf ( " %c ", ptr -> data ) ;
ptr = ptr -> RightChild ;
}
}
后序遍历思想为:每个节点都要进栈两次,第二次退栈是才访问节点。第一次进栈时,在遍历左子树的过程中将根节点进栈,待左子树访问完后,回溯的节点退栈,即退出这个根节点,但不能立即访问,只能借助于这个根去找该根的右子树,并遍历这棵右子树,直到该右子树全部遍历以后,再退出该根节点,并访问它。所以,为了记录节点是第一次还是第二次进栈,需单独定义一个节点作为标志。
代码如下:
void NicePastOrder ( BtNode *ptr )
{
if ( NULL == ptr ) return ;
stack st;
Init_Stack ( &st ) ;
BtNode *tag=NULL;
while ( ptr !=NULL || ! Is_empty ( &st ) )
{
while ( ptr !=NULL )
{
push ( & st , ptr -> data ) ;
ptr = ptr -> LiftChild ;
}
ptr = top ( &st ) ; pop( &st ) ; // 遇到空直接出栈
if ( ptr -> RightChild == NULL || ptr -> RightChild == tag )
{
printf ( "%c", ptr -> data ) ;
tag = ptr ;
ptr = NULL ;
}
else
{
push ( &st, ptr ) ;
ptr = ptr -> RightChild ;
}
}
}
前序遍历的思想:若栈不为空且ptr不为空时入栈即出栈并打印,然后将其右孩子入栈,再继续访问其左孩子;若ptr为空,则出栈。
代码如下:
void NicePerOrder ( BtNode *ptr )
{
if ( ptr == NULL ) return ;
stack st ;
Init_Stack ( &st ) ;
while ( ptr !=NULL || ! Is_Empty ( &st ) )
{
push ( &st , ptr ) ;
if ( p )
{
ptr = top ( &st ) ; pop ( &st ) ;
printf ( "%c " , ptr -> data ) ;
push ( &st , ptr -> RightChild ) ;
ptr = ptr -> LeftChild ;
}else
{
ptr = top ( &st ) ; pop ( &st ) ;
}
}
}
- 用栈实现二叉树的遍历(非递归)
- 二叉树的遍历(递归实现+非递归实现)
- 二叉树的遍历(递归,非递归)实现
- 二叉树的遍历(非递归和递归实现)
- 非递归实现二叉树的遍历
- 非递归实现二叉树的遍历
- 二叉树遍历的非递归实现
- 二叉树遍历的非递归实现
- 二叉树遍历的非递归实现
- 二叉树的非递归遍历实现
- 二叉树遍历的非递归实现
- 非递归实现二叉树的遍历
- 二叉树遍历的非递归实现
- 二叉树遍历的非递归实现
- 非递归遍历二叉树的实现
- 二叉树遍历的非递归实现
- 二叉树遍历的非递归实现
- 二叉树遍历(非递归实现--栈实现)
- 条款08:别让异常逃离析构函数
- 第二十三篇 jQuery 学习5 添加元素
- String中的字符串拼接问题
- Linux根目录的建立
- Glide调试方法
- 用栈实现二叉树的遍历(非递归)
- java服务端程序部署服务器以及压力测试过程
- 【转载】centOS6启动流程
- Fragment中再嵌套Fragment(java.lang.IllegalStateException: FragmentManager is already executing transact)
- 关于Class.getResource和ClassLoader.getResource的路径问题
- 我oracle数据库安装完了,字符集是ZHS16GBK,但是我需要一个数据库字符集是UTF8的,怎么办?。新建一个数据库实例,选择字符集为utf8即可
- 哪些地方会出现css阻塞,哪些地方会出现js阻塞?
- js中的||与&&用法
- java 4位byte转为int类型