二叉树的操作(二)

二叉树的属性操作

1.二叉树结点的数目
对于二叉树结点数目的计算需要用递归来解决,在node为根节点的二叉树中统计结点数目的递归公式如下所示

               return 0;   node == NULL

count(node)  

               count(node->left)+count(node->right)+1;    node!=NULL;

代码如下:

int count(BTreeNode<T>* node)const
{
    if(node == NULL)
    {
       return 0;
    }
    else
    {
        return count(node->l_pointer)+count(node->r_pointer)+1;
    }
}
/*
  可以简化为
  return (node!=NULL)?(count(node->l_pointer)+count(node->r_pointer)+1):0;
*/

2.二叉树的高度
原理上是一样的,二叉树的高度也要用递归来求,获取node为根节点的二叉树的高度的递归公式如下所示,比较左子树和右子树高度的最大值加1就完成了

                return 0;       node==NULL;
height(node)
              Max{height(node->left),height(node->right)}+1;  node!=NULL;

代码实现

    int height(BTreeNode<T>* node) const
{
    if(node == NULL)
    {
       return 0;
    }
    else
    {
       int lh = height(node->l_pointer);
       int rh = height(node->r_pointer);
       return ((rh>lh)?rh:lh)+1;
    }
}

3.树的度数
还是老套路使用递归来求解这个问题,递归公式如下所示

               return 0;    node ==  NULL
degree(node)
              Max{
                    degree(node->left),
                    degree(node->right),          node!=NULL
                    !!node->left + !!node->right
                 };

代码实现

int degree(BTreeNode<T>* node)const
      {
          int ld,rd,ret;
          if(node == NULL)
          {
             return 0;
          }
          else
          {
              ld = degree(node->l_pointer);
              rd = degree(node->r_pointer);
              ret  = !!node->l_pointer + !!node->r_pointer;
              if(ret<ld)
              {
                 ret = ld;
              }
              if(ret < rd)
              {
                  ret = rd;
              }
          }
          return ret;
      }

二叉树的层次遍历

二叉树的遍历是指从根节点出发,按照某种次序依次访问二叉树中的所有结点,使得每个结点有且只有一次被访问,提供一组遍历相关的函数,按层次访问二叉树中的数据元素
算法设计
在二叉树中加入一个队列成员BQueue,该队列用来层次遍历使用
思想:
begin()->将根结点压入队列中
current()->访问队头元素指向的数据元素
next()->队头元素弹出,将队头元素的孩子压入队列中
end()->判断队列是都为空
在这里插入图片描述

bool begin()
{
    bool ret = (root()!=NULL);
    if(ret)
    {
       BQueue.clear();
       BQueue.add(root());
    }
    return ret;
}
bool next()
{
    bool ret = (BQueue.length()>0);
    if(ret)
    {
      BTreeNode<T>* node = BQueue.front();
      BQueue.remove();
      if(node->l_pointer!=NULL)
      {
         BQueue.add(node->l_pointer);
      }
      if(node->r_pointer!=NULL)
      {
         BQueue.add(node->r_pointer);
      }
    }
    return ret;
}
bool end()
{
    return (BQueue.length()==0);
}
T current()
{
    if(!end())
    {
       return BQueue.front()->value;
    }
    else
    {
        THROW_EXCEPTION(InvalidParamterException,"no value to read");
    }
}

二叉树的其他遍历方式

先序遍历
1.访问根结点中的数据元素
2.先序遍历左子树
3.先序遍历右子树
在这里插入图片描述
中序遍历
1.中序遍历左子树
2.访问根结点中的数据元素
3.中序遍历右子树
在这里插入图片描述
后序遍历
1.中序遍历左子树
2.中序遍历右子树
3.访问根结点中的数据元素
在这里插入图片描述
接口设计

SharedPointer<Array<T>> traversal(BTTraversal order)
1.根据参数order选择执行遍历算法(先序,中序,后序)
2.返回值为堆中的数组对象(生命期由智能指针管理)
3.数组元素的次序反映遍历的先后次序

代码
BTree.h

template <typename T>
class BTree : public Tree<T>
{
	private:
	void PreOrderTraversal(BTreeNode<T>* node,LinkQueue<BTreeNode<T>*>& q)
	{
	    if(node!=NULL)
	    {
	        q.add(node);
	        PreOrderTraversal(node->l_pointer,q);
	        PreOrderTraversal(node->r_pointer,q);
	    }
	}
	void InOrderTraversal(BTreeNode<T>* node,LinkQueue<BTreeNode<T>*>& q)
	{
	   if(node!=NULL)
	   {
	       PreOrderTraversal(node->l_pointer,q);
	       q.add(node);
	       PreOrderTraversal(node->r_pointer,q);
	   }
	}
	void PostOrderTraversal(BTreeNode<T>* node,LinkQueue<BTreeNode<T>*>& q)
	{
	   if(node!=NULL)
	   {
	       PreOrderTraversal(node->l_pointer,q);
	       PreOrderTraversal(node->r_pointer,q);
	       q.add(node);
	   }
	}
	public:
	  SharedPointer< Aarry <T> > traversal(BTTraversal order)
      {
         DynamicArray<T> *ret = NULL;
         LinkQueue<BTreeNode<T>*> queue;
         switch(order)
         {
            case PreOrder:
                 PreOrderTraversal(root(),queue);
                 break;
            case InOrder:
                 InOrderTraversal(root(),queue);
                 break;
            case PostOrder:
                 PostOrderTraversal(root(),queue);
                 break;
             default:
                 THROW_EXCEPTION(InvalidParamterException,"Invaild para");
                 break;
         }
         cout<<"the queue's length is"<<queue.length()<<endl;
         ret = new DynamicArray<T> (queue.length());
         if(ret!=NULL)
         {
             for(int i =0;i<ret->length();i++,queue.remove())
             {
                  ret->set(i,queue.front()->value);
                  ;
             }
         }
         else
         {
             THROW_EXCEPTION(NoEnougMemoryException,"no EnoungMemory......");
         }
         return ret;
      }
}

main.c

#include <BTree.h>
int main()
{
  BTree<int> bt;
  BTreeNode<int>* n = NULL;
  bt.insert(1,NULL);

  n = bt.find(1);
  bt.insert(2,n);
  bt.insert(3,n);


  n = bt.find(2);
  bt.insert(4,n);
  bt.insert(5,n);

  n = bt.find(4);
  bt.insert(8,n);
  bt.insert(9,n);

  n = bt.find(5);
  bt.insert(10,n);

  n=bt.find(3);
  bt.insert(6,n);
  bt.insert(7,n);
  
  SharedPointer < Aarry <int> > sp = bt.traversal(PreOrder);


  for(int i =0;i<(*sp).length();i++)
  {
      cout<<(*sp)[i]<<" ";
  }
  cout<<endl;
  SharedPointer < Aarry <int> > sp1 = bt.traversal(InOrder);


  for(int i =0;i<(*sp1).length();i++)
  {
      cout<<(*sp1)[i]<<" ";
  }
  cout<<endl;
  SharedPointer < Aarry <int> > sp2 = bt.traversal(PostOrder);


  for(int i =0;i<(*sp2).length();i++)
  {
      cout<<(*sp2)[i]<<" ";
  }
  return 0; 
} 

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值