【备战2014笔面试】二叉树与树的常见操作

数据结构面试之五—二叉树的常见操作(递归实现部分)

题注:《面试宝典》有相关习题,但思路相对不清晰,排版有错误,作者对此参考相关书籍和自己观点进行了重写,供大家参考。

转载请注明:http://blog.csdn.net/wojiushiwo987/article/category/1210932

五、二叉树的基本操作(递归实现)

    二叉树是笔试、面试的重点,包括选择题的题型之——求解前、中、后序的遍历结果等。去年(2011秋季)的百度笔试试题就考察了二叉树的后序遍历的非递归实现。

    笔者先就下面常考几个题目就递归算法的实现分析如下:

递归的核心就是遍历完根节点后,再依次同样的方法递归左孩子、右孩子节点,直到为空为止!

1.中根遍历

//中序:左->根->右[递归实现]

[cpp] view plain copy
  1. template<typename elemType>  
  2.      voidbinaryTreeType<elemType>::inorder(nodeType<elemType> *p)  
  3.      {  
  4.             if( p != NULL )  
  5.             {  
  6.                    inorder(p->llink);  
  7.                    cout << p->info << " ";  
  8.                    inorder(p->rlink);  
  9.             }  
  10.      }  

2.先根遍历

       //前序:根->左->右[递归实现]

      

[cpp] view plain copy
  1. template<typename elemType>  
  2.       voidbinaryTreeType<elemType>::preorder(nodeType<elemType> *p)  
  3.       {      
  4.              if( p != NULL )  
  5.              {  
  6.                     cout << p->info << " ";  
  7.                     preorder(p->llink);  
  8.                     preorder(p->rlink);  
  9.              }      
  10.       }  

3.后根遍历

       //后序:左->右->根[递归实现]

[cpp] view plain copy
  1. template<typename elemType>  
  2.       voidbinaryTreeType<elemType>::postorder(nodeType<elemType> *p)  
  3.       {  
  4.              if( p != NULL )  
  5.              {  
  6.                     postorder(p->llink);  
  7.                     postorder(p->rlink);  
  8.                     cout << p->info << " ";  
  9.              }  
  10.       }  

4.//求树的高度![递归实现]

   //等于左右子树的最大高度+1

 

[cpp] view plain copy
  1.    template<typename elemType>  
  2.     intbinaryTreeType<elemType>::height(nodeType<elemType> *p)  
  3.     {  
  4.            if( p == NULL)  
  5.            {  
  6.                   return 0;  
  7.            }  
  8.            else  
  9.            {  
  10.                   return 1 + max( height(p->llink),height(p->rlink)); //加上根节点1层..  
  11.            }  
  12.     }  
  13.   
  14. //辅助max  
  15.     template<typename elemType>  
  16.     int binaryTreeType<elemType>::max(int x, int y)  
  17.     {  
  18.            return ( x >= y ? x : y );  
  19.     }  

5./全部/节点数目统计[递归实现]

 

[cpp] view plain copy
  1. template<typename elemType>  
  2.     int binaryTreeType<elemType>::nodeCount(nodeType<elemType>*p)  
  3.     {      
  4.            if(p == NULL)  
  5.            {  
  6.                   return 0;  
  7.            }  
  8.            else  
  9.            {  
  10.                   return 1 + nodeCount(p->llink) +nodeCount(p->rlink);  
  11.            }  
  12.      
  13.     }  

6.//叶节点数目[递归实现]

//叶子节点的特征就是左右子树为空。

  

[cpp] view plain copy
  1. template<typename elemType>  
  2.   intbinaryTreeType<elemType>::leavesCount(nodeType<elemType> *p)  
  3.   {  
  4.          if(p == NULL)  
  5.          {  
  6.                 return 0;  
  7.          }  
  8.          else if(p->llink == NULL && p->rlink ==NULL)  
  9.          {  
  10.                 return 1; //  
  11.          }  
  12.          else  
  13.          {  
  14.                 return leavesCount(p->llink) +leavesCount(p->rlink);  
  15.          }  
  16.   }  

