二叉树的 前序、中序遍历(非递归)

二叉树的 前序、中序遍历(非递归)

二叉树基本结构应该都知道,我就不赘述了,其遍历规则倒是经常出现的知识点,根据根节点的相对位置又分为前序遍历,中序遍历,后序遍历。
要是使用递归的方法,直接控制输出的顺序即可
以前序遍历为例

void BiTree::PreOrder(BiNode *bt){
	if(bt==nullptr){
		return;
	}
	else{
	cout<<bt->data<<endl;
	PreOrder(bt->lchild);
	PreOrder(bt->rchild);
	}
}

这样就行了,但往往是不允许使用递归的,以下就是非递归算法
一个普通的二叉树

思路及代码

首先是结构体的基础代码

struct BiNode{
	int data;
	BiNode* lchild, * rchild;
};
struct BiNode{
	int data;
	BiNode* lchild, * rchild;
};

class BiTree {
private:
	BiNode* root;
public:
	BiTree();
	BiNode* GetRoot() { return root; }
	BiNode* creat();
	void PreOrder();
	void InOrder();
	void PostOrder(BiNode* p);	
};

BiNode* BiTree::creat() {
	BiNode* bt;
	int a;
	cout << "请输入节点的值,-1代表此节点不存在" << endl;
	cin >> a;
	if(a==-1){
		bt = nullptr;
	}
	else {
		bt = new BiNode;
		bt->data = a;
		cout << "请输入" << bt->data<<"的左子树:"<<endl;
		bt->lchild = creat();
		cout << "请输入" << bt->data << "的右子树:" << endl;
		bt->rchild = creat();
	}
	return bt;
}
BiTree::BiTree() {
	root = creat();
}

前序遍历(根左右)

前序遍历的关键在于,访问玩全部的左子树后,如何再找到最初结点的右子树,这就要求我们在输出根节点的值后,保留其地址,以便遍历完左子树后找到右子树地址。这就很容易想到一种存储结构——

指针指向根节点
循环3步:
输出指针指向的结点的数据
该结点存入栈,准备在访问完左子树后用它访问右子树
指针指向该结点的左子树
如果指针指向为空(无左子树了)
就回到上一个结点,指针指向右子树
继续上一个循环

void BiTree::PreOrder(){
	BiNode* bt = root;
	BiNode* s[10];//栈,用于存储节点地址
	int top = -1;//确定操作位置
	cout << "前序遍历结果为:" << endl;
	while (bt != nullptr || top != -1) {
		while (bt != nullptr) {
			cout << bt->data;
			s[++top] = bt;
			bt = bt->lchild;
		}
		if (top != -1) {
			bt = s[top--];//把先前存入的节点出栈
			bt = bt->rchild;
		}
	}
	cout << '\n';
}

中序遍历(左根右)

与前序遍历有一点点不同,这个是要先把每个相对的根节点入栈,等出栈的时候再输出值,所以只要改动一下输出位置即可。

void BiTree::InOrder() {
	BiNode* bt = root;
	BiNode* s[10];//栈,用于存储节点地址
	int top = -1;//确定操作位置
	cout << "中序遍历结果为:" << endl;
	while (bt != nullptr || top != -1) {
		while (bt != nullptr) {
			s[++top] = bt;
			bt = bt->lchild;
		}
		if (top != -1) {
			bt = s[top--];//把先前存入的节点出栈
			cout << bt->data;
			bt = bt->rchild;
		}
	}
	cout << '\n';
}

后序遍历(左右根)

这个遍历如果不递归将会异常繁琐,所以我这里就不展开讲了(其实是我改bug越改越多)直接递归解决问题吧

void BiTree::PostOrder(BiNode *p) {
	if (p == nullptr) { return; }
	else {
		PostOrder(p->lchild);
		PostOrder(p->rchild);
		cout << p->data;
	}
}

就以这张图来测试在这里插入图片描述
结果符合预期
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值