二叉树的递归实现(前序,中序,后序,层序,高度,叶子节点数,第k层节点数)
2017-04-12 17:45
639 查看
一:二叉树是我们学过最常用也是最基础的数据结构,要想学好二叉树
①首先要学会利用含有非法值得数组前序遍历★建立一颗二叉树;
②然后我们要会用递归的方式对这颗二叉树进行★前序,★中序,★后序的遍历打印,也要学会利用队列的先进先出的原则对着棵树进行★层序访问;
③然后我们还要知道这颗二叉树的基本信息;比如,★二叉树的总节点个数,★二叉树的叶子节点个数,★二叉树的第k层的节点个数,★二叉树的高度(深度);
二:完整代码
测试代码:
三:运行结果
后面还有二叉树的非递归实现。。。敬请关注 ——-O(∩_∩)O哈哈~
①首先要学会利用含有非法值得数组前序遍历★建立一颗二叉树;
②然后我们要会用递归的方式对这颗二叉树进行★前序,★中序,★后序的遍历打印,也要学会利用队列的先进先出的原则对着棵树进行★层序访问;
③然后我们还要知道这颗二叉树的基本信息;比如,★二叉树的总节点个数,★二叉树的叶子节点个数,★二叉树的第k层的节点个数,★二叉树的高度(深度);
二:完整代码
#include<iostream> using namespace std; #include<assert.h> #include<queue> template<class T> struct TreeNode { TreeNode( const T& data=T()) :_data(data) ,_left(NULL) ,_right(NULL) {} int _data; TreeNode<T>* _left; TreeNode<T>* _right; }; template<class T> class BinaryTree { typedef TreeNode<T> Node; public: BinaryTree()//无参构造函数 :_root(NULL) {} BinaryTree(const T* arr,int sz,const T invalid)//有参构造函数 { assert(arr); int index=0;//数组中的位置 _root=BuildTree(arr,sz,invalid,index); } BinaryTree(const BinaryTree<T>& bt)//拷贝构造 { _root=Copy(bt._root); } BinaryTree<T>& operator=(const BinaryTree<T>& bt)//赋值运算符重载1 { if (this!=&bt) { Node* tmp=Copy(bt._root);//拷贝源对象给中间变量 Free(_root);//释放本对象 _root=tmp;//将中间变量给本对象 } return *this; } //BinaryTree<T>& operator=(const BinaryTree<T>& bt)//赋值运算符重载2(现代写法) //{ // std::swap(_root,bt._root); // return *this; //} void PreOrder()//前序遍历打印(递归) { cout<<"前序打印:"; _PreOrder(_root); } void InOrder()//中序遍历打印(递归) { cout<<"中序打印:"; _InOrder(_root); } void EndOrder()//后序遍历打印(递归) { cout<<"后序打印:"; _EndOrder(_root); } void SeqOrder()//层序遍历打印 { cout<<"层序打印:"; _SeqOrder(_root); } int Szie()//二叉树节点数 { return _Szie(_root); } int Hight()//二叉树的高度 { return _Hight(_root); } int GetLeafNodeNumber()//求叶子节点数 { return _GetLeafNodeNumber(_root); } int Get_K_NodeNumber(int k)//求第k层节点数 { return _Get_K_NodeNumber(_root,k); } protected: Node* BuildTree(const T*arr,int sz,const T& invalid, int& index)//前序遍历建树 { assert(arr); if (index<sz && arr[index]!=invalid) { Node* root=new Node(arr[index]); root->_left=BuildTree(arr,sz,invalid,++index); root->_right=BuildTree(arr,sz,invalid,++index); return root; } return NULL; } Node* Copy(Node* root)//先序遍历拷贝(递归) { Node* tmp=NULL; if (root) { tmp=new Node(root->_data); tmp->_left=Copy(root->_left); tmp->_right=Copy(root->_right); } return tmp; } void Free(Node*& root)//后序遍历的方式释放树 { if (root) { Free(root->_left); Free(root->_right); delete root; root=NULL; } } void _PreOrder(Node* root)//前序遍历打印 { if (root) { cout<<root->_data<<"->"; _PreOrder(root->_left); _PreOrder(root->_right); } } void _InOrder(Node* root)//中序遍历打印 { if (root) { _InOrder(root->_left); cout<<root->_data<<"->"; _InOrder(root->_right); } } void _EndOrder(Node* root)//后续遍历打印 { if (root) { _EndOrder(root->_left); _EndOrder(root->_right); cout<<root->_data<<"->"; } } void _SeqOrder(Node* root)//层序遍历打印 { //利用队列先进先出的特点层序的打印二叉树的节点 queue<Node*> q; if (root)//首先判断树的跟目录不为空 { q.push(root);//将根目录入队列 } while (!q.empty())//当队列不为空时,此时队列中一直有元素,则继续进入循环打印 { Node* tmp=q.front(); cout<<tmp->_data<<"->"; q.pop(); if (tmp->_left) { q.push(tmp->_left); } if (tmp->_right) { q.push(tmp->_right); } } } int _Szie( Node* root)//二叉树节点数 { int count=0;//定义一个count计数器 if (NULL==root)//情况一:如果root为空,则节点数为0 { count=0; } else//情况二:root不为空 { //树的节点=左子树的节点数+右子树的节点数+1(根); count=_Szie(root->_left)+_Szie(root->_right)+1; } return count; } int _Hight(Node* root)//二叉树的高度 { if (NULL==root)//情况一:root为空 { return 0; } //情况二:root不为空,此时该树高度为左右子树中大的树高度+1(根) return _Hight(root->_left)>_Hight(root->_right)? (_Hight(root->_left)+1):(_Hight(root->_right)+1); } int _GetLeafNodeNumber(const Node* root)//二叉树的叶子节点数 { if (NULL==root)//情况一:root为空 { return 0; } if (NULL==root->_left && NULL==root->_right)//情况二:该节点左右子树都为空 { return 1; } //情况三:左右子树都不为空 return _GetLeafNodeNumber(root->_left)+_GetLeafNodeNumber(root->_right); } int _Get_K_NodeNumber(Node* root,int k)//求二叉树的第k层的 { assert(k>0); if (NULL==root) { return 0; } if (k==1) { return 1; } return _Get_K_NodeNumber(root->_left,k-1)+_Get_K_NodeNumber(root->_right,k-1); } protected: Node* _root; };
测试代码:
void Test() { /*int arr[]={1,2,'#',3,'#','#',4,5,'#',6,'#',7,'#','#',8};*/ int arr[] = {1, 2, 3, '#', '#', 4, '#' , '#', 5, 6,'#','#','#'}; int sz=sizeof(arr)/sizeof(arr[0]); BinaryTree<int> bt2(arr,sz,'#');//调用带有参数的构造函数 BinaryTree<int> bt1(bt2);//调用拷贝构造函数 BinaryTree<int> bt;//调用默认构造函数 bt=bt1;//调用赋值运算符重载 bt.PreOrder(); cout<<endl; bt.InOrder(); cout<<endl; bt.EndOrder(); cout<<endl; bt.SeqOrder(); cout<<endl; cout<<"二叉树的节点数:"<<bt.Szie()<<endl; cout<<"二叉树的叶子节点个数:"<<bt.GetLeafNodeNumber()<<endl; cout<<"二叉树的高度:"<<bt.Hight()<<endl; cout<<"二叉树第1层节点数:"<<bt.Get_K_NodeNumber(1)<<endl; cout<<"二叉树第2层节点数:"<<bt.Get_K_NodeNumber(2)<<endl; cout<<"二叉树第3层节点数:"<<bt.Get_K_NodeNumber(3)<<endl; cout<<"二叉树第4层节点数:"<<bt.Get_K_NodeNumber(4)<<endl; cout<<"二叉树第5层节点数:"<<bt.Get_K_NodeNumber(5)<<endl; } int main() { Test(); return 0; }
三:运行结果
后面还有二叉树的非递归实现。。。敬请关注 ——-O(∩_∩)O哈哈~
相关文章推荐
- 二叉树的各种操作的(递归非递归)的实现,如(递归非递归)先序后序中序层次遍历 二叉树的高度 叶子节点数,所有节点数
- c语言实现二叉树先序,中序,后序(递归),层次遍历,求叶子节点个数及树的深度,下一篇写非递归的遍历
- C语言非递归实现二叉树的先序、中序、后序、层序遍历
- 二叉树第K层叶子节点个数 -- 采用递归和非递归方法实现
- 二叉树系列(建树,前序,中序,后序,中序非递归,深度,叶子数,节点数)
- 二叉树的创建,先序、中序、后序遍历的递归实现以及层序遍历
- 二叉树的遍历(前序、中序、后序、层序),递归和非递归实现
- 二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现
- Java实现二叉树的前序、中序、后序、层序遍历(递归方法)
- java实现二叉树及(层序,先序,中序,后序,节点查找)
- 二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现(转)
- java语言实现的二叉树的各种操作(包括递归与非递归遍历二叉树,求二叉树的高度,节点总数,叶子节点等)
- Java实现二叉树的前序、中序、后序、层序遍历(非递归方法)
- Java实现二叉树的前序、中序、后序、层序遍历(非递归方法)
- 二叉树的遍历(前序,中序,后序,层序)--递归和非递归算法实现
- 二叉树先序,中序,后序、层序遍历递归和非递归实现
- 二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现
- 非递归遍历二叉树(前序,中序,后序,叶子节点的计算)
- 二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现
- 二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现