二叉树非递归遍历(堆栈)——C语言
二叉树非递归遍历(堆栈)——C语言
二叉树遍历根据输出根节点数据次序的不同,分为先序、中序、后序三种。用递归的方式可以很容易实现。
先序是在第一次遇到节点时就输出,中序是访问完左子树后回退时输出,后序是访问完右子树后回退时输出。
而非递归的方式,则是通过堆栈实现。
#include
#include
typedef struct TreeNode *BinTree;
struct TreeNode{
int data;
BinTree lef;
BinTree rig;
};
typedef struct Node *Stack;
struct Node{
/* 堆栈的本质是一种链表关系, 通过对ElemType的灵活定义,
可以将这种关系拓展到其他数据结构元上, 如: 此处的二叉树结点
而这里的变量名tNode, last可固定化, 故通过模板(害没学..)可实现高效的堆栈复用 */
BinTree tNode;
Stack last;
};
Stack CreateStack(){
Stack s = (Stack)malloc(sizeof(Node));
s->tNode = NULL;
s->last = NULL;
return s;
}
BinTree CreateBT(){
BinTree t = (BinTree)malloc(sizeof(TreeNode));
t->rig = NULL;
t->lef = NULL;
return t;
}
void Push(Stack s, BinTree t){
Stack tmpNode = CreateStack();
tmpNode->tNode = t;
tmpNode->last = s->last;
s->last = tmpNode;
}
BinTree Pop(Stack s){
BinTree t;
Stack tmpNode;
tmpNode = s->last;
t = tmpNode->tNode;
s->last = tmpNode->last;
free(tmpNode);
return t;
}
void InOrderTraversal(BinTree tree)
{
BinTree t = tree;
Stack s = CreateStack();
BinTree visitedNode = NULL;
while(t || (s->last!=NULL))
// t isnt empty means we have not reached the end
// s isnt empty means we have not reached the top
{
while(t!=NULL){
Push(s, t);
// printf("%d", t->data);
// 先序遍历在第一次访问根节点(深挖)时输出
t = t->lef;
}
if (s->last!=NULL){
t = Pop(s);
// printf("%d", t->data);
// 中序遍历在第二次访问根节点(深挖后第一次回退)时输出
// t = t->rig;
// 后序时注释掉上行
if (!(t->rig) || (t->rig == visitedNode)){
printf("%d", t->data);
t = NULL;
}
else{
Push(s, t);
visitedNode = t->rig;
t = t->rig;
}
// 后序遍历逻辑较为复杂一点,访问完左子树后,需要访问右子树,故要将
// 出的栈再压回去,而此逻辑又将造成死循环,程序卡在右子树内(若右子树不空),
// 故引入visitedNode先记录根结点的右结点,再进行访问,这样右子结点出栈后再次遇
// 到根节点时,只需进行一次判断即可跳出死循环逻辑。
// 还有一种做法是在每个树结点内,引入状态变量记录是否访问过,
// 本质与此方法一样,但空间开销增加。
// 还有另一种截然不同的做法是,使用双栈,考虑先序输出:根->左->右,后序输出:左->右->根
// 可将二叉树左右结点互换后,先序输出并依序压栈,再依序出栈,即为后序遍历
}
}
}
int main(){
BinTree t = CreateBT();
t->data = 1;
t->lef = CreateBT();
t->lef->data = 2;
t->lef->lef = CreateBT();
t->lef->lef->data = 3;
t->lef->rig = CreateBT();
t->lef->rig->data = 4;
t->lef->rig->lef = CreateBT();
t->lef->rig->lef->data = 5;
InOrderTraversal(t);
system("pause");
return 0;
}
二叉树非递归遍历(堆栈)——C语言相关教程
LeetCode——235. 二叉搜索树的最近公共祖先
LeetCode——235. 二叉搜索树的最近公共祖先 根据二叉搜索树的性质查找节点,二叉搜索树,左子树的值小于根节点,右子树的值大于根节点,每棵树都符合这种规则,我们可以从上往下去遍历寻找,当节点的值比两个给的节点的值都大的时候,就往左子树上寻找,都小
递归 八皇后问题的一些思考
递归 八皇后问题的一些思考 大家觉得写还可以,可以 点赞、收藏、关注 一下吧! 也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn 如何设计一种方案。在一个无穷大的国际棋盘的每一行每一列里都放置一个皇后,
leetcode-669. 修剪二叉搜索树
leetcode-669. 修剪二叉搜索树 修剪二叉搜索树 给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。 示例 1: 输入:
什么叫递归
递归: 1、要调用自己本身; 2、要有一个趋于终止的条件。 (推荐教程:java课程) 下面以一个求阶乘的例子简单介绍一下: public class recursion { public static int fac(int n) { if(n == 1){ return 1; //终止条件 } return n * fac(n-1); //调用自身 }
递归原来可以so easy|-连载(2)
递归原来可以so easy|-连载(2) 一个简单的例子 下面用一个简单的例子来演示递进和回归。 public class Hello { static int s=1; static void rd(int n){ System.out.format(%d 递进,n:%d\n,s++,n); if(n==1) return; else{ rd(n-1); System.out.format(%d
递归原来可以so easy|-连载(1)
递归原来可以so easy|-连载(1) 引子 从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚
【树】---- 二叉树
【树】---- 二叉树 1 树的基本概念 (1)树是由若干结点组成的具有层次关系的集合,非空树有且只有一个根结点(/)。 (2)某个结点及其下面所有的结点并称为以该结点为根的子树(usr及其下的所有结点就是/的一颗子树,usr是该子树的根)。 (3)结点拥有的子
leetcode 102 剑指Offer 32 二叉树的层次遍历
leetcode 102 剑指Offer 32 二叉树的层次遍历 思路不难,直接用队列迭代就可以。 遍历过程如下: 代码如下: public class offer32 { public ListListInteger levelOrder(TreeNode root) { ListListInteger ans = new LinkedList(); DequeTreeNode deque = ne