java数据结构二叉树查找结点操作,递归调用求详细讲解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java数据结构二叉树查找结点操作,递归调用求详细讲解相关的知识,希望对你有一定的参考价值。

treeNode是先输入的根节点
递归调用那块我想不明白 ,求大神讲解

CBTType TreeFindNode(CBTType treeNode,String data)
CBTType ptr;
if(treeNode!=null)
return null;
else
if(treeNode.data.equals(data))
return treeNode;
else
if((ptr=TreeFindNode(treeNode.left,data))!=null)
return ptr;
else if((ptr=TreeFindNode(treeNode.right,data))!=null)
return ptr;
else
return null;



比如这个二叉树,我现在要找到5,按照代码具体怎么个实现
1
2 3
4 5 6 7

参考技术A 这是先序遍历树的代码,什么是先序遍历呢,一种按照根-左子树-右子树的顺序遍历树就是先序遍历。
CBTType TreeFindNode(CBTType treeNode,String data)
CBTType ptr;
if(treeNode==null)//输入根节点为空时
return null;
else
if(treeNode.data.equals(data))//根节点等于要查找的数据时
return treeNode;
else
if((ptr=TreeFindNode(treeNode.left,data))!=null)//从左子树查找,为什么可以用TreeFindNode表示呢?
return ptr;
else if((ptr=TreeFindNode(treeNode.right,data))!=null)//从右子树查找
return ptr;
else
return null;




从左子树查找,为什么可以用TreeFindNode表示呢?因为,左子树也可以按照先序遍历的顺序查找的,所以当然可以用TreeFindNode表示,如果你想左子树用中序遍历查找,那么就不可以用TreeFindNode表示。
上述例子的查找过程:
1 --根(2,4,5)--左(3,6,7)--右
2--根(4)--左(5)--右
4--根
5--根
返回追问

查找过程能说的再清楚点吗

追答

1 --根(2,4,5)--左(3,6,7)--右
2--根(4)--左(5)--右
4--根
5--根
这个过程是分解过程,不是实际执行的,所以,你不能看成先执行完第1行然后执行第2行,实际执行必须按照中-左-右的顺序执行的,先执行1然后执行(2,4,5)这一串,然后再执行(3,6,7)这一串。
(2,4,5)这一串又按照中-左-右的顺序执行的,先执行2,然后执行(4),然后再执行(5),
(4)这一串又按照中-左-右的顺序执行的,由于没有左右子树,所以执行完根后直接返回,
(5)这一串又按照中-左-右的顺序执行的,由于没有左右子树,所以执行完根后直接返回。
所以实际查找过程是,1-2-4-5,竖着来看你就明白了。

追问

那块儿不是有递归调用么,当根 是1 的时候,先执行1的左,然后再执行1的右还是执行1的左的左,我就递归那块儿看不懂

追答

对你无语。
先执行1然后执行(2,4,5)这一串,你看得懂这句话吗?

追问

我看得懂这句话,但是递归调用那块儿不明白,具体怎么调的还是不懂啊,具体步骤
我是有点笨

追答

你还是不懂,“先执行1然后执行(2,4,5)这一串,然后再执行(3,6,7)这一串
”意思是,必须执行完(2,4,5)这一串然后才轮到(3,6,7)这一串,那么,你认为会执行1的右是不可能的,
2是1的左,4是1的左左,5是1的左右,3是1的右,执行顺序是1-2-4-5,3后面的没机会执行。
顺便说下,左中右是相对的,例如4相对2是左,相对它自己就是中,你懂不懂都算了,我没有耐心了。

本回答被提问者和网友采纳

二叉树的操作

二叉树的查找

二叉树也有两种查找方式,一种是基于数据元素值的查找和基于结点的查找,之前说过通用树结构的查找,一样也是一个递归调用的过程,递归公式如下图所示
值查找的递归公式

基于值的查找

