二叉树的先序、中序、后序非递归遍历算法

记录一下二叉树的先序、中序、后序非递归遍历算法
因为递归算法很简单,所以不再罗列
节点的结构体定义为:

typedef struct BTNode{
	int val;
	struct BTNode* left;
	struct BTNode* right;
}BTNode;

访问节点的函数:

void visit(BTNode* p){
	printf("%d\n", p->val);
}

1.先序非递归

void pre_order(BTNode* root){
	if(root == NULL)
		return;
	BTNode* stack[MAX_SIZE];
	int top = -1;
	BTNode* ptr = root;
	while(ptr != NULL || top > -1){
		while(ptr != NULL){
			visit(ptr);
			stack[++top] = ptr;
			ptr = ptr->left;
		}
		if(top > -1){
			ptr = stack[top--];
			ptr = ptr->right;
		}
	}
}

2.中序非递归算法

void in_order(BTNode* root){
	if(root == NULL)
		return;
	BTNode* stack[MAX_SIZE];
	int top = -1;
	BTNode* ptr = root;
	while(ptr != NULL || top > -1){
		while(ptr != NULL){
			stack[++top] = ptr;
			ptr = ptr->left;
		}
		if(top > -1){
			ptr = stack[top--];
			visit(ptr);
			ptr = ptr->right;
		}
	}
}

后序非递归算法相对前两种复杂一点,关键是想办法保存父节点并确定何时该访问父节点(即左右子树都访问完后才能访问),所以可以设置一个前驱指针pre,永远指向当前节点cur的父节点,并由pre->right == cur这个条件来确定访问父节点的时机
3.后序非递归算法

void post_order(BTNode* root){
	if(root == NULL)
		return;
	BTNode* stack[MAX_SIZE];
	int top = -1;
	BTNode* cur = root;
	BTNode* pre = NULL;		//当cur为根节点时,其父节点为NULL
	while(cur != NULL || top > -1){
		while(cur != NULL){
			stack[++top] = cur;
			pre = cur;
			cur = cur->left;
		}
		while(pre != NULL && pre->right == cur){//表示此时pre的左右子树已遍历结束
			visit(pre);
			cur = pre;
			top--;
			if(top > -1)
				pre = stack[top];
			else
				pre = NULL;		//栈空,此时遍历完二叉树,pre置为NULL
		}
		if(pre != NULL)
			cur = pre->right;	//表示此时cur是pre左孩子,要将其变为pre的右孩子
		else
			cur = NULL;
	}
}

这就是三种非递归遍历算法,其中先序和中序非递归算法较为常见。后序非递归网上有很多种方法,但此种方法是从先序和中序的算法思路受启发变形而来,更容易理解。以上代码均已经通过测试。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值