二叉树的非递归遍历实现
2014-08-02 23:45
169 查看
对于上一篇文章中介绍的二叉树结构,可以考虑使用非递归的方式进行不同的遍历方式,分别为:
1> 非递归先序遍历二叉树
2> 非递归中序遍历二叉树
3> 非递归后序遍历二叉树(标记法和非标记法)
4> 按二叉树层次序遍历二叉树
具体的二叉树的创建和打印等实现,参考前一篇文章,二叉树的实现
1> 非递归先序遍历二叉树
2> 非递归中序遍历二叉树
3> 非递归后序遍历二叉树(标记法和非标记法)
4> 按二叉树层次序遍历二叉树
具体的二叉树的创建和打印等实现,参考前一篇文章,二叉树的实现
#include <iostream> #include <stack> #include <queue> typedef char DataType; typedef struct BinaryNode { DataType data; BinaryNode* lTree; BinaryNode* rTree; }BinNode, *BinTree; typedef struct markTree { BinNode* node; bool showFlag; }; // 非递归先序遍历打印二叉树 void PreShowBinaryTree(BinTree tree) { if (NULL == tree) return; std::stack<BinaryNode*> binStack; BinaryNode* ptr = tree; BinaryNode* tmp = NULL; do { while(NULL != ptr) // 处理左子树 { std::cout << " " << ptr->data; // 最先遇到的是跟结点 遇到就打印 binStack.push(ptr); ptr = ptr->lTree; } if (binStack.empty()) continue; tmp = binStack.top(); // 弹出根结点处理右子树 ptr = tmp->rTree; binStack.pop(); } while (!(binStack.empty() && NULL == ptr)); } // 非递归中序遍历打印二叉树 void InShowBinaryTree(BinTree tree) { if (NULL == tree) return; std::stack<BinNode* > binStack; BinNode* ptr = tree; BinaryNode* tmp = NULL; while(NULL != ptr || !binStack.empty()) { while(NULL != ptr) { binStack.push(ptr); ptr = ptr->lTree; } if (binStack.empty()) continue; tmp = binStack.top(); std::cout << " " << tmp->data; // 和先序打印最大的地方在于根节点的打印时间,中序在左子树遍历完成后打印根节点 binStack.pop(); ptr = tmp->rTree; } } // 非递归后序遍历打印二叉树 // 后序遍历需要根节点两次出入栈, 第一次出栈是左子树遍历完成 // 第二次出栈是右子树遍历完成,后序遍历的重点在于处理打印时机, // 需要在处理完左右子树后,才进行根节点的处理打印 showflag做 // 是否到了打印时机即右子树已经处理完的标志,动态更新 void PostShowBinaryTree(BinTree tree) { if (NULL == tree) return; std::stack<markTree> binStack; // 需要借助标记结构markTree BinNode* ptr = tree; markTree tmp; while(NULL != ptr || !binStack.empty()) { while (NULL != ptr) // 处理左子树, 每个根节点第一次入栈都showFlag初始化为false { tmp.node = ptr; tmp.showFlag = false; binStack.push(tmp); ptr = ptr->lTree; } if (binStack.empty()) continue; tmp = binStack.top(); binStack.pop(); if (!tmp.showFlag) // 需要处理根节点的时候判断是不是已经处理过右子树,若已处理直接打印,若未处理完子树先处理 { tmp.showFlag = true; binStack.push(tmp); ptr = tmp.node->rTree; } else { std::cout << " " << tmp.node->data; ptr = NULL; } } } // 非递归后序遍历打印二叉树 不做额外标记 // 遍历栈,对于访问到的每一个root节点,先入栈。 // 如果root为叶子节点,则可以直接访问它 // 如果root存在左孩子或者右孩子,但是其左孩子和右孩子 // 都已被在这之前访问过了,则同样可以直接访问该结点,否则按照后序的反序方式 // root - right - left 一次入栈 void PostShowNotMark(BinTree tree) { if (NULL == tree) return; BinTree ptr; BinTree last = NULL; // 最后一次访问过的节点, 如果是单支左子树last未当前节点的左子树,否则为当前节点的右子树 std::stack<BinNode* > binStack; binStack.push(tree); while(!binStack.empty()) { ptr = binStack.top(); if ((ptr->lTree == NULL && ptr->rTree == NULL) || (NULL != last && (last == ptr->lTree || last == ptr->rTree))) { last = ptr; binStack.pop(); std::cout << " " << ptr->data; // 判断是不是满足了可以打印需求 continue; } if (NULL != ptr->rTree) // 分别将又子树,左子树一次入栈 binStack.push(ptr->rTree); if (NULL != ptr->lTree) binStack.push(ptr->lTree); } } // 按二叉层次遍历打印二叉树 // 按层次广度优先进行搜索,队列模拟即可 void LevelShowBinaryTree(BinTree tree) { if (NULL == tree) tree; std::queue<BinNode* > binQueue; binQueue.push(tree); BinNode* ptr = NULL; while(!binQueue.empty()) { ptr = binQueue.front(); std::cout << " " << ptr->data; binQueue.pop(); if (ptr->lTree != NULL) binQueue.push(ptr->lTree); if (ptr->rTree != NULL) binQueue.push(ptr->rTree); } }
相关文章推荐
- Java实现二叉树的递归与非递归遍历
- 遍历中序C语言实现二叉树的递归遍历与非递归遍历
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- c/c++实现二叉树前序,中序和后序的递归和非递归遍历
- C++语言实现二叉树的非递归遍历
- 数据结构的C实现_二叉树的非递归遍历和层序遍历
- 二叉树的链表实现以及非递归遍历
- C语言实现二叉树的递归遍历与非递归遍历
- Java实现二叉树后序非递归遍历(好理解)
- 二叉树先序,中序,后序的非递归遍历(附java实现)
- java实现二叉树的非递归遍历
- java实现二叉树的非递归遍历
- 二叉树的非递归遍历(借鉴递归思想实现非递归遍历)
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 二叉树基本操作的递归实现(二叉树建立,先序,中序,后序,深度的递归遍历。广度优先,高度优先的非递归遍历)
- C语言实现二叉树的递归遍历与非递归遍历
- 利用通用栈实现对于二叉树的前序、中序、后序的非递归遍历
- 二叉树高度,栈实现二叉树的先序,中序,后序遍历的非递归遍历,二叉树层次遍历
- Python实现二叉树的递归和非递归遍历
- Java实现二叉树的创建、递归/非递归遍历