前言:
阅读本文时,你只需要了解到二叉树的基本遍历思想。
借助栈就可以将二叉树的递归遍历算法转化成非递归遍历算法。
我们知道,二叉树一般使用的是链式存储,栈可以使用顺序存储也可以使用链式存储。
所以一般情况下,使用栈实现二叉树的非递归遍历算法有两种存储方式:
- 链式存储树-顺序存储栈
- 链式存储树-链式存储栈
本文中使用到的是链式存储树-链式存储栈。对于第一种存储方式,读者可以自行尝试,其实大同小异,这里不再赘述。
直接开始重点,具体实现思想如下:
回顾二叉树先序遍历的步骤:
- 访问根结点;
- 先序遍历左子树;
- 先序遍历右子树;
那么算法的核心部分我们就可以这样设计:
- 定义一个树结构体指针p,初始化指向树的根结点;
- 访问p所指向的结点地址的值,然后将p压入栈;
- 访问p所指向结点的左孩子,并且访问p所指向的结点地址的值,将p压入栈;
- 这个过程直到p指向为空;
- 此时取出栈顶元素,将p指向栈顶元素的右孩子;
- 上述循环的跳出条件是栈空;
代码实现:
1.树结构的定义与栈结构的定义:
//树结点结构定义
typedef struct BiTNode {
int data;
struct BiTNode* lchild, * rchild;
}*BiTree;
//链栈结点结构定义
typedef struct Linknode {
BiTNode* data;
struct Linknode* next;
}*Stack;
2.手动创建一个二叉树:
//手动构建一颗二叉树
void createtree(BiTree& T) {
T = new BiTNode;
T->data = 1;
BiTNode* p1 = new BiTNode;
p1->data = 2;
BiTNode* p2 = new BiTNode;
p2->data = 3;
BiTNode* p3 = new BiTNode;
p3->data = 4;
BiTNode* p4 = new BiTNode;
p4->data = 5;
BiTNode* p5 = new BiTNode;
p5->data = 6;
T->lchild = p1;
T->rchild = p2;
p1->lchild = p3;
p1->rchild = p4;
p4->lchild = nullptr;
p4->rchild = nullptr;
p3->lchild = nullptr;
p3->rchild = nullptr;
p2->lchild = p5;
p2->rchild = nullptr;
p5->lchild = nullptr;
p5->rchild = nullptr;
}
3.初始化链栈:
void initlink(Stack& S) {
S = NULL;
}
4.链栈判空:
bool emptyStack(Stack S) {
if (S == NULL)
return true;
return false;
}
5.入栈操作:
void enqueue(Stack& head, BiTNode* T) {
Linknode* L = new Linknode;
L->data = T;
L->next = head;
head = L;
}
6.出栈操作:
bool pop(Stack& head, BiTree& p)
{
if (head == NULL)
return false;
else {
p = head->data;
head = head->next;
}
return true;
}
7.先序非递归遍历核心代码:
void preorder(BiTree T) {
Stack S;
initlink(S);
BiTNode* p = T;
while (p || !emptyStack(S))
{
if (p != nullptr)
{
enqueue(S, p);
cout << p->data << " ";
p = p->lchild;
}
else
{
pop(S, p);
p = p->rchild;
}
}
}
完整代码:
#include<iostream>
using namespace std;
//树结点结构定义
typedef struct BiTNode {
int data;
struct BiTNode* lchild, * rchild;
}*BiTree;
//链栈结点结构定义
typedef struct Linknode {
BiTNode* data;
struct Linknode* next;
}*Stack;
//手动构建一颗二叉树
void createtree(BiTree& T) {
T = new BiTNode;
T->data = 1;
BiTNode* p1 = new BiTNode;
p1->data = 2;
BiTNode* p2 = new BiTNode;
p2->data = 3;
BiTNode* p3 = new BiTNode;
p3->data = 4;
BiTNode* p4 = new BiTNode;
p4->data = 5;
BiTNode* p5 = new BiTNode;
p5->data = 6;
T->lchild = p1;
T->rchild = p2;
p1->lchild = p3;
p1->rchild = p4;
p4->lchild = nullptr;
p4->rchild = nullptr;
p3->lchild = nullptr;
p3->rchild = nullptr;
p2->lchild = p5;
p2->rchild = nullptr;
p5->lchild = nullptr;
p5->rchild = nullptr;
}
//初始化链栈
void initlink(Stack& S) {
S = NULL;
}
bool emptyStack(Stack S) {
if (S == NULL)
return true;
return false;
}
void enqueue(Stack& head, BiTNode* T) {
Linknode* L = new Linknode;
L->data = T;
L->next = head;
head = L;
}
bool pop(Stack& head, BiTree& p)
{
if (head == NULL)
return false;
else {
p = head->data;
head = head->next;
}
return true;
}
void preorder(BiTree T) {
Stack S;
initlink(S);
BiTNode* p = T;
while (p || !emptyStack(S))
{
if (p != nullptr)
{
enqueue(S, p);
cout << p->data << " ";
p = p->lchild;
}
else
{
pop(S, p);
p = p->rchild;
}
}
}
int main() {
BiTree T;
createtree(T);
preorder(T);
return 0;
}
执行结果:

本文介绍了如何使用链式存储树和链式存储栈实现二叉树的非递归先序遍历算法。通过访问根节点、左子树和右子树的顺序,设计算法并给出核心代码,最终展示执行结果。
954

被折叠的 条评论
为什么被折叠?



