问题:
如上二叉树,请按层遍历,每层一行,遍历结果如下:
1
2 3
4 5 6 7
8
我的思路:
在按层遍历之前,我们可以思考一下,如果我们从根结点看起,通过根节点,我们就能找到下一层中同层的所有的节点,得到下一层所有的节点,那么就能找到下下一层同层的所有的节点,以此类推,就能实现按层遍历了,但是由于树的原因,我们不可能直接按层遍历,所以得找到一个数据结构,能保存同层中不能一次性访问的节点,经过分析,符合先进先出条件,那么队列就当仁不让的站出来啦!
上面一段分析了实现按层遍历,但是题目条件是需要一层一行的输出,因此我们就需要适时的给输出加上换行。我的想法是能不能在队列中保存节点信息的同时,稍带的把节点所在层数也保存起来,只要遇到层数改变,就在输出前加上回车,不是就实现了按层输出,每层一行的要求吗?是的!
代码如下:
#include<stdio.h>
#include<stdlib.h>
#define SQU_MAX 100
//定义二叉树节点
struct BinaryTreeNode
{
int id;
struct BinaryTreeNode *left;
struct BinaryTreeNode *right;
};
//保存节点内容和节点高度
struct BinaryTreeWithHight
{
int height;
struct BinaryTreeNode *data;
};
//队列结构体
typedef struct
{
struct BinaryTreeWithHight *data[SQU_MAX];
int top;
int length;
}Queue;
//创建二叉树
struct BinaryTreeNode* createBinaryTree()
{
int id;
scanf("%d",&id);
if (id == 0)
{
return NULL;
}
struct BinaryTreeNode *root;
root=(struct BinaryTreeNode *)malloc(sizeof(struct BinaryTreeNode));
root->id=id;
root->left = createBinaryTree();
root->right = createBinaryTree();
return root;
}
//先序遍历二叉树
void printBinaryTreeFirst(struct BinaryTreeNode *root)
{
if(root == NULL)
{
return;
}
printf("%d\t\n",root->id);
printBinaryTreeFirst(root->left);
printBinaryTreeFirst(root->right);
}
//返回队列长度
int QueueLength(Queue *queue)
{
return queue->length;
}
//判空
int IsEmpty(Queue *queue)
{
if(queue->length == 0)
{
return 1;
}
return 0;
}
//判满
int IsFull(Queue *queue)
{
if(queue->length == SQU_MAX)
{
return 1;
}
return 0;
}
//入队列
int InsertQueue(struct BinaryTreeWithHight *data, Queue *queue)
{
if(IsFull(queue))
{
printf("队列已满!\n");
return 0;
}
queue->top = (queue->top+1) % SQU_MAX;
queue->length++;
queue->data[queue->top]=data;
return 1;
}
//出队列
struct BinaryTreeWithHight *DeleteQueue(Queue *queue)
{
if(IsEmpty(queue))
{
printf("队列为空!\n");
return NULL;
}
int tail = (queue->top - queue->length + SQU_MAX + 1) % SQU_MAX;
struct BinaryTreeWithHight *rtu;
rtu = queue->data[tail];
queue->length--;
return rtu;
}
//按层遍历
int PrintBinaryTreeByBayer(struct BinaryTreeNode*root, Queue *queue)
{
if(root == NULL)
{
return -1;
}
//队列层数或高度
int curr_hight=1;
struct BinaryTreeWithHight *data;
data = (struct BinaryTreeWithHight *)malloc(sizeof(struct BinaryTreeWithHight));
data->data=root;
data->height=curr_hight;
//将根结点入队列
InsertQueue(data,queue);
while(!IsEmpty(queue))
{
struct BinaryTreeWithHight *tmp;
//将根队列出栈
tmp = DeleteQueue(queue);
//如果遍历到新的层,则先回车再输出
if(tmp->height > curr_hight)
{
curr_hight++;
printf("\n");
}
//输出
printf("%d\t", tmp->data->id);
//如果左子树不为空
if(tmp->data->left != NULL)
{
//入队列
struct BinaryTreeWithHight *left;
left = (struct BinaryTreeWithHight *)malloc(sizeof(struct BinaryTreeWithHight));
left->height=tmp->height+1;
left->data = tmp->data->left;
InsertQueue(left,queue);
}
//如果右子树不为空
if(tmp->data->right != NULL)
{
//入队列
struct BinaryTreeWithHight *right;
right = (struct BinaryTreeWithHight *)malloc(sizeof(struct BinaryTreeWithHight));
right->height = tmp->height+1;
right->data = tmp->data->right;
InsertQueue(right, queue);
}
}
return 0;
}
//初始化队列
void InitQueue(Queue **queue)
{
*queue=(Queue *)malloc(sizeof(Queue));
(*queue)->top = -1;
(*queue)->length = 0;
}
int main()
{
struct BinaryTreeNode *root;
root = createBinaryTree();
printBinaryTreeFirst(root);
Queue *queue;
InitQueue(&queue);
PrintBinaryTreeByBayer(root,queue);
printf("\n");
}
结果如下: