树的非递归遍历

树是递归定义的,利用递归算法遍历树实现起来比较简单,然而难的是非递归遍历。非递归遍历需要借助栈这一数据结构来完成。

首先定义树的结点和构建链表栈:

//定义树的节点
typedef struct Node
{
int data;
struct Node* lchild;
struct Node* rchild;
}Node;
//定义栈节点
typedef struct Stacknode
{
Node* tnode;
struct Stacknode* next;
}Stacknode; 
//构建栈
typedef struct Stacktree
{
struct Stacknode* top;
}Stacktree;
//初始化栈
void init_stack(Stacktree* T)
{
T->top=NULL;
}
//判断栈是否为空
int is_stack_empty(Stacktree* T)
{
if(T->top==NULL)
return 1;
return 0;
}
//获取栈顶值
Node* get_stack_topvalue(Stacktree* T)
{
if(is_stack_empty(T))
{
return (Node*)-1;
}
return T->top->tnode;
}
//进栈
void Push(Stacktree* T,Node* value)
{
if(T==NULL)
{
return ;
}
Stacknode* newnode=(Stacknode*)malloc(1*sizeof(Stacknode));
newnode->tnode=value;
newnode->next=T->top;
T->top=newnode;
}
//出栈
void Pop(Stacktree* T)
{
if(is_stack_empty(T))
{
return ;
}
Stacknode* tmp=T->top;
T->top=T->top->next;
free(tmp);
tmp=NULL;
}

创建树:

Node* create_tree()
{
int _data;
scanf("%d",&_data);
if(_data==-1)
{
return NULL;
}
Node* root=(Node*)malloc(1*sizeof(Node));
root->data=_data;
root->lchild=create_tree();
root->rchild=create_tree();
return root;
}

遍历:

1.非递归前序遍历:

思想:(1)访问结点p,并将节点p进栈。如p的左孩子不为空,这将p的左孩子置为结点p,重复(1);若p的左孩子为空,这获取栈顶值并出栈,栈顶结点的右孩子赋给p,重复(1),如栈为空且p==NULL,则遍历结束。

void pre_print(Node* root)
{
if(root)
{
Stacktree st;
init_stack(&st);
while(root!=NULL || !is_stack_empty(&st))
{
while(root!=NULL)
{
printf("%d\t",root->data);
Push(&st,root);
root=root->lchild;
}
if(!is_stack_empty(&st))
{
root=get_stack_topvalue(&st);
Pop(&st);
root=root->rchild;
}
}
printf("\n");
}
}

2.非递归中序遍历:

思想:

对于任意结点p

(1)若左孩子不为空,则将p进栈并将p的左孩子置为当前的p,然后对当前结点p进行同样处理。

(2)若左孩子为空,这访问该结点,并将栈顶元素出栈且将p置为栈顶元素的右孩子,进行(1)操作。

(3)知道p为空且栈顶元素为空时遍历结束。

void mid_print(Node* root)
{
if(root)
{
Stacktree st;
init_stack(&st);
while(root!=NULL || !is_stack_empty(&st))
{
while(root!=NULL)
{  
Push(&st,root);
root=root->lchild;
}
if(!is_stack_empty(&st))
{
root=get_stack_topvalue(&st);
Pop(&st);
printf("%d\t",root->data);
root=root->rchild;
}
}
}
}
时间: 2024-10-13 12:48:45

树的非递归遍历的相关文章

树的非递归遍历——前序、中序、后序

