我们将依据下图的二叉树(具体来说是二叉搜索树)结构实现树的层序遍历
关于二叉树的实现:点击这里
为实现树的层序遍历,比较常用的做法是用队列来实现。
让我们模拟遍历的过程。假设我们有一个队列queue,初始状况下队列queue里什么也没有
队列queue的front和rear指针指向最初的地点(图中蓝色箭头所指为front和rear的共同位置),如下图:
1.我们遇到3节点,将节点入队
此时队列queue里情况如下(图中蓝色箭头所指为front和rear的共同位置):
2.再将三号节点的左右子节点入队列,每个子树节点入队时rear指针也要同时后移(也就是蓝色箭头所在位置)如下图:
3.front指针后移一位至红色箭头处
4.我们需要获取当前红色箭头所指向的节点(也就是上图的1号节点)的左右节点入队(1号节点的左子树为空故不入队,右子树节点为2将之入队),同时rear指针后移至下图中蓝色箭头的位置。
重复上述3,4过程,直到front在rear指针的后面,代表二叉树遍历完全。
明白了原理,上述的代码实现又是另外一回事了,主要的实现方法分为递归和循环两种。
下面我给出的是递归的版本。
我的设想是队列保存的是每个节点的地址,每次入队的不是具体节点内容的数值,而是节点所在内存空间的地址。
想要详细理解的话,建议跟着代码的逻辑一步步模拟,就可以理解为什么这样做了~,这样也是最快的方法。
void LevelTravel(Node* queue[] , Node *t , int front , int rear)
{
if (front > rear) return;
queue[front] = t;
printf("%d ", queue[front]->data);
if(t->left)
queue[++rear] = t->left;
if(t->right)
queue[++rear] = t->right;
LevelTravel(queue,queue[front+1], front+1 , rear);
}
以下是完整代码:
以下代码测试时只有四个节点,但更多的节点测试已经通过,没有出现问题。
#include<stdio.h>
#include<malloc.h>
/**/
typedef struct node
{
int data;
struct node* left, * right;
}Node;
void insert(Node** t, int data)
{
if (*t == NULL)
{
(*t) = (Node*)malloc(sizeof(Node));
(*t)->data = data;
(*t)->left = (*t)->right = NULL;
}
else if (data >= (*t)->data)
{
insert(&((*t)->right), data);
}
else insert(&((*t)->left), data);
}
/**前序遍历 根左右**/
void PreOrderTravel(Node* T)
{
if (T == NULL )
return;
printf("%d ", T->data);
PreOrderTravel(T->left);
PreOrderTravel(T->right);
}
/**中序遍历 左根右**/
void InOrderTravel(Node* T)
{
if (T == NULL)
return;
InOrderTravel(T->left);
printf("%d ", T->data);
InOrderTravel(T->right);
}
/**后序遍历 左右根**/
void TailOrderTravel(Node* T)
{
if (T == NULL)
return;
TailOrderTravel(T->left);
TailOrderTravel(T->right);
printf("%d ", T->data);
}
void LevelTravel(Node* queue[] , Node *t , int front , int rear)
{
if (front > rear) return;
queue[front] = t;
printf("%d ", queue[front]->data);
if(t->left)
queue[++rear] = t->left;
if(t->right)
queue[++rear] = t->right;
LevelTravel(queue,queue[front+1], front+1 , rear);
}
int main()
{
Node* t = NULL;
int i,a[4] = { 3,1,4,2 };
Node* queue[10];
for(i = 0; i < 4; i++)
insert(&t, a[i]);
PreOrderTravel(t); printf("\n");
InOrderTravel(t); printf("\n");
TailOrderTravel(t); printf("\n");
LevelTravel(queue, t, 0, 0);
}
运行截图如下: