二叉树的操作

Posted 勇士后卫头盔哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的操作相关的知识,希望对你有一定的参考价值。

二叉树的属性操作

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)
              Maxheight(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; 
 

结果:

以上是关于二叉树的操作的主要内容,如果未能解决你的问题,请参考以下文章

二叉树

数据结构 二叉树的基本概念

每日辞典 二叉树的递归定义

第2节 二叉树的基本操作(递归实现)

二叉树的后续遍历是啥意思啊?

二叉树的性质