C++:二叉查找树实现(二)——非递归遍历操作

本文深入探讨了二叉树的遍历方法,包括广度优先遍历和深度优先遍历,通过具体实例展示了如何使用队列和栈来实现这两种遍历方式,是理解二叉树结构和操作的重要资源。

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

     建立好二叉树,有时候我们需要对整个二叉树锦星遍历,即输出二叉树的所有结点元素。理论上,遍历的方式有无数种,顺序可以自己任意选定,但是绝大部分遍历方式在实际中并没有用处,比较有用的的遍历方式有两种:广度优先遍历、深度优先遍历。实现这两种遍历可以考虑利用栈以及队列的特性。

(1)广度优先遍历

        广度优先遍历的意思是每次优先遍历完一层的所有子节点,遍历完N层子节点后再遍历N+1层节点,遵循的原则是自上而下、自左向右。

                                                                       

                                                                                   图1.典型二叉查找树

     图中的二叉查找树使用广度优先遍历的方法,获得的结果是:8,3,10,1,6,14,4,7,13.。

     要实现广度优先遍历,可以考虑使用队列实现,我们知道队列的性质是先进先出,我们先将节点8压入队列,输出节点后,弹出节点8,再将节点3和节点10压入队列(注意顺序)。接下来继续对队列处理,节点3先压入队列,所以先处理节点3,处理完之后将该节点弹出,将其左有两个节点1和6压入队列,但是要注意此时队列中还有节点10没有处理,因此先处理节点10,处理完之后弹出并将其子节点14压入队列。以此类推,二叉树的节点压入队列的顺序为

                                                                          图2.广度优先遍历时节点入队顺序以及输出顺序

         图中的竖线表示这些节点是在不同的循环中压入队列,按这个顺序对二叉树输出,,图中相同颜色曲线表示这些节点在相同层输出的,这样就能完成广度优先遍历,程序如下:

void Btree::BreadthFirstVisit()
{
	BreadthFirstVisit(root);

}
void Btree::BreadthFirstVisit(BtreeNode *Bvs)
{
	queue<BtreeNode *> nodeQueue;
	nodeQueue.push(root);
	
	while (!nodeQueue.empty())
	{
		BtreeNode *node = nodeQueue.front();
		cout << node->ele << ' ';
		nodeQueue.pop();
		if (node->left)
			nodeQueue.push(node->left);
		if (node->right)
			nodeQueue.push(node->right);
	}

(1)深度优先遍历

     深度优先遍历就是优先遍历完某一条线的所有子节点,遍历完之后再考虑下一条线,所遵循的顺序仍然是自上而下,自左向右。图1的二叉树,如果采用深度优先遍历原则,输出的顺序为8 3 1 6 4 7 10 14 13。

   类似广度优先遍历,我们可以考虑用栈实现深度优先遍历,将节点一次压入栈,注意栈的原则是后进先出。我们首先将8压入栈,此时栈中只有8一个元素,输出并弹出,然后将其右节点10和左结点3分别压入栈,注意是先压右再压左,这样才能保证左边的先输出。接着输出节点3并弹出节点,弹出后将节点3的右节点6和左结点1分别压入栈,注意此时节点1是最后入栈的,因此需要先处理节点1,处理完节点1之后,因为节点1没有子节点了,再来处理节点6,处理完节点6后还有其左节点4和右节点7,这两个节点肯定是后入栈的,所以必然会先处理,将这些处理完之后,再回去处理节点10。以此类推。所有节点入栈的顺序为

                          

                                                                 图3.  深度优先遍历法节点入栈顺序以及输出顺序

      图3显示了采用深度优先遍历是节点入栈顺序,竖线同样表示节点是在不同循环压入栈的,两种不同颜色的路线表示其中一条完成后才会进行另一条输出,红色代表节点8的左结点产生的分支,绿色部分表示节点8右节点产生的分支。深度优先遍历的程序如下

void Btree::DepthFirstVisit(BtreeNode* dvs)
{
	stack<BtreeNode*> nodeStack;
	nodeStack.push(root);
	while (!nodeStack.empty())
	{
		BtreeNode *node = nodeStack.top();
		cout << node->ele << ' ';
		nodeStack.pop();
		if (node->right)
		{
			nodeStack.push(node->right);
		}
		if (node->left)
		{
		
			nodeStack.push(node->left);
		}
     }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值