二叉树的非递归遍历
运行结果(采用二叉排序法构建二叉树):
代码如下:
#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;
}
}
}
}