二叉树的层序遍历(c)

我们先来了解一下什么是二叉树的层序遍历!

层序遍历的理解

下图是一棵二叉树,

层序遍历这棵二叉树的顺序是:

1→2→3→4→5→6→7,

看图也很简单易懂,

第一层→第二层→第三层。

层序遍历的实现

如果二叉树的结点以数组的方式储存,那就是打印一遍数组就完成了层序遍历。

但是,我们用的是链式结构,难度就会蹭蹭往上涨......

我们实现层析遍历需要使用队列(queue).

队列的特点是先进先出,观察下图的橙色箭头→:

只要入队列的顺序是1234567,那么出队列的顺序也是1234567.

我们就实现了层序遍历。

先上队列的代码,

头文件Queue.h

cpp 复制代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int QDataType;

typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType val;
}QNode;

typedef struct Queue
{
//指向队列头的指针
	QNode* phead;
//指向队列尾的指针
	QNode* ptail;
	int size;
}Queue;

//队列初始化
void QueueInit(Queue* pq);
//销毁队列
void QueueDestroy(Queue* pq);
//在队尾插入元素
void QueuePush(Queue* pq, QDataType x);
//删除队头元素
void QueuePop(Queue* pq);
//队列长度
int QueueSize(Queue* pq);
//返回队头元素的值
QDataType QueueFront(Queue* pq);
//返回队尾元素的值
QDataType QueueBack(Queue* pq);
//判断队列是否为空
bool QueueEmpty(Queue* pq);

源文件Queue.c

cpp 复制代码
#include"Queue.h"

void QueueInit(Queue* pq)
{
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void QueueDestroy(Queue* pq)
{
	assert(pq);
	
	QNode* cur = pq->phead;
	while (cur) {
		QNode* temp = cur->next;
		free(cur);
		cur = temp;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* temp = (QNode*)malloc(sizeof(QNode));
	if (temp == NULL) {
		perror("malloc fail");
		return;
	}
	temp->next = NULL;
	temp->val = x;
	if (pq->ptail == NULL) {
		pq->phead = pq->ptail = temp;
	}
	else
	{
		pq->ptail->next = temp;
		pq->ptail = temp;
	}
	pq->size++;
	
	
}
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->size!=0);
	QNode* temp = pq->phead->next;
	free(pq->phead);
	pq->phead = temp;
	if (pq->phead == NULL) {
		pq->ptail = NULL;
	}
	pq->size--;
}
int QueueSize(Queue* pq) {
	assert(pq);
	return pq->size;
}
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->phead->val;
}
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->ptail);
	return pq->ptail->val;
}
bool QueueEmpty(Queue* pq) {
	assert(pq);
	return pq->size == 0;
}

然后是层序遍历的实现。

cpp 复制代码
void TreeLevelOrder(BTNode* root)
{
	Queue pq;
	QueueInit(&pq);

//根结点先入队列
	if (root)
	{
		QueuePush(&pq, root);
	}

	while (!QueueEmpty(&pq))
	{
//存着队列头的结点
		BTNode* front = QueueFront(&pq);
//删除队列头的节点
		QueuePop(&pq);
//打印队列头结点的值
		printf("%d ", front->data);
//左右节点先后入队列
		if(front->left)
		QueuePush(&pq, front->left);
		if(front->right)
		QueuePush(&pq, front->right);
	}

	QueueDestroy(&pq);
	
}
相关推荐
AI软著研究员3 小时前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish3 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱4 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
地平线开发者20 小时前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮20 小时前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者21 小时前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考21 小时前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习
HXhlx1 天前
CART决策树基本原理
算法·机器学习
Wect1 天前
LeetCode 210. 课程表 II 题解:Kahn算法+DFS 双解法精讲
前端·算法·typescript
颜酱1 天前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法