二叉树的递归和非递归
来源:互联网 发布:幕墙光污染模拟软件 编辑:程序博客网 时间:2024/04/30 00:49
二叉树的几种遍历算法
1.二叉树的前序遍历
2.二叉树的中序遍历
3.二叉树的后序遍历
4 .二叉树的后序遍历
一. 二叉树的前序遍历
前序遍历算法是判断节点是否为空,如果不为空,先访问根节点,再访问左子树,最后访问右子树;
前序的递归: 根->左子树(为空)->右子树。对于每一个子树又可以用同样的访问顺序来遍历。
void PrevOrder() { _PrevOrder(_root); cout << endl; }
具体实现:
void _PrevOrder(Node *root) { Node *cur = root; if (cur == NULL) { return ; } cout << cur->_data << " "; _PrevOrder(cur->_left); _PrevOrder(cur->_right); }
前序的非递归算法
对于任意节点cur:
1:判断根节点是否为空,空则返回
2:根节点不为空,输出节点,将根节点入栈,再看cur的左子树是否为空。
3:若cur的左子树不为空,将cur左子树置为当前节点,重复3操作。
4:若cur的左子树为空,将栈顶节点出栈,但不输出,将右子树的节点置为当前节点,看右子树是否为空。
5:不为空重复3操作
6:为空重复4操作
7:直到当前节点为NULL,且栈为空,则遍历结束。
前序
void PrevOrder_NotR() { cout << "前序非递归" << endl; return _PrevOrder_NotR(_root); cout << endl; }`void _PrevOrder_NotR(Node *root){if (root == NULL)//空树{return;}Node*cur = root;stack<Node*> s;while ( !s.empty()||cur!= NULL){//边遍历边将节点压栈while(cur){cout << cur->_data << " ";s.push(cur);//根节点入栈cur = cur->_left;}//说明此时左子树已经遍历完了,要遍历要遍历右子树if (!s.empty()){cur = s.top();//取栈顶元素s.pop();//出栈cur = cur->_right;}}cout << endl;}
二:二叉树的中序遍历****
二叉树的中序遍历算法:先访问左子树,再访问根节点,最后访问右子树。
中序:
void InOrder(){_InOrder(_root);cout << endl;}
实现:
void _InOrder(Node *root) { Node *cur = root; if (cur == NULL) { return; } _InOrder(cur->_left); cout << cur->_data << " "; _InOrder(cur->_right); }
中序的非递归算法:
对于任意节点cur:
1:cur是否为空若为空返回。
2:cur不为空,判断cur的左子树是否为空,若不为空,将cur入栈,将cur的左子树置为当前节点。并对当前节点进行相同操作。
3:cur的左子树为空,输出cur,并将cur的右子树当前节点,看是否为空。
4:不为空重复2和3操作。
5:为空,则执行出栈操作,输出栈顶结点,并将右孩子置为当前节点,看是否为空重复3和4操作。
6:直到当前节点P为NULL并且栈为空,则遍历结束
非递归的实现:
void _InOrder_NotR(Node*root) { Node*cur = root; if (cur == NULL) { return; } stack<Node *> s; while (cur!= NULL||!s.empty()) { //一直遍历到左子树的最下面 while (cur) { s.push(cur); cur = cur->_left; } //说明左子树已经遍历完了;这时需要出栈 if (!s.empty()) { cur = s.top(); s.pop(); cout << cur->_data << " "; //遍历右子树 cur = cur->_right; } } cout << endl; }
三:二叉树的后序遍历:
后序遍历算法:根节点->右子树->左子树
后序的递归:
void PosOrder() { _PosOrder(_root); cout << endl; }
实现:
void _PosOrder(Node *root) { Node *cur = root; if (cur == NULL) { return; } _PosOrder(cur->_right); cout << cur->_data << " "; _PosOrder(cur->_left); }
后序的非递归算法:
对于任意节点cur:
1:cur是否为空若为空返回。
2:cur不为空,判断cur的右子树是否为空,若不为空,将cur入栈,将cur的右子树置为当前节点。并对当前节点进行相同操作。
3:cur的右子树为空,输出cur,并将cur的左子树当前节点,看是否为空。
4:不为空重复2和3操作。
5:为空,则执行出栈操作,输出栈顶结点,并将左孩子置为当前节点,看是否为空重复3和4操作。
6:直到当前节点P为NULL并且栈为空,则遍历结束
非递归的实现:
//后序非递归 void _PosOrder_NotR(Node*root) { Node*cur = root; if (cur == NULL)//空树 { return; } stack<Node*>s; while (!s.empty() || cur!=NULL) { //一直遍历右子树的最下面,边遍历边将节点压栈 while (cur) { s.push(cur); cur=cur->_right; } if (!s.empty()) { //右子树已经遍历完了, cur = s.top(); s.pop(); cout << cur->_data << " "; //遍历左子树 cur = cur->_left; } } cout << endl; }
四:二叉树的层序遍历:
我们可以利用队的先进先出的性质,具体实现是,先遍历当前层,入队,然后遍历下一层。置到结束:
实现:
void _LevelOeder(Node *root) { queue<Node *> q; if (root == NULL) { return; } if (root) { q.push(root);//把根节点入队 } while (!q.empty()) { Node*front = q.front(); cout << front->_data << " "; q.pop(); if (front->_left) q.push(front->_left);//左子树入队 if (front->_right) q.push(front->_right);//右子树入队 } cout << endl; }
五:实现及其测试函数:
.h文件
#pragma once#include<queue>#include<stack>#include<assert.h>using namespace std;template<class T>struct BinaryTreeNode{ T _data;//数据 BinaryTreeNode<T>* _left;//左节点 BinaryTreeNode<T>* _right;//右节点 BinaryTreeNode(const T&x =T()) :_data(x) , _left(NULL) , _right(NULL) {}};template<class T>class BinaryTree{ typedef BinaryTreeNode<T> Node;public: BinaryTree() :_root(NULL) {} BinaryTree(const BinaryTree<T> &t) { _root = _copy(t._root); } BinaryTree<T>&operator = (BinaryTree<T> &t) { //BinaryTree<T> tmp(t._root); swap(_root, t._root); return *this; } ~BinaryTree() { _Destroy(_root); } BinaryTree(const T*a, size_t n, const T&invalued = T()) { size_t indes = 0; _root = _CreatTree(a, n, indes, invalued);//创建一个二叉树 } //数节点的个数 size_t Size() { return _Size(_root); } //深度 size_t Depth() { return _Depth(_root); } //叶子节点的个数 size_t LeftSize() { return _LeftSize(_root); } //获取k的节点 int GetkLevel(Node *root, int k) { if (root == NULL||k<1) { return 0; } if (k == 1) { return 1; } int leftGetkLevel = GetkLevel(root->_left, k - 1); int rightGetkLevel = GetkLevel(root->_right, k - 1); return (leftGetkLevel + rightGetkLevel); } //前序 void PrevOrder() { _PrevOrder(_root); cout << endl; } //前序非递归 void PrevOrder_NotR() { cout << "前序非递归" << endl; return _PrevOrder_NotR(_root); cout << endl; } //中序 void InOrder() { _InOrder(_root); cout << endl; } //中序非递归 void InOrder_NotR() { cout << "中序非递归" << endl; return _InOrder_NotR(_root); cout << endl; } //后序 void PosOrder() { _PosOrder(_root); cout << endl; } //后序非递归 void PosOrder_NotR() { cout << "后序非递归" << endl; return _PosOrder_NotR(_root); cout << endl; } //层序 void LevelOrder() { _LevelOeder(_root); cout << endl; }protected: Node*_CreatTree(const T*a, size_t n, size_t &indes, const T&invalued) { assert(a); Node* root = NULL; if (indes<n && a[indes] != invalued) { root = new Node(a[indes]);//创建根节点 root->_left = _CreatTree(a, n,++indes,invalued); root->_right= _CreatTree(a, n,++indes,invalued); } return root; } //拷贝 Node *_copy(Node *node) { Node*cur = node; Node root = NULL;// if (cur) { root = new Node(cur->_data);//创建新节点 root->_left = _copy(cur->_left);//递归调用 root->_right = _copy(cur->_right);//递归调用 } return root; } //删除 void _Destroy(Node *node) { Node* del = node; if (del) { _Destroy(del->_left); _Destroy(del->_right); delete del; del = NULL; } } //树节点的个数 size_t _Size(Node *root) { if (root == NULL) { return 0; } return _Size(root->_left) + _Size(root->_right) + 1; } //深度 size_t _Depth(Node *root) { Node *cur = root; if (cur == NULL) { return 0; } //比较左子树和右子树的大小 return 1 + (_Depth(cur->_left) > _Depth(cur->_right) ? _Depth(cur->_left) : _Depth(cur->_right)); } //叶子节点的个数 size_t _LeftSize(Node *root) { Node*cur = root; if (NULL == cur)//空树 { return 0; } if (cur->_left == NULL&&cur->_right == NULL)//只有根节点 { return 1; } return _LeftSize(cur->_left)+_LeftSize(cur->_right);//左子树与右子树的和 } //前序 void _PrevOrder(Node *root) { Node *cur = root; if (cur == NULL) { return ; } cout << cur->_data << " "; _PrevOrder(cur->_left); _PrevOrder(cur->_right); } //前序非递归 void _PrevOrder_NotR(Node *root) { if (root == NULL)//空树 { return; } Node*cur = root; stack<Node*> s; while ( !s.empty()||cur!= NULL) { //边遍历边将节点压栈 while(cur) { cout << cur->_data << " "; s.push(cur);//根节点入栈 cur = cur->_left; } //说明此时左子树已经遍历完了,要遍历要遍历右子树 if (!s.empty()) { cur = s.top();//取栈顶元素 s.pop();//出栈 cur = cur->_right; } } cout << endl; } //中序 void _InOrder(Node *root) { Node *cur = root; if (cur == NULL) { return; } _InOrder(cur->_left); cout << cur->_data << " "; _InOrder(cur->_right); } //中序非递归 void _InOrder_NotR(Node*root) { Node*cur = root; if (cur == NULL) { return; } stack<Node *> s; while (cur!= NULL||!s.empty()) { //一直遍历到左子树的最下面 while (cur) { s.push(cur); cur = cur->_left; } //说明左子树已经遍历完了;这时需要出栈 if (!s.empty()) { cur = s.top(); s.pop(); cout << cur->_data << " "; //遍历右子树 cur = cur->_right; } } cout << endl; } //后序 void _PosOrder(Node *root) { Node *cur = root; if (cur == NULL) { return; } _PosOrder(cur->_right); cout << cur->_data << " "; _PosOrder(cur->_left); } //后序非递归 void _PosOrder_NotR(Node*root) { Node*cur = root; if (cur == NULL)//空树 { return; } stack<Node*>s; while (!s.empty() || cur!=NULL) { //一直遍历右子树的最下面,边遍历边将节点压栈 while (cur) { s.push(cur); cur=cur->_right; } if (!s.empty()) { //右子树已经遍历完了, cur = s.top(); s.pop(); cout << cur->_data << " "; //遍历左子树 cur = cur->_left; } } cout << endl; } //层序 void _LevelOeder(Node *root) { queue<Node *> q; if (root == NULL) { return; } if (root) { q.push(root);//把根节点入队 } while (!q.empty()) { Node*front = q.front(); cout << front->_data << " "; q.pop(); if (front->_left) q.push(front->_left);//左子树入队 if (front->_right) q.push(front->_right);//右子树入队 } cout << endl; }protected: Node *_root;};void TestBinaryTree(){ int a1[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 }; size_t sz = sizeof(a1) / sizeof(a1[0]); BinaryTree<int> t(a1, sz, '#'); BinaryTree<int> t1; t1 = t;//调赋值运算符的重载 cout << t1.Size() << endl; cout << t1.Depth() << endl; cout << t1.LeftSize() << endl; cout << t1.LeftSize() << endl; t1.PrevOrder(); t1.InOrder(); t1.PosOrder(); t1.LevelOrder(); t1.PrevOrder_NotR(); t1.InOrder_NotR(); t1.PosOrder_NotR();}
.cpp文件
#include<iostream>#include"BinaryTree.h"using namespace std;int main(){ TestBinaryTree(); system("pause"); return 0;}
- 二叉树的递归和非递归
- 二叉树的递归和非递归
- 二叉树的递归和非递归的遍历算法
- 二叉树的前序中序后序的递归和非递归遍历
- 递归 和 非递归 遍历二叉树
- 递归和非递归遍历二叉树
- 反转二叉树--递归和非递归
- 递归和非递归遍历二叉树
- 二叉树递归和非递归遍历
- 二叉树递归和非递归遍历
- 递归和非递归遍历二叉树
- 遍历二叉树的递归和非递归算法
- 二叉树的递归和非递归遍历
- 二叉树的递归和非递归遍历
- 二叉树的遍历(递归和非递归)
- 二叉树的遍历:递归和非递归实现
- 二叉树的递归和非递归遍历
- 二叉树遍历的递归和非递归算法
- C陷阱与缺陷(五)
- kali安装sublime text 2
- VanlOS 10 RedWhale Kube coVirt 套件 --- 一套框架同时管理X86_64和aarch64容器和虚拟机
- A Low Cost JTAG Debugger for the Raspberry Pi
- Longest Substring Without Repeating Characters
- 二叉树的递归和非递归
- Markdownpad 2 破解补丁与注册机最新使用说明
- Starting up Pi/RTEMS development again, updates on the way!
- 算法笔记_070-BellmanFord算法简单介绍(Java)
- Caffe源码中Pooling Layer文件分析
- Codeforces Round #405 C. Bear and Different Names (思维)
- 10w定时任务,如何高效触发超时
- 我为什么打算开始写博客了
- printf 格式化字符串