有关二叉树的简单实现

来源:互联网 发布:弹性矩阵和刚度矩阵 编辑:程序博客网 时间:2024/06/06 17:52
#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();                 //t3.InOrder();                 //t3.PostOrder();                 //t3.LevelOrder();                 //cout<<t3.Size()<<endl;                 //cout<<t3.Hight()<<endl;                 //cout<<t3.LeafNum()<<endl;                 //BinaryTree<int> t4;      //赋值运算符重载的测试                 //t4=t2;                 //t4.PreOrder();                 //t4.InOrder();                 //t4.PostOrder();                 //t4.LevelOrder();                 //cout<<t4.Size()<<endl;                 //cout<<t4.Hight()<<endl;                 //cout<<t4.LeafNum()<<endl;                 //t2.PreOrder_Non_R();                 //t2.InOrder_Non_R();                 //t2.PostOrder_Non_R();                 BinaryTreeNode<int >* ret=t2.Find(4);}int main(){                test();                system( "pause");                 return 0;}



层次遍历思路:(不用递归,而是利用队列的先进先出原则

                 首先,访问二叉树根节点,并将其入队

                 其次,当队列不为空时,重复以下操作:

                                                         1.从队列弹出一个节点

                                                         2.将其左右节点压入队列


本文出自 “追寻内心的声音” 博客,转载请与作者联系!

0 0