二叉树的递归遍历与非递归遍历

多年之前笔者刚毕业的时候去百度面试,要求当场写出非递归方式的二叉树遍历。(当场懵逼了。)

其实当时自己可能由于紧张,并且对不同数据结构之间的理解还不够深刻。

本质上递归遍历也是利用栈来控制遍历的先后顺序,只是递归算法由于子程序的使用代码会简介许多。

而非递归需要自己对进栈和出栈有一定的理解。而且还需要构建额外的数据结构(C语言没有线程的栈结构,c++的std::stack可以方便不少)。所以实现上会难于递归。

销毁二叉树采用递归方式。

遍历二叉树采用栈的方式。

大概讲一下思路。(采用中序遍历为例子)

1)首先将头结点进栈,然后进入一个主循环

2)主循环判断栈是否为空,若空则退出若非空则进入

3)取出栈中的第一个结点称为pTail

4)由于栈是先进后出,因此右结点在左结点之后遍历。所以先判断是否存在右结点,若存在则入栈

5)接着判断是否存在左结点,若存在则入栈

6)可以输出当前结点的一些信息或者进行一些操作表明“遍历”

7)当前循环结束,跳转至步骤2)循环


代码如下。

#define  _CRT_SECURE_NO_WARNINGS  
#include <tchar.h>  
#include <windows.h>  
#include <stdio.h>
#include <process.h>

#define MAX_NODE	256

typedef struct TreeNode{
	int id;
	TreeNode * left;
	TreeNode * right;
}TreeNode;


//
TreeNode *g_data[MAX_NODE] = { 0 };
int g_p = 0;

void stackPush(TreeNode* pNode) {
	// stack overflow!
	if (g_p >= MAX_NODE)
		return;

	g_data[g_p++] = pNode;
}

TreeNode *stackPop() {
	// stack overflow
	if (g_p == 0)
		return NULL;
	return g_data[--g_p];
}

bool isStackEmpty() {
	return g_p == 0;
}
//
//Travesal without recursive.
void TravesalTree(TreeNode *phead) {
	TreeNode *pTail = phead;
	if (pTail)
		stackPush(pTail);
	while (!isStackEmpty()) {
		pTail = stackPop();
		if (pTail) {
			printf("%d ", pTail->id);
			if (pTail->right)
				stackPush(pTail->right);
			if (pTail->left)
				stackPush(pTail->left);
		}
	}
	printf("\n");
}

// Travesal tree with recursive.
void DestroyTree(TreeNode *phead) {
	if (phead->left)
		DestroyTree(phead->left);

	if (phead->right)
		DestroyTree(phead->right);
	//
	printf("destroy node id:%d\n", phead->id);
	free(phead);
}

int _tmain(int argc, TCHAR* argv[], TCHAR * env[])
{
	int id = 0;
	
	TreeNode * phead = (TreeNode *)malloc(sizeof(TreeNode));
	phead->id = id++;
	phead->left = NULL;
	phead->right = NULL;

	TreeNode *pTail = phead;
	TreeNode * p = (TreeNode *)malloc(sizeof(TreeNode));
	p->id = id++;
	p->left = NULL;
	p->right = NULL;
	pTail->left = p;

	p = (TreeNode *)malloc(sizeof(TreeNode));
	p->id = id++;
	p->left = NULL;
	p->right = NULL;
	pTail->right = p;

	pTail = pTail->left;
	p = (TreeNode *)malloc(sizeof(TreeNode));
	p->id = id++;
	p->left = NULL;
	p->right = NULL;
	pTail->left = p;

	TravesalTree(phead);
	DestroyTree(phead);
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值