二叉树的创建与前中后序遍历递归非递归
来源:互联网 发布:淘宝上网上如何注册? 编辑:程序博客网 时间:2024/04/30 00:04
树的定义是递归的所以二叉树的定义也是递归的,一般先定义它的根节点在定义它的左子树再定义它的右子树,就像先序遍历一样
struct Node{ Node(T data = T()) :_data(data) ,_lChild(NULL) ,_rChild(NULL) {} T _data; Node* _lChild; Node* _rChild;};
void CreateBinTreePreOrder(Node<T>*& root, const T array[], const size_t size, size_t& i, const T invalue) { if (i < size && array[i] != invalue) { root = new Node<T>(array[i]); CreateBinTreePreOrder(root->_lChild, array, size, ++i, invalue); CreateBinTreePreOrder(root->_rChild, array, size, ++i, invalue); } }
二叉树的先序遍历规则先访问根节点,先按照先序遍历的规则访问左子树,之后按照先序遍历的规则访问右子树
递归算法的代码很简单但是并不是很好理解比如对下面这个二叉树的递归先序遍历
void PreOrderTraverse(const Node<T>* root) { if (NULL == root) { return; } cout << root->_data << " "; PreOrderTraverse(root->_lChild); PreOrderTraverse(root->_rChild); }
二叉树的非递归先序遍历需要一个栈来辅助实现分三步实现
用指针p指向根节点并访问根节点将其入栈
p指向他的左子树并且档期不为空时访问它并入栈
当p为空时p指向它的右子树
void PreOrder() { if (_root != NULL) { stack<Node<T>*> s; Node<T>* p = _root; while (p != NULL || !s.empty()) { while (NULL != p) { cout << p->_data << " "; s.push(p); p = p->_lChild; } if (!s.empty()) { p = s.top(); p = p->_rChild;; s.pop(); } } } cout << endl; }
中序遍历二叉树递归
void InsOrderTraverse(const Node<T>* root) { if (NULL == root) { return; } InsOrderTraverse(root->_lChild); cout << root->_data << " "; InsOrderTraverse(root->_rChild); }
中序遍历非递归
非递归中序遍历二叉树的思想和先序遍历的方法差别不大区别在于先序遍历是在入栈是访问节点中序遍历是在出栈时访问节点
void InOrder() { if (_root != NULL) { Node<T>* p = _root; stack<Node<T>*> s; while (p != NULL || !s.empty()) { while (p) { s.push(p); p = p->_lChild; } if (!s.empty()) { p = s.top(); cout << p->_data << " "; p = p->_rChild; s.pop(); } } cout << endl; } }
后序遍历二叉树
递归
void PosOrderTraverse(const Node<T>* root) { if (NULL == root) { return; } PosOrderTraverse(root->_lChild); PosOrderTraverse(root->_rChild); cout << root->_data << " "; }
非递归后序遍历二叉树的难点在于当这个节点在第二次出现在栈顶是才访问它
非递归后序遍历二叉树有两种方法
第一种设置一个标志表示这个节点是第几次出现在栈顶如果是第二次则访问他
struct BinNode { BinNode(Node<T>* p) :root(p) ,IsFirst(true) {} Node<T>* root; bool IsFirst; };void PosOrder() { if (_root != NULL) { stack<BinNode*> s; Node<T>* p = _root; BinNode* tmp; while (p != NULL || !s.empty()) { while (NULL != p) { BinNode* pNewNode = new BinNode(p); s.push(pNewNode); p = p->_lChild; } if (!s.empty()) { tmp = s.top(); s.pop(); if (tmp->IsFirst) { tmp->IsFirst = false; s.push(tmp); p = tmp->root->_rChild; } else { cout << tmp->root->_data << " "; p = NULL; } } } } cout << endl; }
第二种方法是指针pCur从根节点开始一直将其左孩子一次入栈直到最左边的节点,此时如果栈顶元素没有右孩子访问该节点否则比较前一节点pPre与当前节点的右孩子的如果相等就访问该节点不相等pCur=pCur->rChild
void PosOrder1() { if (_root) { stack<Node<T>*> s; Node<T>* pCur = _root; Node<T>* pPre = NULL; while (pCur || !s.empty()) { while (pCur) { s.push(pCur); pCur = pCur->_lChild; } pCur = s.top(); if (pCur->_rChild == NULL || pPre == pCur->_rChild) { cout << pCur->_data << ' '; s.pop(); pPre = pCur; pCur = NULL; } else { pCur = pCur->_rChild; } } cout << endl; } }
1 0
- 二叉树的创建与前中后序遍历递归非递归
- 二叉树的创建遍历-递归与非递归
- 二叉树的创建和递归与非递归遍历
- 二叉树的前中后序递归与非递归遍历
- 二叉树的创建,递归遍历,非递归遍历
- 二叉树的创建,递归遍历以及非递归遍历
- 二叉树的创建|非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 数据结构与算法学习记录--二叉树的创建,递归遍历,非递归遍历的实现
- 二叉树的常用操作(创建、先中后序递归与非递归遍历、层序遍历)
- 二叉树的创建--(3)遍历二叉树(递归与非递归、Level)
- Python单引号、双引号和三双引号的区别
- spring——依赖注入DI(main函数方式)
- 如何写出正确CUDA程序(持续更新中)
- HAUTOJ 1264 某科学家的打麻将 dp
- Nginx配置基础-内置变量
- 二叉树的创建与前中后序遍历递归非递归
- c++ 数据结构 二叉树前序、中序、后序遍历相互求法
- 搜索练习11/hdu/problem2612 Find a way/ bfs模板
- MongoDB干货篇之查询
- Maven入门
- MongoDB干货篇之查询
- 动态规划—钢条切割问题
- 32位架构应用转64位架构小结
- .gitignore