virtual BTreeNode<T>* find(BTreeNode<T>* node,const T& value)const

    BTreeNode<T>* ret = NULL;
    if(node!=NULL)
    
      if(node->value == value)
      
         ret = node;
      
      else
      
          if(ret == NULL)
          
             ret = find(node->l_pointer,value);
          
          if(ret == NULL)
          
             ret = find(node->r_pointer,value);
          

      
    
   return ret;

结点查找的递归公式

基于结点的查找

  virtual BTreeNode<T>* find(BTreeNode<T>* node,BTreeNode<T>* obj)const

    BTreeNode<T>* ret = NULL;
    if(node!=NULL)
    
      if(node == obj)
      
         ret = node;
      
      else
      
          if(ret == NULL)
          
             ret = find(node->l_pointer,obj);
          
          if(ret == NULL)
          
             ret = find(node->r_pointer,obj);
          

      
    
   return ret;

二叉树的插入操作

二叉树也有插入新结点和插入数据元素的两种操作,二叉树的插入操作我们需要考虑的问题就是
1.是否能够在二叉树的任意结点处插入子结点
2.是否需要指定新数据元素的插入位置
对于第一个问题很显然是不能够的,对于二叉树里面的每个成员是相对固定的,假设我们要插入结点的父节点已经有左右孩子两个结点那么插入就会失败,这与通用树有所不同,通用树可以有任意多个子节点
对于第二个问题答案是肯定的,我们需要是插入父节点的左节点还是右节点,我们可以定义一个枚举类型表示位置

enum BTNodePos

   ANY,//任意位置
   LEFT,//左孩子处
   RIGHT//右孩子处
;

插入新结点

插入的代码

 bool insert(BTreeNode<T>* n,BTreeNode<T>* np,BTNodePos pos)
 
    bool ret = true;
    if(pos==ANY)
    
        if(np->l_pointer == NULL)
        
            np->l_pointer = n;
        
        else if(np->r_pointer == NULL)
        
            np->r_pointer = n;
        
        else
        
            ret = false;
        
    
    else if(pos == LEFT)
    
        if(np->l_pointer == NULL)
        
          np->l_pointer  = n;
        
        else
        
           ret = false;
        
    
    else if(pos == RIGHT)
    
        if(np->r_pointer == NULL)
        
          np->r_pointer  = n;
        
        else
        
           ret = false;
        
    
    else
    
       ret = false;
    

   return false;

插入新结点的流程如下图所示

上述流程图的代码

 virtual bool insert(TreeNode<T>* node,BTNodePos pos)

   bool ret = true;
   if(node!=NULL)
   
       if(this->m_root == NULL)
       
           node->parent = NULL;
           this->m_root       = node;
       
       else
       
           BTreeNode<T>* np = find(node->parent);
           if(np!=NULL)
           
               ret = insert(dynamic_cast<BTreeNode<T>*>(node),np,pos);
           
           else
           
               THROW_EXCEPTION(InvalidParamterException,"np == NULL......");
           
       
   
   else
   
       THROW_EXCEPTION(InvalidParamterException,"node == NULL.....");
   

插入新数据

插入新数据元素的流程图

代码

 bool insert(const T& value,TreeNode<T>* parent)
 
   return insert(value,parent,ANY);
 
 virtual bool insert(const T& value,TreeNode<T>* parent,BTNodePos pos)

    bool ret = true;
    BTreeNode<T>* node = BTreeNode<T>::NewNode();
    if(node==NULL)
    
        THROW_EXCEPTION(NoEnougMemoryException,"No memory to create new node....");
    
    else
    
        node->parent = parent;
        node->value  = value;
        ret = insert(node,pos);
        if(!ret)
        
          delete node;
        
    
    return ret;

以上是关于java数据结构二叉树查找结点操作,递归调用求详细讲解的主要内容,如果未能解决你的问题,请参考以下文章

关于二叉树,高分!

二叉树的操作

创建二叉树非递归完成对二叉树的先序和后序遍历并遍历输出每一层的结点数查找结点P 和结点Q的最近共同祖先

Java实现二叉树地遍历求深度和叶子结点的个数

数据结构 二叉树的简单理解和代码实现

树-第三节5:CC++和Java实现二叉树