二叉树的层次遍历
前言
算法思想:一般的二叉树层次遍历是自上而下,从左到右,这里的遍历顺序则恰好相反。利用原有的层次遍历算法,出队的同时将各个结点指针入栈,在所有结点入栈之后再从栈顶开始依次访问所有结点直到栈为空,就结束。
一、树和队列的结构
typedef struct Node //定义树的结构,别名为Node
{
char data; //数据域char类型
struct Node* Lchild; //左孩子
struct Node* Rchild; //右孩子
}Node;
typedef struct Queue //定义队列的结构
{
Node* data; //data定义为Node类型的指针,因为后续的入队和出队操作使用指针取地址的方便
struct Queue* pre; //队列Q的前指针
struct Queue* next; //队列Q的后指针
}Queue;
二、对队列和树的操作
1.创建二叉树
代码如下(示例):
void creatTree(Node** tree, char* data, int* index) //创建树,这里可能不会说很清楚,可观看上一篇博客
{
char temp; //temp变量进行保存
temp = data[*index]; //保存data里面index索引值的数据
*index += 1; //对指针指向的数据进行++
if (temp == '#') //如果是#
{
*tree = NULL; //该树的节点指向NULL
}
else
{
*tree = (Node*)malloc(sizeof(Node)); //如果有数据则开辟空间
(*tree)->data = temp; //这里需要对下一个data数据进行操作,传进来的二级指针需要加个括号来进行对data取值
creatTree(&((*tree)->Lchild),data,index); //使用递归的方法来进行对左孩子的创建
creatTree(&((*tree)->Rchild), data, index); //使用递归的方法来进行对右孩子的创建
}
}
2.队列初始化
代码如下(示例):
Queue* initQueue() //初始化队列
{
Queue* Q = (Queue*)malloc(sizeof(Queue)); //开辟一个Q的空间
Q->data = NULL; //data指向NULL
Q->next = Q; //Q的next指针指向Q
Q->pre = Q; //Q的pre指针指向Q
return Q;
}
3.队列初始化
代码如下(示例):
Queue* initQueue() //初始化队列
{
Queue* Q = (Queue*)malloc(sizeof(Queue)); //开辟一个Q的空间
Q->data = NULL; //data指向NULL
Q->next = Q; //Q的next指针指向Q
Q->pre = Q; //Q的pre指针指向Q
return Q;
}
4.队列入队
代码如下(示例):
void enQueue(Node* tree, Queue* Q) //入队,这里使用的是尾插法来进行入队
{
Queue* node = (Queue*)malloc(sizeof(Queue)); //额外开辟一个node的节点
node->data = tree; //node的data指针指向传进来的tree
node->next = Q; //node的NEXT指向Q
node->pre = Q->pre; //node的pre指向Q的pre,也就是node的pre指向Q的最后一个指针
Q->pre->next = node; //Q的pre的next指向node,即最后的节点的next指向node
Q->pre = node; //Q的pre指针指向node
}
}
5.队列出队
代码如下(示例):
Queue* deQueue(Queue* Q) //出队
{
if (isEmpty(Q)) //先判断是否为空
{
return NULL;
}
else
{
Queue* node = Q->next; //定义一个node来指向Q的next,取得第一个节点
Q->next->next->pre = Q; //Q的下一个的下一个节点的pre指向Q
Q->next = Q->next->next; //Q的next指向Q的next的next也就是第二节点
return node;
}
}
6.层次遍历
代码如下(示例):
void tree_Level(Node* tree, Queue* Q) //层次遍历的主函数
{
enQueue(tree,Q); //先对根节点的入队
while (!isEmpty(Q)) //先进行对Q队列是否为空,类似于套娃一样的
{
Queue* node = deQueue(Q); //创建一个类型为Queue的Node节点接收出队的指针
printf("%c", node->data->data); //因为这里的data是指针所以还需要对data指向的data取值
if (node->data->Lchild) //如果node的data指针指向的左孩子有值的话,再进行入队
{
enQueue(node->data->Lchild, Q); //入队
}
if (node->data->Rchild) //如果node的data指针指向的右孩子有值的话,再进行入队
{
enQueue(node->data->Rchild, Q); //入队
}
}
}
总结
上述有错误的东西,麻烦请指出,谢谢啦!