二叉树的广度优先搜索-层次遍历
程序员文章站
2022-06-16 12:13:46
...
层次遍历是树的第四种遍历方式,使用队列,可以认为是广度优先搜索在树的应用。
目录
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;
}