二叉树的三种遍历(前序,中序,后序)

本文详细介绍了二叉树的三种遍历方法:前序遍历(根节点->左子树->右子树)、中序遍历(左子树->根节点->右子树)和后序遍历(左子树->右子树->根节点),并探讨了它们的应用场景和实现技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

void PreOrder()
	{
	  _PreOrder(_pRoot);
	  cout<<endl;
	}

首先,创建二叉树

//-------------孩子表示法---------------

//节点
template <typename T>
struct BinaryTreeNode
{
	BinaryTreeNode(const T& value):_value(value),_pLeft(NULL),_pRight(NULL)
	{
	}
        T _value;
        BinaryTreeNode<T>* _pLeft;//左孩子
        BinaryTreeNode<T>* _pRight;//右孩子
};

//二叉树
template <class T>
class BinaryTree
{

	typedef BinaryTreeNode<T> Node;
public:
	BinaryTree():_pRoot(NULL)
	{
	}
	
	BinaryTree(const T* arr,size_t size,const T& invalid)
	{
	  size_t index=0;
	  _CreateBinaryTree(_pRoot,arr,size,index,invalid);
	}
private:
	//创建树
	void _CreateBinaryTree(Node*& pRoot,const T* arr,size_t size,size_t& index,const T& invalid)
	{
	    if(index<size && invalid!=arr[index])
		{
		   //根节点
			pRoot =new Node(arr[index]);
			//左子树
			_CreateBinaryTree(pRoot->_pLeft,arr,size,++index,invalid);
			//右子树
			_CreateBinaryTree(pRoot->_pRight,arr,size,++index,invalid);
		}
	}
}



先序遍历:先访问根节点,接着访问左子树,再访问右子树

以下用两种方法实现:

第一种:递归实现

 /*先序遍历(根节点--左子树---右子树)*/
private:
	void _PreOrder(Node* pRoot)
	{
	  if(pRoot)
	  {
		  cout<<pRoot->_value<<" ";
		  _PreOrder(pRoot->_pLeft);
		  _PreOrder(pRoot->_pRight);
	  }
	 
	}

将上面的函数封装在下面的函数中

public:
        void PreOrder()
	{
	  _PreOrder(_pRoot);
	  cout<<endl;
	}
第二种:循环实现

/*思路:根入栈--访问栈顶,出栈--右入栈--左入栈*/
public:
	void PreOrder_Not()
	{
	   if(NULL ==_pRoot)
	     return ;
	  stack<Node*> s;
	  s.push(_pRoot);
	  while(!s.empty())
	  {
	   Node* pTop=s.top();
	   cout<<pTop->_value<<" ";
	   s.pop();
	   if(pTop->_pRight)
		   s.push(pTop->_pRight);
	   if(pTop->_pLeft)
		   s.push(pTop->_pLeft);
	  }

		cout<<endl;
	}
中序遍历:访问顺序:左子树---根节点-----右子树
第一种:递归实现

public:
        void InOrder()
	{
		_InOrder(_pRoot);
		cout<<endl;
	}

/*中序遍历(左子树--根节点---右子树)*/
private:
	void _InOrder(Node* pRoot)
	{
		if(pRoot)
		{
		  _InOrder(pRoot->_pLeft);
		  cout<<pRoot->_value<<" ";
		  _InOrder(pRoot->_pRight);
		}
		
	}



第二种:循环实现

public:
        void InOrder_Nor()
	{
	  stack<Node*> s;
		Node* pCur=_pRoot;
		while(pCur||!s.empty())
		{
			//找到最左边的节点,记录做过的节点
	       while(pCur)
		   {
		     s.push(pCur);
			 pCur=pCur->_pLeft;
		   }
		   //访问节点
		   pCur=s.top();
		   cout<<pCur->_value<<" ";
		   s.pop();

		   //访问右子树
		   pCur=pCur->_pRight;
		}
     cout<<endl;
	}


后序遍历:访问顺序:左子树---右子树----根节点

第一种:递归实现

public:
        void PostOrder()
	{
		_PostOrder(_pRoot);
		cout<<endl;
	}

/*后序遍历(左子树---右子树----根节点)*/
private:
	void _PostOrder(Node* pRoot)
	{
	  if(pRoot)
	  {
		  _PostOrder(pRoot->_pLeft);
		  _PostOrder(pRoot->_pRight);
		  cout<<pRoot->_value<<" ";
	  }
	
	}


第二种:循环实现

public:
       void PostOrder()
	{
		_PostOrder(_pRoot);
		cout<<endl;
	}
	//非递归:
	void PostOrder_Nor()
	{
	 if(NULL == _pRoot)
		 return ;
	 stack<Node*> s;
	 Node* pCur=_pRoot;
	 Node* prev=NULL;
	 //找最左边的节点,并记录路径上的所有节点
	 while(pCur||!s.empty())
	 {
	    while(pCur)
	    {
	       s.push(pCur);
	       pCur=pCur->_pLeft;
	    }
	    //取栈顶
	    Node* pTop=s.top();
		//右子树不存在
	    if(NULL == pTop->_pRight ||prev==pTop->_pRight)
	    {
		 cout<<pTop->_value<<" ";
		 prev=pTop;
		 s.pop();
	    }
		//右子树存在
	    else
		   pCur=pTop->_pRight;
	 }
	 cout<<endl;
	}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值