二叉树的基本功能实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的基本功能实现相关的知识,希望对你有一定的参考价值。
二叉树的创建、非递归与递归前中后遍历、层次遍历、求节点数目、深度、叶子节点个数、查找某一节点
#include<iostream> #include<queue> #include<stack> using namespace std; template<class T> struct BinaryTreeNode { BinaryTreeNode(const T&x) :_data(x) ,_left(NULL) ,_right(NULL) {} T _data; BinaryTreeNode<T>* _left; BinaryTreeNode<T>* _right; }; template<class T> class BinaryTree { public: BinaryTree() :_root(NULL) {} BinaryTree(T* a,size_t size) { size_t index=0; _root=_CreateTree(a,index,size); } ~BinaryTree() { _Destory(_root); } void PrevOrder() { _PrevOrder(_root); cout<<endl; } void InOrder() { _InOrder(_root); cout<<endl; } void PostOrder() { _PostOrder(_root); cout<<endl; } //层次遍历---常温故//采用队,压根,访问根,删根,压左右孩子 void LevelOrder() { queue<BinaryTreeNode<T>*> q; if(_root!=NULL) q.push(_root); while(!q.empty()) { BinaryTreeNode<T>* front=q.front(); cout<<front->_data<<" "; q.pop(); if(front->_left!=NULL)//易忘 q.push(front->_left); if(front->_right!=NULL) q.push(front->_right); } cout<<endl; } //先序非递归遍历----->利用栈,先压根,访问根,删根,再分别压右孩子和左孩子,访问左右孩子,删左右孩子 void PrevOrder_Non_R() { stack<BinaryTreeNode<T>*> s; if(_root!=NULL) s.push(_root); while(!s.empty()) { BinaryTreeNode<T>* top=s.top(); cout<<top->_data<<" "; s.pop(); if(top->_right!=NULL)//top不是删去了吗,此时的top为空,还可以用top->_right??? s.push(top->_right); if(top->_left!=NULL) s.push(top->_left); } cout<<endl; } //中序非递归遍历-------->一直压左,取栈顶,前序遍历top节点(再访问最左(栈顶)的节点,删左,把当前节点的右节点作为新根cur,重复前面的一直压左) //所有的右的访问是通过子树的cur //每个节点作为子树的跟被输出 void InOrder_Non_R() { stack<BinaryTreeNode<T>*> s; BinaryTreeNode<T>* cur=_root; while(cur||!s.empty())//易忘------>每次都要判断cur是否为NULL { while(cur!=NULL) { s.push(cur); cur=cur->_left; } BinaryTreeNode<T>* top=s.top(); cout<<top->_data<<" "; s.pop(); cur=top->_right; } cout<<endl; } //后序遍历非递归--------->一直压左,访问最左,删左,把右孩子作为新根cur,一直压左,重复。。。 //关键是判断当根节点没有左右节点时,是真的没有,还是刚刚左右孩子被删了,即右孩子是进过栈还是即将进,所有引入了另一个指针标记 void PostOrder_Non_R() { stack<BinaryTreeNode<T>*> s; BinaryTreeNode<T>* cur=_root; BinaryTreeNode<T>* PrevVisited=NULL; while(cur||!s.empty()) { while(cur!=NULL) { s.push(cur); cur=cur->_left; } //已访 if(!s.empty()) { BinaryTreeNode<T>* top=s.top(); //右子树已访 if(top->_right==NULL||top->_right==PrevVisited) { cout<<top->_data<<" "; s.pop(); PrevVisited=top; //cur=top->_right; } ///右子树未访,把当前右孩子作为新根重复一直压左遍历 else { cur=top->_right; } } } cout<<endl; } void Find(const T& x) { BinaryTreeNode<T>* Ret=_Find(_root,x); if(Ret) cout<<Ret->_data<<endl; else cout<<"所找数据不存在"<<endl; } void Size() { cout<<"Size:"<<_Size(_root)<<endl; } void Hight() { cout<<"Hight:"<<_Hight(_root)<<endl; } void LeafNum() { cout<<"LeafNum:"<<_LeafNum(_root)<<endl; } protected: BinaryTreeNode<T>* _root; BinaryTreeNode<T>* _CreateTree(T* _array,size_t &index,size_t size) { if(index<size) { if(_array[index]!=‘#‘) { BinaryTreeNode<T>* root=new BinaryTreeNode<T>(_array[index++]); root->_left=_CreateTree(_array,index,size); root->_right=_CreateTree(_array,index,size); return root; } else { index++; return NULL; } } return NULL;//为什么不可以删除 } void _Destory(BinaryTreeNode<T>* &root) { if(root==NULL) return; if(root->_left==NULL&&root->_right==NULL) { delete root; root=NULL;//注意 return; } _Destory(root->_left); _Destory(root->_right); delete root; } void _PrevOrder(BinaryTreeNode<T>* &root) { if(root==NULL) return; cout<<root->_data; _PrevOrder(root->_left); _PrevOrder(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; } 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); } 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)+1; int rightHight=_Hight(root->_right)+1; return leftHight>rightHight?leftHight:rightHight; } 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 Test1() { char array[10]={‘a‘,‘b‘,‘d‘,‘#‘,‘#‘,‘e‘,‘#‘,‘#‘,‘c‘,‘f‘}; BinaryTree<char> bt1(array,10); bt1.PrevOrder(); bt1.PrevOrder_Non_R(); bt1.InOrder(); bt1.InOrder_Non_R(); bt1.PostOrder(); bt1.PostOrder_Non_R(); bt1.Find(‘d‘); bt1.Find(‘z‘); bt1.LevelOrder(); bt1.Size(); bt1.Hight(); bt1.LeafNum(); } int main() { Test1(); system("pause"); return 0; }
本文出自 “sunshine225” 博客,请务必保留此出处http://10707460.blog.51cto.com/10697460/1757510
以上是关于二叉树的基本功能实现的主要内容,如果未能解决你的问题,请参考以下文章