有关二叉树的简单实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有关二叉树的简单实现相关的知识,希望对你有一定的参考价值。
#include<iostream> #include<queue> #include<stack> using namespace std; template<class T> struct BinaryTreeNode { BinaryTreeNode< T>(const T& x) :_data( x) ,_left( NULL) ,_right( NULL) {} T _data; BinaryTreeNode<T >* _left; BinaryTreeNode<T >* _right; }; template<class T> class BinaryTree { public: BinaryTree< T>() //构造函数 :_root( NULL) {} BinaryTree< T>(const T* a,size_t size) { size_t index=0; _root=_CreateTree( a,index,size ); } ~BinaryTree< T>() //析构函数 { Clear(); _root= NULL; cout<< "~BinaryTree<T>()" <<endl; //是为了析构函数的测试 } BinaryTree< T>(const BinaryTree& bt) //拷贝构造函数 { _root=_Copy( bt._root); } //BinaryTree<T>& operator=(const BinaryTree& bt) //赋值运算符重载 //{ // if(this!=&bt) // { // this->Clear(); // _root=_Copy(bt._root); // } // cout<<"BinaryTree<T> operator=()"<<endl; // return *this; //} BinaryTree<T >& operator=(BinaryTree< T> bt ) //赋值运算符重载,利用swap()函数 { swap(_root, bt._root); return *this ; } void PreOrder() //递归——前序遍历(先根遍历),顺序:根,左,右 { _PreOrder(_root); cout<<endl; } void InOrder() //递归——中序遍历,顺序:左,根,右 { _InOrder(_root); cout<<endl; } void PostOrder() //递归——后序遍历,顺序:左,右,根 { _PostOrder(_root); cout<<endl; } void LevelOrder() //递归——层次遍历,顺序:一层一层遍历 { _LevelOrder(_root); cout<<endl; } void PreOrder_Non_R() //非递归——前序遍历(先跟遍历),顺序:根,左,右 { _PreOrder_Non_R(_root); cout<<endl; } void InOrder_Non_R() //非递归——中序遍历,顺序:左,根,右 { _InOrder_Non_R(_root); cout<<endl; } void PostOrder_Non_R() //非递归——后序遍历,顺序:左,右,根 { _PostOrder_Non_R(_root); cout<<endl; } void Clear() { _Clear(_root); } int Size() //二叉树节点个数 { return _Size(_root); } int Hight() //二叉树的深度 { return _Hight(_root); } int LeafNum() { return _LeafNum(_root); } BinaryTreeNode<T >* Find(const T& x) { return _Find(_root,x ); } protected: BinaryTreeNode<T >* _CreateTree(const T* a,size_t& index,size_t size) //创建数(关键),注意所传参数和内部逻辑 { BinaryTreeNode<T >* root=NULL; if((index <size)&&( a[index ]!=‘#‘)) { root= new BinaryTreeNode <T>(a[index]); root->_left=_CreateTree( a,++index ,size); root->_right=_CreateTree( a,++index ,size); } return root; } void _PreOrder(BinaryTreeNode <T>* root) //前序遍历(递归)内部函数,顺序:根,左,右 { if(root ==NULL) return; cout<< root->_data<<" " ; _PreOrder( root->_left); _PreOrder( root->_right); } void _InOrder(BinaryTreeNode <T>* root) //中序遍历(递归)的内部函数,顺序:左,根,右 { if(root ==NULL) return; _InOrder( root->_left); cout<< root->_data<<" " ; _InOrder( root->_right); } void _PostOrder(BinaryTreeNode <T>* root) //后序遍历(递归)的内部函数,顺序:左,右,根 { if(root ==NULL) return; _PostOrder( root->_left); _PostOrder( root->_right); cout<< root->_data<<" " ; } //void _LevelOrder(BinaryTreeNode<T>* root) //层次遍历的内部函数,顺序:一层一层遍历(不能用递归,要用队列Queue,先进先出) //{ // queue<BinaryTreeNode<T>*> q; //先创建一个队列,注意创建方法 // q.push(root); //先将根节点压入队列 // while(root) // { // cout<<root->_data<<" "; //先访问根节点 // if(!q.empty()) // { // BinaryTreeNode<T>* cur=q.front(); //获得先入队的节点 // q.pop(); //将其弹出 // q.push(cur->_left); //其左节点入队 // q.push(cur->_right); //其右节点入队 // root=q.front(); // } // } //} void _LevelOrder(BinaryTreeNode <T>* root) //层次遍历的内部函数,顺序:一层一层遍历(不能用递归,要用队列Queue,先进先出) { queue<BinaryTreeNode <T>*> q; if(root ) q.push( root); while(!q.empty()) { BinaryTreeNode<T >* front=q.front(); cout<<front->_data<< " "; q.pop(); if(front->_left) q.push(front->_left); if(front->_right) q.push(front->_right); } } int _Size(BinaryTreeNode <T>* root) //二叉树的节点个数 { if(root ==NULL) return 0; return _Size(root ->_left)+_Size(root->_right)+1; //左节点数+右节点数+当前根节点 } int _Hight(BinaryTreeNode <T>* root) //二叉树的深度 { if(root ==NULL) return 0; int LeftHight=_Hight(root ->_left); int RightHight=_Hight(root ->_right); return (LeftHight>RightHight)?(LeftHight+1):(RightHight+1); //返回左子树高度和右子数高度中的最大值 } int _LeafNum(BinaryTreeNode <T>* root) //二叉树的叶子节点个数 { if(root ==NULL) return 0; if((root ->_left==NULL)&&( root->_right==NULL )) //根节点的左右节点都为空,则它是叶子节点 return 1; return _LeafNum(root ->_left)+_LeafNum(root->_right); } void _Clear(BinaryTreeNode <T>* root) //析构的内部函数(等同于后序遍历) { if(root !=NULL) { _Clear( root->_left); _Clear( root->_right); delete(root ); } } BinaryTreeNode<T >* _Copy(BinaryTreeNode< T>* root ) //等同于前序遍历 { if(root ==NULL) return NULL ; BinaryTreeNode<T >* newRoot; BinaryTreeNode<T >* cur=root; if(cur!=NULL ) { newRoot= new BinaryTreeNode <T>(cur->_data); newRoot->_left=_Copy(cur->_left); newRoot->_right=_Copy(cur->_right); } return newRoot; } void _PreOrder_Non_R(BinaryTreeNode <T>* root) //前序遍历(非递归)内部函数,顺序:根,左,右,利用栈stack { stack<BinaryTreeNode <T>*> s; if(root ) s.push( root); while(!s.empty()) { BinaryTreeNode<T >* top=s.top(); //得到栈顶元素 cout<<top->_data<< " "; //访问这个元素 s.pop(); //将栈顶元素弹出 if(top->_right) //由于栈是先入后出,而前序遍历要保证的顺序是根,左,右, s.push(top->_right); //所以根访问完后,接下来要先压右,再压左,这样才能保证左比右先出来 if(top->_left) s.push(top->_left); } } void _InOrder_Non_R(BinaryTreeNode <T>* root) //中序遍历(非递归)的内部函数,顺序:左,根,右 { stack<BinaryTreeNode <T>*> s; BinaryTreeNode<T >* cur=root; while(cur||!s.empty()) { while(cur) { s.push(cur); cur=cur->_left; //压左节点 } if(!s.empty()) { BinaryTreeNode<T >* top=s.top(); //取栈顶元素 cout<<top->_data<< " "; //访问栈顶元素 s.pop(); cur=top->_right; //对右节点的遍历 } } } void _PostOrder_Non_R(BinaryTreeNode <T>* root) //后序遍历(非递归)的内部函数,顺序:左,右,根 { stack<BinaryTreeNode <T>*> s; BinaryTreeNode<T >* cur=root; BinaryTreeNode<T >* prevVisited=NULL; while(cur||!s.empty()) { while(cur) { s.push(cur); cur=cur->_left; } BinaryTreeNode<T >* top=s.top(); if(top->_right==NULL ||top->_right==prevVisited) { cout<<top->_data<< " "; prevVisited=top; s.pop(); } else cur=top->_right; } } BinaryTreeNode<T >* _Find(BinaryTreeNode< T>* root ,const T& x) //递归查找 { if(root ==NULL) return NULL ; if(root ->_data==x) return root ; BinaryTreeNode<T >* lRet=_Find(root->_left, x); if(lRet) return lRet; return _Find(root ->_right,x); } protected: BinaryTreeNode<T >* _root; }; void test() { int array[10]={1,2,3,‘#‘ ,‘#‘,4,‘#‘,‘#‘,5,6}; //BinaryTree<int> t1; BinaryTree<int > t2(array,10); //t2.PreOrder(); //1, 2, 3, 4, 5, 6 //t2.InOrder(); //3, 2, 4, 1, 6, 5 //t2.PostOrder(); //3, 4, 2, 6, 5, 1 //t2.LevelOrder(); //1, 2, 5, 3, 4, 6 //cout<<t2.Size()<<endl; //cout<<t2.Hight()<<endl; //cout<<t2.LeafNum()<<endl; //BinaryTree<int> t3(t2); //拷贝构造函数的测试 //t3.PreOrder();以上是关于有关二叉树的简单实现的主要内容,如果未能解决你的问题,请参考以下文章
二叉树有关习题整理 144二叉树的前序遍历 100相同的树 101对称二叉树 110平衡二叉树 958二叉树的完全性检验 662二叉树的最大宽度
设一棵二叉树以二叉链表表示,试以成员函数形式编写有关二叉树的递归算法:
二叉树有关习题整理145二叉树的后序遍历 94二叉树的中序遍历 572另一棵树的子树 236二叉树的最近公共祖先 JZ36二叉搜索树与双向链表 - 牛客