7.判定两颗二叉树是否相等

【思路】:逐个节点(从根节点开始)进行比对,可能出现二叉树1自根节点左子树与二叉树2自根节点的右子树完全一致的情况,或者反之,这种情况也视为两颗二叉树一致。

分为一下5种情况。

       

[cpp] view plain copy
  1. template<typename elemType>  
  2.        boolbinaryTreeType<elemType>::beTreesEqual(nodeType<elemType> *first,nodeType<elemType> *second)  
  3.        {  
  4.               bool isFirstTreeNull = (first == NULL);  
  5.               bool isSecondTreeNull = (second == NULL);  
  6.    
  7.               //case1: 两者不等.  
  8.               if(isFirstTreeNull != isSecondTreeNull)  
  9.               {  
  10.                      return false;  
  11.               }  
  12.               //case2: 两者都为非空.  
  13.               if(isFirstTreeNull == true &&isSecondTreeNull==true)  
  14.               {  
  15.                      return true;  
  16.               }  
  17.               //case3: 两者都非空,但两者的节点值不等  
  18.               //case4: 两者都非空,但节点值相等,需要考虑左右分支的情况...  
  19.               if(!isFirstTreeNull && !isSecondTreeNull)  
  20.               {  
  21.                      if(first->info != second->info) //节点值是否相等  
  22.                      {  
  23.                             return false;  
  24.                      }  
  25.                      else  
  26.                      {  
  27.                             return((beTreesEqual(first->llink,second->llink) &&beTreesEqual(first->rlink,second->rlink))  
  28.                                       ||(beTreesEqual(first->llink,second->rlink) &&beTreesEqual(first->rlink,second->llink)));  
  29.                      }//  
  30.               }//end if  
  31.               return false;  
  32.        }  

建议:

       1.代码不是目的,主要是分析问题的思路;

       2.可以自己画一个二叉树的草图结构,然后根据程序进行代码走读,而后理清思路,再写出代码才是王道!

       3.上述方面,笔者也有欠缺,希望和大家交流探讨!


树的遍历


树的抽象数据类型有:

Tree createEmptyTree(void)

int isNull(Tree t)

Node getRoot(Tree t)

Node parent(Node p)

Tree leftChild(Tree t)

Tree rightBrother(Tree t)


树的深度优先遍历有两种方式,一种为先根次序一种为后根次序


1.先根次序

void preOrder(Tree t)
{
	Tree c;
	if(t.isNull())
		return;
	
	//显示当前根节点
	visit(t);

	c = t.getLeftChild();
	while(!c.isNull)
	{
		//递归调用
		preOrder(c);
		c = c.getRightBrother();
	}
}

2.后根次序

void preOrder(Tree t)
{
	Tree c;
	if(t.isNull())
		return;

	c = t.getLeftChild();
	while(!c.isNull)
	{
		//递归调用
		preOrder(c);
		c = c.getRightBrother();
	}
        
        //显示当前根节点
	visit(t);

}

3.求树的高度

int getHight(Tree t)
{
	Tree c;
	if(!t.haveChild())
		return 0;
	
	c = t.getLeftChild();

	int Max = 0;
	int Temp = 0;

	while(!c.isNull)
	{		
		temp = 	getHight(c);
		
		if(Max < temp)
			Max = temp;
		
		c = c.getRightBrother();
	}

	return Max + 1;
}

4.树的广度优先周游

void levelOrder(Tree t)
{
	Tree c;
	Queue q = new Queue();

	c = t;
	if( c.isNull() )
		return;
	q.add(c);

	while(!q.isEmpty())
	{
		c = q.get();
		q.delete();

		visit(c);

		//每出队一次,其所有的子树均要入队
		c = c.getleftChild();
		while(c.isNull())
		{
			q.add(c);
			c = c.getrightBrother();
		}
	}

}

5.树的宽度




















































你可能感兴趣的:(数据结构)