先序遍历
#include <stdio.h>
#define MAX 100
typedef struct Node
{
int data;
struct Node * lchild;
struct Node * rchild;
}BTNode;
// 先序遍历非递归算法
void preorder(BTNode * b)
{
// 创建指针数组栈
BTNode * st[MAX];
// 工作指针
BTNode * p;
// 栈顶
int top = -1;
if(b != NULL)
{
// 根节点进栈
top++;
st[top] = b;
while(top > -1)
{
// 访问栈顶元素
p = st[top];
top--;
printf("%d\n", p->data);
// 右孩子先进栈,先序先访问左孩子
if(p->rchild != NULL)
{
top++;
st[top] = p->rchild;
}
// 再压入左孩子,后访问
if(p -> lchild != NULL)
{
top++;
st[top] = p->lchild;
}
}
}
}
中序遍历
#include <stdio.h>
#define MAX 100
typedef struct Node
{
int data;
struct Node * lchild;
struct Node * rchild;
}BTNode;
// 中序遍历的非递归算法
void Inorder(BTNode * b)
{
// 创建指针数组栈
BTNode * st[MAX];
// 工作指针
BTNode * p;
// 栈顶
int top = -1;
if(b != NULL)
{
// 先让工作指针指向根节点
p = b;
while(top > -1 || p != NULL)
{
// 栈不为空,或者还有未访问的节点
// 处理未访问的节点,将左孩子进栈,最左的孩子在栈顶
while(p != NULL)
{
top++;
st[top] = p;
p = p -> lchild;
}
if(top > -1)
{
// 出栈
p = st[top];
top--;
printf("%d\n", p->data);
// 此时最左的p的右孩子可能为空,但是循环之后就打印中间节点,完成了中序遍历
p = p->rchild;
}
}
}
}
后序遍历:
#include <stdio.h>
#define MAX 100
typedef struct Node
{
int data;
struct Node * lchild;
struct Node * rchild;
}BTNode;
// 后序遍历的非递归算法
void Postorder(BTNode * b)
{
// 创建指针数组栈
BTNode * st[MAX];
// 工作指针
BTNode * p;
// 栈顶
int top = -1;
// 创建标志,表示当前节点是否还有左孩子
int flag;
if(b != NULL)
{
do
{
// 先进入,再循环
while(b != NULL)
{
// 左孩子依次进栈,栈顶为最左孩子
top++;
st[top] = b;
b = b->lchild;
}
// p永远指向上一个输出元素的指针
p = NULL;
flag = 1;
while(top > -1 && flag != 0)
{
b = st[top];
if(b->rchild == p)
{
// 若没有右孩子
printf("%d\n", p->data);
top--;
p = b;
}
else
{
// 表示还有右孩子
b = b->rchild;
flag = 0;
}
}
}while(top > -1)
}
}
层次遍历
#include <stdio.h>
#define MAX 100
typedef struct Node
{
int data;
struct Node * lchild;
struct Node * rchild;
}BTNode;
// 层次遍历
void Levelorder(BTNode * b)
{
// 循环队列
BTNode * qu[MAX];
// 初始化队头队尾的指针
int front, rear;
front = rear = -1;
// 工作指针
BTNode * p;
// 根节点进队
rear++;
qu[rear] = b;
while(rear != front)
{
// 出队
front = (front + 1) % MAX;
p = qu[front];
printf("%d\n", p->data);
if(p->lchild != NULL)
{
// 先进队左孩子
rear = (rear + 1) % MAX;
qu[rear] = p->lchild;
}
if(p->rchild != NULL)
{
// 再进队右孩子
rear = (rear + 1) % MAX;
qu[rear] = p->rchild;
}
}
}