問題:
如上二叉樹,請按層遍歷,每層一行,遍歷結果如下:
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");
}
結果如下: