首页 > 编程知识 正文

二叉树的先序,中序,后序遍历(非递归算法),二叉树的非递归中序遍历

时间:2023-05-06 03:54:15 阅读:266866 作者:3381

目录

节点定义 

二叉树

前序遍历

递归

 非递归

中序遍历

递归

非递归

后序遍历

递归

非递归1

非递归2

非递归3

非递归4

层序遍历

序列相同的二叉树


节点定义  template<typename T>class TreeNode {public: T data; TreeNode<T>* left, * right; TreeNode() :left(nullptr), right(nullptr) {} TreeNode(const T& data) :data(data), left(nullptr), right(nullptr) {}}; 二叉树 #include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<string>using namespace std;template<typename T>class BinaryTree {private: TreeNode<T>* root; void destroy(TreeNode<T>**); void pre_order_traversal(TreeNode<T>*)const; void in_order_traversal(TreeNode<T>*)const; void post_order_traversal(TreeNode<T>*)const ;public: BinaryTree(); void pre_order_traversal()const; void pre_order_traversal_non_recursive()const; void in_order_traversal()const; void in_order_traversal_non_recursive()const; void post_order_traversal()const; void post_order_traversal_non_recursive()const; void post_order_traversal_non_recursive2()const; void post_order_traversal_non_recursive3()const; void post_order_traversal_non_recursive4()const; void level_order_traversal()const;}; 前序遍历 递归 /** * 前序遍历 */template<typename T>void BinaryTree<T>::pre_order_traversal()const{ if (this->root != nullptr) { pre_order_traversal(this->root); } cout << endl;}  非递归 /** * 非递归前序遍历 */template<typename T>void BinaryTree<T>::pre_order_traversal_non_recursive()const{ stack<TreeNode<T>*> s; TreeNode<T>* p = this->root; while (p != nullptr || !s.empty()) { //一直向左子树访问 while (p) { cout << p->data << ' '; if (p->right != nullptr) { //存储右子树 s.push(p->right); } p = p->left; } if (!s.empty()) { //右子树 p = s.top(); s.pop(); } } cout << endl;} 中序遍历 递归 /** * 中序遍历 */template<typename T>void BinaryTree<T>::in_order_traversal()const{ if (this->root != nullptr) { in_order_traversal(this->root); } cout << endl;} 非递归 /** * 非递归中序遍历 */template<typename T>void BinaryTree<T>::in_order_traversal_non_recursive()const{ stack<TreeNode<T>*> s; TreeNode<T>* p = this->root; while (p != nullptr || !s.empty()) { //压入当前节点 while (p != nullptr) { s.push(p); p = p->left; } //左子树已经访问完了,开始访问根 if (!s.empty()) { p = s.top(); s.pop(); cout << p->data << ' '; //右子树 p = p->right; } } cout << endl;} 后序遍历 递归 /** * 后序遍历 */template<typename T>void BinaryTree<T>::post_order_traversal()const{ if (this->root != nullptr) { post_order_traversal(this->root); } cout << endl;} 非递归1 /** * 非递归后序遍历 */template<typename T>void BinaryTree<T>::post_order_traversal_non_recursive()const{ stack<TreeNode<T>*> s; TreeNode<T>* p = this->root, *pre = nullptr; while (p != nullptr || !s.empty()) { //压入当前节点 while (p!=nullptr) { s.push(p); p = p->left; } p = s.top(); //如果没有右子树或者右子树已经访问过了,那么就可以访问根节点 if (p->right == nullptr || p->right == pre) { cout << p->data << ' '; pre = p; s.pop(); p = nullptr; } else { //访问右子树 p = p->right; } } cout << endl;} 非递归2 /** * 非递归后序遍历 */template<typename T>void BinaryTree<T>::post_order_traversal_non_recursive2()const{ stack<TreeNode<T>*> s; TreeNode<T>* p = this->root, * pre = nullptr; if (p == nullptr)return; s.push(p); while (!s.empty()) { p = s.top(); //没有左子树和右子树,或者上次访问的的节点是左子树或右子树 if ((p->left == nullptr && p->right == nullptr) || ((p->left == pre || p->right == pre) && pre != nullptr)) { cout << p->data << ' '; pre = p; s.pop(); } else { //先压入右子树,再压入左子树,这样取的时候是反过来的 if (p->right != nullptr) { s.push(p->right); } if (p->left != nullptr) { s.push(p->left); } } } cout << endl;} 非递归3 /** * 非递归后序遍历 */template<typename T>void BinaryTree<T>::post_order_traversal_non_recursive3()const{ stack<TreeNode<T>*> s; TreeNode<T>* p = this->root, *pre = nullptr; //一直往左子树访问 while (p != nullptr) { s.push(p); p = p->left; } while (!s.empty()) { p = s.top(); //如果右子树为空或者访问过,则可以访问根 if (p->right == nullptr || p->right == pre) { cout << p->data << ' '; s.pop(); pre = p; } else { //访问右子树 p = p->right; //一直往左子树访问 while (p) { s.push(p); p = p->left; } } } cout << endl;} 非递归4 /** * 非递归后序遍历 */template<typename T>void BinaryTree<T>::post_order_traversal_non_recursive4()const{ stack<TreeNode<T>*> s; //当前节点的右子树是否访问过的栈 stack<bool> visited; bool flag; TreeNode<T>* p = this->root; while (p != nullptr || !s.empty()) { //一直往左子树访问 while (p) { s.push(p); //还没有访问过右子树 visited.push(false); p = p->left; } p = s.top(); flag = visited.top(); //右子树为空或访问过了 if (p->right == nullptr || flag) { cout << p->data << ' '; s.pop(); visited.pop(); p = nullptr; } else { p = p->right; visited.pop(); //访问过右子树 visited.push(true); } } cout << endl;} 层序遍历 /** * 层序遍历 */template<typename T>void BinaryTree<T>::level_order_traversal()const{ queue<TreeNode<T>*> q; if (this->root != nullptr) { q.push(this->root); } TreeNode<T>* p; while (!q.empty()) { p = q.front(); q.pop(); cout << p->data << ' '; if (p->left != nullptr) { q.push(p->left); } if (p->right != nullptr) { q.push(p->right); } } cout << endl;} 序列相同的二叉树

 

前序遍历和后序遍历相同的二叉树

TLR

LRT

显然只有根节点

 

前序遍历和中序遍历相同的二叉树

TLR

LTR

---去掉L----->

TR

显然:非叶子结点只有右子树的二叉树

 

中序遍历和后序遍历相同的二叉树

LTR

LRT

---去掉R----->

LT

显然:非叶子结点只有左子树的二叉树

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。