树的深度优先遍历和广度优先遍历
介绍
本文主要介绍的是 n 叉树的DFS和BFS实现,用到了递归和迭代
树的构造
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXD 3
struct treeNode
{
int data;
struct treeNode *next[MAXD];
};
深度优先遍历 DFS
Deepth First Search
主要内容是:一直遍历直到树底
运用到的思想是递归(也可用栈实现)
前序遍历
递归实现
void VISIT(struct treeNode *t)
{
printf("%d ", t->data);
}
// 运用递归实现
void DFStree(struct treeNode *root)
{
if (root != NULL)
{
VISIT(root);
for (int i = 0; i < MAXD; i++)
{
if (root->next[i] != NULL)
{
DFStree(root->next[i]);
}
}
}
}
栈实现
首先构造栈
struct Stack
{
int capacity;
int top;
struct treeNode **array;
};
struct Stack *initStack(int cap)
{
struct Stack *ret = (struct Stack *)malloc(sizeof(struct Stack));
ret->capacity = cap;
ret->top = -1;
ret->array = (struct treeNode **)malloc(cap * sizeof(struct treeNode *));
return ret;
}
void push(struct Stack *s, struct treeNode *t)
{
s->array[++s->top] = t;
}
void pop(struct Stack *s)
{
s->top--;
}
struct treeNode *top(struct Stack *s)
{
return s->array[s->top];
}
bool isEmpty(struct Stack *s)
{
return s->top == -1;
}
然后是 DFS 实现
void DFStree(struct treeNode *root)
{
if (root != NULL)
{
struct Stack *s = initStack(20);
push(s, root);
while (!isEmpty(s))
{
struct treeNode *tmp = top(s);
pop(s);
VISIT(tmp);
for (int i = MAXD - 1; i >= 0; i--)
{
if (tmp->next[i] != NULL)
{
push(s, tmp->next[i]);
}
}
}
}
}
后序遍历
递归实现
遍历的时候交换了一下顺序
void VISIT(struct treeNode *t)
{
printf("%d ", t->data);
}
// 运用递归实现
void DFStree(struct treeNode *root)
{
if (root != NULL)
{
for (int i = 0; i < MAXD; i++)
{
if (root->next[i] != NULL)
{
DFStree(root->next[i]);
}
}
VISIT(root);
}
}
栈实现
在这个实现中,我们创建了两个栈来帮助进行后序遍历。第一个栈stack1
用于存储节点,第二个栈stack2
用于存储按照后序遍历顺序的节点。最后从stack2
中弹出并访问每个节点。这样就完成了n叉树的迭代后序遍历。
void DFStree(struct treeNode *t)
{
if (t == NULL)
return;
struct Stack *stack1 = initStack(100); // 主栈
struct Stack *stack2 = initStack(100); // 辅助栈
push(stack1, t);
while (!isEmpty(stack1))
{
struct treeNode *node = top(stack1);
pop(stack1);
push(stack2, node);
for (int i = 0; i < MAXD; i++)
{
if (node->next[i])
{
push(stack1, node->next[i]);
}
}
}
while (!isEmpty(stack2))
{
struct treeNode *node = top(stack2);
pop(stack2);
VISIT(node);
}
free(stack1->array);
free(stack1);
free(stack2->array);
free(stack2);
}
广度优先遍历 BFS
Breadth First Search
主要思想是:按每层进行遍历
运用到的思想是队列
首先构造队列
struct Queue
{
int front;
int last;
int capacity;
int num;
struct treeNode **array;
};
struct Queue *initQueue(int cap)
{
struct Queue *ret = (struct Queue *)malloc(sizeof(struct Queue));
ret->num = 0;
ret->capacity = cap;
ret->array = (struct treeNode **)malloc(cap * sizeof(struct treeNode *));
ret->front = 0;
ret->last = cap - 1;
return ret;
}
bool isEmpty(struct Queue *q)
{
if (q->num == 0)
{
return true;
}
else
{
return false;
}
}
void enQueue(struct Queue *q, struct treeNode *t)
{
q->last = (q->last + 1) % q->capacity;
q->array[q->last] = t;
q->num++;
}
struct treeNode *deQueue(struct Queue *q)
{
struct treeNode *tmp = q->array[q->front];
q->front = (q->front + 1) % q->capacity;
q->num--;
return tmp;
}
然后是 BFS 的实现
void VISIT(struct treeNode *t)
{
printf("%d ", t->data);
}
// 运用队列实现
void BFStree(struct Queue *q, struct treeNode *root)
{
if (root != NULL)
{
enQueue(q, root);
while (!isEmpty(q))
{
struct treeNode *tmp = deQueue(q);
VISIT(tmp);
for (int i = 0; i < MAXD; i++)
{
if (tmp->next[i] != NULL)
{
enQueue(q, tmp->next[i]);
}
}
}
}
}