树的递归遍历非常简单,也是写树的遍历时最常用的写法.但是我发现自己对树的非递归遍历并不十分熟悉,所以把三种非递归遍历都写了一遍,以后看到这篇记录博客也可以帮助自己好好回想熟悉一下. Leetcode对应习题:前序,中序,后序. 相对而言,这三种非递归遍历的难度--前序 < 中序 < 后序. 对于第三种(非递归后序遍历)方法,只要稍微调整下第18~19行三个节点push的顺序,就可以实现前中后序的遍历. 树的非递归前序: 1 class Solution { 2 public: 3 vector

树的非递归遍历(中序遍历)

中序 遍历的几种情况 分析1:什么时候访问根.什么时候访问左子树.什么访问右子树 当左子树为空或者左子树已经访问完毕以后,再访问根 访问完毕根以后,再访问右子树. 分析2:非递归遍历树,访问结点时,为什么是栈,而不是其他模型(比如说是队列). 先走到的后访问.后走到的先访问,显然是栈结构 分析3:结点所有路径情况 步骤1: 如果结点有左子树,该结点入栈: 如果结点没有左子树,访问该结点: 步骤2: 如果结点有右子树,重复步骤1: 如果结点没有右子树(结点访问完毕),根据栈顶指示回退,访问栈顶元素

树的非递归遍历:一种很好的算法

栈模拟非递归算法 递归算法的本质是利用函数的调用栈进行,实际上我们可以自行使用栈来进行模拟,这样的算法空间复杂度为O(h),h为二叉树的高度. 前序遍历 首先把根节点入栈,然后在每次循环中执行以下操作: 此时栈顶元素即为当前的根节点,弹出并打印当前的根节点. 把当前根节点的右儿子和左儿子分别入栈(注意是右儿子先入栈左儿子后入栈,这样的话下次出栈的元素才是左儿子,这样才符合前序遍历的顺序要求:根节点->左儿子->右儿子). 后序遍历 因为后序遍历的顺序是:左子树->右子树->根节点,

树的递归与非递归遍历总结

树的递归遍历遍历很简单,非递归遍历要复杂一些,非递归先序.中序.后序遍历需要用一个辅助栈,而层次遍历则需要一个辅助队列. 树的结构: 1 public class Tree<T> { 2 private T data; 3 private Tree<T> left; 4 private Tree<T> right; 5 ... 6 } 用策略模式定义一个访问工具: 1 public interface Visitor<T> { 2 void process(

[转] 树的递归与非递归遍历

1 public class Tree<T> { 2 private T data; 3 private Tree<T> left; 4 private Tree<T> right; 5 6 private Tree(T data) { 7 this.data = data; 8 9 } 10 11 public Tree(T[] datas) { 12 makeTree(datas, this); 13 } 14 15 public interface Visitor

(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树

写了一点haffman树的创建和二叉树的非递归遍历. 如果编写代码的时候出现了,思维断点,可以借鉴一下, 避免浪费一些不必要的时间. 我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占 位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我 是占位符我是占位符我是占位符我是占位符我是占位符我是 占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符

二叉树的非递归遍历--京东2015笔试回忆

题目回忆: C/C++研发试卷:偏重于数据结构的考察,编程题有2题+1题附加题: 1.输入整数n,求m,m>9,m中各个数位的乘积=n的最小整数;如n=36,m=49; 2.二叉树前序遍历的非递归实现(本文的总结) 3.求第n个数,这个序列满足(2^i)*(3^j)*(5^k),前7个为:2,3,4,5,6,8,10 .... 小题有基本的数据结构.程序运行结果.SQL题目. 4.删除表格用DROP命令,死锁产生的条件: 4.1互斥使用(资源独占) 一个资源每次只能给一个进程使用 4.2.不可强

史上最简明易懂非递归遍历二叉树算法

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 遍历二叉树的递归函数是体现了算法之美的高妙算法,思路清晰,代码简洁,读之赏心悦目.代码例如以下: 程序代码: void PreOrderTraverse_R(BiTree BT)//採用递归方式先序遍历二叉树BT { if(BT != NULL) { printf("%c", BT->data);//输出该结点(根结点) PreOrderTraverse_R(BT->lchi

数据结构二叉树——建立二叉树、中序递归遍历、非递归遍历、层次遍历

数据结构二叉树-- 编写函数实现:建立二叉树.中序递归遍历.借助栈实现中序非递归遍历.借助队列实现层次遍历.求高度.结点数.叶子数及交换左右子树. ("."表示空子树) #include<stdio.h> #include<stdlib.h> //***********二叉树链表节点结构 typedef char DataType; typedef struct Node {  DataType data;  struct Node*LChild;  struc