有关二叉树的简单实现

#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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值