二叉树的遍历分为BFS和DFS两种大类
下面完整实现BFS遍历二叉树
* 例如二叉树
* 1
* / \
* 2 3
* /\
* 4 5
BFS遍历结果:1-2-3-4-5
具体的代码实现:
方法一、采用递归遍历的方法实现
// Recursive C program for level order traversal of Binary Tree
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct node
{
int data;
struct node* left, *right;
};
/* Function protoypes */
void printGivenLevel(struct node* root, int level);
int height(struct node* node);
struct node* newNode(int data);
/* Function to print level order traversal a tree
* 方法一:
* 方法二见05
* */
void printLevelOrder(struct node* root)
{
int h = height(root);
int i;
for (i=1; i<=h; i++)
printGivenLevel(root, i);
}
/* Print nodes at a given level */
void printGivenLevel(struct node* root, int level)
{
if (root == NULL)
return;
if (level == 1)
printf("%d ", root->data);
else if (level > 1)
{
//递归调用
printGivenLevel(root->left, level-1);
printGivenLevel(root->right, level-1);
}
}
/* Compute the "height" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the height of each subtree */
int lheight = height(node->left);
int rheight = height(node->right);
/* use the larger one */
if (lheight > rheight)
return(lheight+1);
else return(rheight+1);
}
}
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newNode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
/* Driver program to test above functions*/
int main()
{
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
printf("Level Order traversal of binary tree is \n");
printLevelOrder(root);
return 0;
}
输出:
Level Order traversal of binary tree is
1 2 3 4 5
方法二、采用先进先出的队列实现
#include <stdio.h>
#include <stdlib.h>
#define MAX_Q_SIZE 500
/*构造树的结点
* 一个树有一个数据域,一个左孩子指针,一个右孩子指针
*/
struct node {
int data;
struct node *left;
struct node *right;
};
/*几个方法原型*/
struct node **createQueue(int *, int *);//创建一个队列,用双指针
void enQueue(struct node **, int *, struct node *);//第一个参数是双指针
struct node *deQueue(struct node **, int *);//出队
/*创建一个队列,这个队列是以struct node属性的数组存储的
* 此队列,相当于一个数据类型是struct node的数组
*/
struct node **createQueue(int *front, int *rear) {
//为队列申请内存,这里用双指针
struct node **queue = (struct node **) malloc(sizeof(struct node *)*MAX_Q_SIZE);
//初始化的时候,一定记得*front = *rear处于同一位置
*front = *rear = 0;
return queue;
}
/*入队,尾入*/
void enQueue(struct node **queue, int *rear, struct node *new_node) {
queue[*rear] = new_node;//现将结点放到*rear的位置
(*rear)++;//加一
}
/*出队,头出*/
struct node *deQueue(struct node **queue, int *front)
{
(*front)++;
return queue[*front - 1];
}
/*通过给定的数据域,直接构造一个树的结点*/
struct node * newNode(int data){
//要构造新节点,首先要想到的就是为结点申请内存
struct node *node = (struct node *)malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
/*给一个二叉树,要层次打印出各个结点,通过队列的方式实现*/
void printLevelOrder(struct node* root){
//定义变量
int front,rear;
//创建队列,传地址&
struct node **queue = createQueue(&front,&rear);
//创建一个临时的树结点,将root指针指向的结点地址赋值指针temp_node
//因为root已经是指针类型,所以可以直接赋值
struct node *temp_node = root;
//遍历。指针temp_node处的结点存在
while (temp_node){
//打印
printf("%d ",temp_node->data);
//如果左孩子存在,左孩子入队
if (temp_node->left){
enQueue(queue,&rear,temp_node->left);
}
//如果右孩子存在,右孩子入队
if (temp_node->right){
enQueue(queue,&rear,temp_node->right);
}
//出队一个结点指针,使他赋值给temp_node指针
temp_node = deQueue(queue,&front);
}
}
/**
* BFS 广度优先遍历
* 对于每个树的结点来说:
* 第一次访问这个结点后,就将这个结点的的孩子结点放入先进先出的队列中
* @return
*/
int main() {
//初始化一个根结点
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
printf("Level Order traversal of binary tree is \n");
printLevelOrder(root);
return 0;
}
输出:
Level Order traversal of binary tree is
1 2 3 4 5
以上两种方式,第二种相对来说比较容易理解一些。