有二叉树如下图:
实现前序遍历(根左右): 1 2 4 3 5 7 8 9 6
实现中序遍历(左根右): 4 2 1 7 5 9 8 3 6
实现后序遍历(左右根): 4 2 7 9 8 5 6 3 1
实现层次遍历: 1 2 3 4 5 6 7 8 9
代码实现:
#include <stdio.h>
#include <stdlib.h>
/*
二叉树前序遍历:根左右
中序遍历:左根右
后序遍历:左右根
*/
// 创建二叉树的节点结构体
struct treeNode
{
int a; // 数据域
struct treeNode* pLeft; // 左子树指针
struct treeNode* pRight;// 右子树指针
};
// 创建节点
struct treeNode* CreateNode(int a);
// 连接节点
void InsertNode(struct treeNode* curNode, struct treeNode* leftNode, struct treeNode* rightNode);
// 打印数据
void Print(struct treeNode* root);
// 递归 前序遍历
void PreOrder(struct treeNode* curNode);
// 栈实现 前序遍历
void PreOrderByStack(struct treeNode* curNode);
// 递归 中序遍历
void MidOrder(struct treeNode* curNode);
// 栈实现 中序遍历
void MidOrderByStack(struct treeNode* curNode);
// 递归 后序遍历
void LastOrder(struct treeNode* curNode);
// 栈实现 后序遍历
void LastOrderByStack(struct treeNode* curNode);
// 利用队列实现层次遍历
void LayerOrder(struct treeNode* curNode);
int main()
{
// 创建二叉树节点
struct treeNode* T1 = CreateNode(1);
struct treeNode* T2 = CreateNode(2);
struct treeNode* T3 = CreateNode(3);
struct treeNode* T4 = CreateNode(4);
struct treeNode* T5 = CreateNode(5);
struct treeNode* T6 = CreateNode(6);
struct treeNode* T7 = CreateNode(7);
struct treeNode* T8 = CreateNode(8);
struct treeNode* T9 = CreateNode(9);
// 连接节点
InsertNode(T1, T2, T3);
InsertNode(T2, T4, NULL);
InsertNode(T4, NULL, NULL);
InsertNode(T3, T5, T6);
InsertNode(T6, NULL, NULL);
InsertNode(T5, T7, T8);
InsertNode(T7, NULL, NULL);
InsertNode(T8, T9, NULL);
InsertNode(T9, NULL, NULL);
// 遍历
printf("前序遍历\n");
// 前
PreOrder(T1);
printf("\n");
PreOrderByStack(T1);
// 中
printf("\n中序遍历\n");
MidOrder(T1);
printf("\n");
MidOrderByStack(T1);
// 后
printf("\n后序遍历\n");
LastOrder(T1);
printf("\n");
LastOrderByStack(T1);
// 利用队列实现层次遍历
printf("\n层次遍历\n");
LayerOrder(T1);
system("pause>0");
return 0;
}
// 创建节点
struct treeNode* CreateNode(int a)
{
// 动态申请内存空间 创建节点
struct treeNode* newNode = (struct treeNode*)malloc(sizeof(struct treeNode));
// 判空
if (NULL == newNode)
{
return NULL;
}
// 给节点结构体赋值
newNode->a = a;
newNode->pLeft = NULL;
newNode->pRight = NULL;
return newNode;
}
// 连接节点
void InsertNode(struct treeNode* curNode, struct treeNode* leftNode, struct treeNode* rightNode)
{
// 判断当前父节点否为空
if (NULL == curNode)
{
return;
}
// 当前节点左指针指向左子树节点
curNode->pLeft = leftNode;
// 当前节点右指针指向右子树节点
curNode->pRight = rightNode;
}
// 打印数据
void Print(struct treeNode* root)
{
// 当节点不为空时,进行打印数据
if (NULL != root)
{
// 打印数据
printf("%d\t", root->a);
}
}
// 递归 前序遍历
void PreOrder(struct treeNode* curNode)
{
// 检验参数
if (NULL == curNode)
{
return;
}
// 根
Print(curNode);
// 左
PreOrder(curNode->pLeft);
// 右
PreOrder(curNode->pRight);
}
// 递归 中序遍历
void MidOrder(struct treeNode* curNode)
{
// 检验参数
if (NULL == curNode)
{
return;
}
// 左
MidOrder(curNode->pLeft);
// 根
Print(curNode);
// 右
MidOrder(curNode->pRight);
}
// 递归 后序遍历
void LastOrder(struct treeNode* curNode)
{
// 检验参数
if (NULL == curNode)
{
return;
}
// 左
LastOrder(curNode->pLeft);
// 右
LastOrder(curNode->pRight);
// 根
Print(curNode);
}
// 栈实现 前序遍历
void PreOrderByStack(struct treeNode* curNode)
{
// 检验参数
if (NULL == curNode)
{
return;
}
// 声明数组 栈 类型struct treeNode*
struct treeNode* Stack[100];
// 定义变量用于记录数组下标
int stackTop = -1;
// 定义移动指针
struct treeNode* pMove = curNode;
// 当记录数组下标的变量不为-1 或是 移动指针不为空
while (-1 != stackTop || NULL != pMove)
{
// 入栈 根 左
while (NULL != pMove)
{
// 前序遍历根
// 打印数据
printf("%d\t", pMove->a);
// 将移动指针记录到数组(栈中)
Stack[++stackTop] = pMove;
// 左移
pMove = pMove->pLeft;
}
// 出栈 右
if (-1 != stackTop)
{
// 将数组(栈)中的元素赋给移动指针
pMove = Stack[stackTop--];
// 移动指针右移
pMove = pMove->pRight;
}
}
}
// 栈实现 中序遍历
void MidOrderByStack(struct treeNode* curNode)
{
// 检验参数
if (NULL == curNode)
{
return;
}
// 声明数组 栈 类型struct treeNode*
struct treeNode* Stack[100];
// 定义变量用于记录数组下标
int stackTop = -1;
// 定义移动指针
struct treeNode* pMove = curNode;
// 当记录数组下标的变量不为-1 或是 移动指针不为空
while (-1 != stackTop || NULL != pMove)
{
// 入栈 根 左
while (NULL != pMove)
{
// 中序遍历根
// 将移动指针记录到数组(栈中)
Stack[++stackTop] = pMove;
// 左移
pMove = pMove->pLeft;
}
// 出栈 左 根 右
if (-1 != stackTop)
{
// 将数组(栈)中的元素赋给移动指针
pMove = Stack[stackTop--];
// 打印数据
printf("%d\t", pMove->a);
// 移动指针右移
pMove = pMove->pRight;
}
}
}
// 栈实现 后序遍历
void LastOrderByStack(struct treeNode* curNode)
{
// 检验参数
if (NULL == curNode)
{
return;
}
// 创建数组(栈) 类型是struct treeNode*
struct treeNode* Stack[100];
// 定义移动指针
int stackTop = -1;
// 定义移动指针
struct treeNode* pMove = curNode;
// 定义一个记录节点是否已被访问的指针
struct treeNode* pLastVisited = NULL;
// 入栈
while (NULL != pMove)
{
// 将移动指针装进数组中(栈)
Stack[++stackTop] = pMove;
// 指针左移
pMove = pMove->pLeft;
}
// 出栈
while (-1 != stackTop)
{
// 将数组中元素赋给移动指针
pMove = Stack[stackTop--];
// 判断是否进行打印数据
// 当右节点为空,或是右节点已被访问,则进行打印数据操作
if (NULL == pMove->pRight || pLastVisited == pMove->pRight)
{
// 打印数据
printf("%d\t", pMove->a);
// 记录已被访问(打印数据)的指针
pLastVisited = pMove;
}
else
{
// 当右子树节点不为空 后序遍历 -> 左右根
// 当节点不为空时进行入栈操作 移动指针右移
if (NULL != pMove)
{
// 入栈操作 将移动指针装进数组中(栈)
Stack[++stackTop] = pMove;
// 右移
pMove = pMove->pRight;
}
// 入栈 移动指针左移
while (NULL != pMove)
{
// 将移动指针装进数组中(栈)
Stack[++stackTop] = pMove;
// 指针左移
pMove = pMove->pLeft;
}
}
}
}
// 利用队列实现层次遍历
void LayerOrder(struct treeNode* curNode)
{
// 检验参数
if (NULL == curNode)
{
return;
}
// 声明队列(数组) 类型 struct treeNode*
struct treeNode* queue[100];
// 定义队头(数组下标)出数据
int front = 0;
// 定义队尾(数组下标)存数据
int back = 0;
// 定义移动指针
struct treeNode* pMove = curNode;
// 入队 将移动指针装进数组中
queue[back++] = pMove;
// 直接打印数据
printf("%d\t", pMove->a);
// 循环遍历 当队头与队尾下标不同时
while (front != back)
{
// 出队将队列中的元素赋给移动指针
pMove = queue[front++];
// 当左子树节点不为空时,打印左节点
if (NULL != pMove->pLeft)
{
// 入队
queue[back++] = pMove->pLeft;
// 打印数据
printf("%d\t", pMove->pLeft->a);
}
// 当右子树节点不为空时,打印右节点
if (NULL != pMove->pRight)
{
// 入队
queue[back++] = pMove->pRight;
// 打印数据
printf("%d\t", pMove->pRight->a);
}
}
}
程序输出: