概念:
二叉树的层序遍历是指,访问结点是按层自上而下进行访问,每一层从左到右进行访问。
如下图所示:
层序遍历过程就是:
A - B - C - D - E - F - G - H - I - J - K
层序遍历的算法设计思想:
层序遍历可以借助队列进行实现,在遍历开始时,将根结点存入队列,循环取出队首元素,访问队首元素的值,然后如果队首结点的左孩子不为空,即存储左孩子结点,如果右孩子不为空即存入右孩子,顺序不可变!直至队列为空位置,遍历也就结束了。
注意:对于初学者或者是想要了解底层实现的同学来说,用到的队列和树最好是自己定义去实现,中间涉及到的指针值得学习,而不用容器实现。
算法实现:
本文用到的是链队列结构。
1.定义二叉树结点结构:
typedef struct BiTNode {
int data;
struct BiTNode* lchild, * rchild;
}*BiTree;
2.定义队列结点结构:
typedef struct MyQueueNode {
BiTNode* data;
struct MyQueueNode* next;
};
3.定义队列结构:
typedef struct myque {
MyQueueNode* front;
MyQueueNode* rear;
}*Queue;
4.手动创建二叉树:
void createtree(BiTree& T) {
T = new BiTNode;
T->data = 1;
BiTNode* p1 = new BiTNode;
p1->data = 2;
BiTNode* p2 = new BiTNode;
p2->data = 3;
BiTNode* p3 = new BiTNode;
p3->data = 4;
BiTNode* p4 = new BiTNode;
p4->data = 5;
BiTNode* p5 = new BiTNode;
p5->data = 6;
T->lchild = p1;
T->rchild = p2;
p1->lchild = p3;
p1->rchild = p4;
p4->lchild = nullptr;
p4->rchild = nullptr;
p3->lchild = nullptr;
p3->rchild = nullptr;
p2->lchild = p5;
p2->rchild = nullptr;
p5->lchild = nullptr;
p5->rchild = nullptr;
}
5.队列初始化:
void InitQueue(Queue& Q) {
Q->front = Q->rear = new MyQueueNode;
Q->front->next = NULL;
}
6.队列判空:
bool isempty(Queue Q) {
if (Q->front == Q->rear) return true;
else return false;
}
7.入队操作:
void EnQueue(Queue& Q, BiTree T) {
MyQueueNode* s = new MyQueueNode;
s->data = T;
Q->rear->next = s;
Q->rear = s;
s->next = NULL;
}
8.出队操作:
void Dequeue(Queue& Q, BiTNode* &p) {
MyQueueNode* s = new MyQueueNode;
s = Q->front->next;
p = s->data;
Q->front->next = s->next;
if (Q->rear == s) //这里注意最后一个结点需要单独做判断,否则逻辑错误。
Q->front = Q->rear;
}
9.层序遍历的核心代码:
void visit(BiTree T) {
Queue Q = new myque;
InitQueue(Q);
EnQueue(Q, T);
while (!isempty(Q))
{
BiTree p = new BiTNode;
Dequeue(Q,p);
cout << p->data << " ";
if (p->lchild != NULL) EnQueue(Q, p->lchild);
if (p->rchild != NULL) EnQueue(Q, p->rchild);
}
}
整体代码:
#include<iostream>
using namespace std;
typedef struct BiTNode {
int data;
struct BiTNode* lchild, * rchild;
}*BiTree;
typedef struct MyQueueNode {
BiTNode* data;
struct MyQueueNode* next;
};
typedef struct myque {
MyQueueNode* front;
MyQueueNode* rear;
}*Queue;
void createtree(BiTree& T) {
T = new BiTNode;
T->data = 1;
BiTNode* p1 = new BiTNode;
p1->data = 2;
BiTNode* p2 = new BiTNode;
p2->data = 3;
BiTNode* p3 = new BiTNode;
p3->data = 4;
BiTNode* p4 = new BiTNode;
p4->data = 5;
BiTNode* p5 = new BiTNode;
p5->data = 6;
T->lchild = p1;
T->rchild = p2;
p1->lchild = p3;
p1->rchild = p4;
p4->lchild = nullptr;
p4->rchild = nullptr;
p3->lchild = nullptr;
p3->rchild = nullptr;
p2->lchild = p5;
p2->rchild = nullptr;
p5->lchild = nullptr;
p5->rchild = nullptr;
}
void InitQueue(Queue& Q) {
Q->front = Q->rear = new MyQueueNode;
Q->front->next = NULL;
}
bool isempty(Queue Q) {
if (Q->front == Q->rear) return true;
else return false;
}
void EnQueue(Queue& Q, BiTree T) {
MyQueueNode* s = new MyQueueNode;
s->data = T;
Q->rear->next = s;
Q->rear = s;
s->next = NULL;
}
void Dequeue(Queue& Q, BiTNode* &p) {
MyQueueNode* s = new MyQueueNode;
s = Q->front->next;
p = s->data;
Q->front->next = s->next;
if (Q->rear == s)
Q->front = Q->rear;
}
void visit(BiTree T) {
Queue Q = new myque;
InitQueue(Q);
EnQueue(Q, T);
while (!isempty(Q))
{
BiTree p = new BiTNode;
Dequeue(Q,p);
cout << p->data << " ";
if (p->lchild != NULL) EnQueue(Q, p->lchild);
if (p->rchild != NULL) EnQueue(Q, p->rchild);
}
}
int main() {
BiTree T;
createtree(T);
visit(T);
return 0;
}
执行结果:
总结:
上述代码还不是非常完美,比如缺少队列的销毁,树的销毁等等,上述代码只是实现了层序遍历的算法。如需完善,读者自行更改。