層次遍歷是樹的第四種遍歷方式,使用隊列,可以認爲是廣度優先搜索在樹的應用。
目錄
1.生成本文例子中的樹
本文中創建的樹如下:
其層次遍歷結果是,也可以先打印右節點,再打印左節點,只需要改變入隊的順序即可。
創建樹的代碼,這裏比較簡單直接賦值的形式了,執行完tree就是一顆如上圖的樹
void Create_Tree(TREE_NODE_S* tree)
{
TREE_NODE_S* poll = (TREE_NODE_S*)malloc(8*sizeof(TREE_NODE_S));
int i = 0;
memset(poll,0,8*sizeof(TREE_NODE_S));
for(i = 0; i <= 7;i++)
{
poll[i].data = i+1;
}
memcpy(tree,&poll[0],sizeof(sizeof(TREE_NODE_S)));
tree->leftchild = &poll[1];
tree->rightchild = &poll[5];
poll[1].leftchild = &poll[2];
poll[1].rightchild = &poll[3];
poll[2].leftchild = &poll[4];
poll[5].leftchild = &poll[6];
poll[5].rightchild = &poll[7];
}
2.層次遍歷方式-使用隊列
//樹的層次遍歷其實就是廣度優先搜索,只是這個不用判重,因爲永遠不會重複
void Bfs_print_tree(TREE_NODE_S* tree)
{
QUEUE_T queue = {0};
TREE_NODE_S* node = NULL;
Queue_Init(&queue,50);
Queue_Pushback(&queue,tree);
while(Queue_Is_Empty(&queue) != 1)
{
node = Queue_Pop(&queue);
if(node != NULL)
{
printf("%d ",node->data);
if(node->leftchild != NULL)
Queue_Pushback(&queue,node->leftchild);
if(node->rightchild != NULL)
Queue_Pushback(&queue,node->rightchild);
}
}
}
層次遍歷,及一層層的打印。每個節點出隊就可以打印,並把其左右孩子入列,從左往右打的話,左孩子先入列即可。
3.完整代碼
https://pan.baidu.com/s/1hzWwNf_B0UYl-MF6_-zfIQ
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//樹節點
typedef struct Tree_node
{
int data;
struct Tree_node* leftchild;
struct Tree_node* rightchild;
}TREE_NODE_S;
typedef struct Queue
{
int head;
int tail;
int size;
int cap;
TREE_NODE_S** treenode;
}QUEUE_T;
void Queue_Init(QUEUE_T* queue,int cap)
{
queue->cap = cap;
queue->size = 0;
queue->head = 0;
queue->tail = 0;
queue->treenode = (TREE_NODE_S**)malloc(sizeof(TREE_NODE_S*)*cap);
}
int Queue_Is_Full(QUEUE_T* queue)
{
return (queue->size == queue->cap) ? 1 : 0;
}
int Queue_Is_Empty(QUEUE_T* queue)
{
return (queue->size == 0) ? 1 : 0;
}
void Queue_Pushback(QUEUE_T* queue,TREE_NODE_S* node)
{
if(Queue_Is_Full(queue) != 1)
{
queue->size++;
queue->treenode[queue->tail] = node;
queue->tail = (++queue->tail) % queue->cap;
}
}
TREE_NODE_S* Queue_Pop(QUEUE_T* queue)
{
int res_index = 0;
if(Queue_Is_Empty(queue) !=1)
{
res_index = queue->head;
queue->head = (++queue->head) % queue->cap;
queue->size--;
return queue->treenode[res_index];
}
else
return NULL;
}
void Queue_Destroy(QUEUE_T* queue)
{
int i = 0;
if(queue->cap != 0)
{
for(i = 0; i <= queue->cap - 1;i++)
{
free(queue->treenode[i]);
queue->treenode[i] = NULL;
}
}
}
void Create_Tree(TREE_NODE_S* tree)
{
TREE_NODE_S* poll = (TREE_NODE_S*)malloc(8*sizeof(TREE_NODE_S));
int i = 0;
memset(poll,0,8*sizeof(TREE_NODE_S));
for(i = 0; i <= 7;i++)
{
poll[i].data = i+1;
}
memcpy(tree,&poll[0],sizeof(sizeof(TREE_NODE_S)));
tree->leftchild = &poll[1];
tree->rightchild = &poll[5];
poll[1].leftchild = &poll[2];
poll[1].rightchild = &poll[3];
poll[2].leftchild = &poll[4];
poll[5].leftchild = &poll[6];
poll[5].rightchild = &poll[7];
}
//樹的層次遍歷其實就是廣度優先搜索,只是這個不用判重,因爲永遠不會重複
void Bfs_print_tree(TREE_NODE_S* tree)
{
QUEUE_T queue = {0};
TREE_NODE_S* node = NULL;
Queue_Init(&queue,50);
Queue_Pushback(&queue,tree);
while(Queue_Is_Empty(&queue) != 1)
{
node = Queue_Pop(&queue);
if(node != NULL)
{
printf("%d ",node->data);
if(node->leftchild != NULL)
Queue_Pushback(&queue,node->leftchild);
if(node->rightchild != NULL)
Queue_Pushback(&queue,node->rightchild);
}
}
}
int main()
{
TREE_NODE_S tree = {0};
Create_Tree(&tree);
printf("\n層次遍歷\n");
Bfs_print_tree(&tree);
return 0;
}