【宝藏】二叉树的非递归遍历 | 先序 | 中序 | 后序 | 层次

二叉树的非递归遍历

运行结果(采用二叉排序法构建二叉树):
在这里插入图片描述

代码如下:

#include<iostream>

// 定义二叉树结点类型,以二叉链表作为存储二叉树的数据结构
typedef struct BTNode {
	int data;
	struct BTNode* lchild;
	struct BTNode* rchild;
	// 默认构造
	BTNode() :data(0), lchild(0), rchild(0) {}
	// 带参构造函数
	BTNode(int _data) : data(_data) {
		this->lchild = 0, this->rchild = 0;
	}
} BTNode;

// 二叉排序树的插入
int BSTInsert(BTNode*& bt, int key);
// 构造二叉排序树
void CreateBST(BTNode*& bt, int key[], int n);
// 打印二叉树结点值
void visit(BTNode* p);
// 先序非递归二叉树
void preOrder(BTNode* bt);
// 中序非递归二叉树
void inOrder(BTNode* bt);
// 后序非递归二叉树
void postOrder(BTNode* bt);
// 层次
void level(BTNode* p);

// 测试主函数
int main() {
	int data[]{ 2,4,1, 3,7 };	// 测试数组
	BTNode* root = new BTNode;  // 生成根结点
	// 根据数组创建二叉排序树
	CreateBST(root, data, sizeof(data) / sizeof(data[0]));

	// 先序
	std::cout << "先序结果:\n";
	preOrder(root);
	std::cout << '\n';

	// 中序
	std::cout << "中序结果:\n";
	inOrder(root);
	std::cout << '\n';

	// 后序
	std::cout << "后序结果:\n";
	postOrder(root);
	std::cout << '\n';

	// 层次
	std::cout << "层次结果:\n";
	level(root);
	std::cout << '\n';

	system("pause");
	return 0;
}

// 二叉排序树的插入
int BSTInsert(BTNode*& bt, int key) {
	if (bt == 0) {
		bt = new BTNode;
		bt->lchild = bt->rchild = 0;
		bt->data = key;
		return 1;		// 插入成功标志
	}
	else {
		if (key == bt->data) return 0;		// 插入失败返回 0
		else if (key < bt->data)
			return BSTInsert(bt->lchild, key);    // 关键字小于根结点值,作为左孩子插入
		else
			return BSTInsert(bt->rchild, key);	  // 关键字大于根结点值,作为右孩子插入
	}
}

// 构造二叉排序树
void CreateBST(BTNode*& bt, int key[], int n) {
	bt = 0;			// 将树清空
	for (int i = 0; i < n; ++i) {
		BSTInsert(bt, key[i]);		// 依次将每个关键字插入到二叉排序树中
	}
}

// 打印二叉树结点值
void visit(BTNode* p) {
	std::cout << p->data << '\t';
}

// 先序非递归二叉树
void preOrder(BTNode* bt) {
	if (bt != 0) {
		const int maxSize = 10;	// 定义栈的大小
		BTNode* Stack[maxSize];	// 定义一个栈
		int top = -1;	// 初始化栈
		BTNode* p = 0;	// 声明一个临时指针,让它指向空
		Stack[++top] = bt; // 根结点入栈
		while (top != -1) {
			p = Stack[top--]; // 出栈
			visit(p); // 输出栈顶结点的值
			if (p->rchild != 0) Stack[++top] = p->rchild;
			if (p->lchild != 0) Stack[++top] = p->lchild;
		}
	}
}

// 中序非递归二叉树
void inOrder(BTNode* bt) {
	if (bt != 0) {
		const int maxSize = 10;
		BTNode* Stack[maxSize];  // 定义初始化栈
		int top = -1;
		BTNode* p = bt;	// 声明一个指针,让它指向根结点
		while (top != -1 || p != 0) {
			while (p != 0) {		// 左孩子存在,左孩子入栈
				Stack[++top] = p;
				p = p->lchild;
			}
			if (top != -1) {	// 在栈不空的情况下输出栈并输出结点的值
				p = Stack[top--];
				visit(p);
				p = p->rchild;
			}
		}
	}
}

// 后序非递归二叉树
void postOrder(BTNode* bt) {
	if (bt != 0) {
		// 定义两个栈
		const int maxSize = 10;
		BTNode* Stack1[maxSize]; int top1 = -1;	// 辅助做逆后序遍历(将先序的左右子树遍历顺序交换)
		BTNode* Stack2[maxSize]; int top2 = -1;
		BTNode* p = 0;  // 声明一个临时指针,让它指向空
		Stack1[++top1] = bt;  // 根结点入栈
		while (top1 != -1) {
			p = Stack1[top1--];	// 结点出栈
			Stack2[++top2] = p; // 输出改为入 Stack2 栈
			// 左右孩子入栈顺序和先序刚好相反
			if (p->lchild != 0) {
				Stack1[++top1] = p->lchild;
			}
			if (p->rchild != 0) {
				Stack1[++top1] = p->rchild;
			}
		}
		while (top2 != -1) {
			// 出栈序列即为后续遍历序列
			p = Stack2[top2--];
			visit(p);
		}
	}
}

// 层次
void level(BTNode* p) {
	int front, rear;
	const int maxSize = 10;
	BTNode* que[maxSize];  // 定义一个循环队列,用来记录将要访问的层次上的结点
	front = rear = 0;
	BTNode* q;
	if (p != 0) {
		rear = (rear + 1) % maxSize;	// 结点不为空,入队
		que[rear] = p;
		while (front != rear) {
			front = (front + 1) % maxSize;
			q = que[front];		// 队头出队
			visit(q);			// 访问、打印队头结点
			if (q->lchild != 0) {	// 如果左子树不空,则左子树的根结点入队
				rear = (rear + 1) % maxSize;
				que[rear] = q->lchild;
			}
			if (q->rchild != 0) {	// 如果右子树不空,则右子树的根结点入队
				rear = (rear + 1) % maxSize;
				que[rear] = q->rchild;
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值