有关二叉树的简单实现

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二叉树的最大宽度

二叉树的java实现 超级简单讲解版!

数据结构与算法:二叉树

设一棵二叉树以二叉链表表示,试以成员函数形式编写有关二叉树的递归算法:

平衡二叉树的插入与实现

二叉树有关习题整理145二叉树的后序遍历 94二叉树的中序遍历 572另一棵树的子树 236二叉树的最近公共祖先 JZ36二叉搜索树与双向链表 - 牛客