赞
踩
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。
在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
- 7
- 2 3 1 5 7 6 4
- 1 2 3 4 5 6 7
4 1 6 3 5 7 2
按照一般的思路,首先应该想办法根据后序遍历序列post和中序遍历序列in把二叉树构造出来
选择用二叉链表作为树的存储结构,定义如下
- typedef struct Node {
- int data;
- struct Node* left;
- struct Node* right;
- }Tree;
构造二叉树的第一步是要找到根节点root,就是后序遍历序列的最后一个元素post[n-1]
需要在中序遍历序列中找到根节点的位置,然后再分别递归构造左子树和右子树
BuildTree函数中的参数依次表示的是后序遍历序列,中序遍历序列和结点个数
- Tree* BuildTree(int post[], int in[], int n) {
- if (n == 0)
- return NULL;
- int root = 0;
- while (in[root] != post[n - 1])
- root++; //找到根节点
- Tree* T = (Tree*)malloc(sizeof(Tree));
- T->data = in[root];
- int m = root;
- T->left = BuildTree(post, in, m);
- T->right = BuildTree(post + m, in + m + 1, n - m - 1);
- return T;
- }
至此,已经能够将二叉树构造出来了,接下来就是要层次遍历这课二叉树
以下图这棵二叉树为例,实现利用队列完成层次遍历
根结点A入队,A
队列非空,如果有左右孩子,将其左右孩子依次入队
队头结点A出队,将A的左右孩子BC入队,BC
队头结点B出队,将B的左右孩子DE入队,CDE
队头结点C出队,将C的左右孩子FG入队,DEFG
队头结点D出队,将D的左右孩子HI入队,EFGHI
队头结点E出队,E没有左右孩子,无新元素入队,FGHI
队头结点F出队,将F左右孩子JK入队,GHIJK
队头结点G出队,将G的左孩子L入队,HIJKL
队头结点H出队,H没有左右孩子,无新元素入队,IJKL
队头结点I出队,I没有左右孩子,无新元素入队,JKL
队头结点J出队,J没有左右孩子,无新元素入队,KL
队头结点K出队,K没有左右孩子,无新元素入队,L
队头结点L出队,L没有左右孩子,无新元素入队,此时队空,结束遍历
出队的顺序即为层次遍历的顺序:ABCDEFGHJKL
❗️因为是将出队结点的左右孩子入队,所以在定义队列的时候data类型应该是Tree
- typedef struct LinkNode {
- Tree* data;
- struct LinkNode* next;
- }LinkNode;
-
- typedef struct {
- LinkNode* front, * rear;
- }Queue;
最核心的层次遍历的代码如下
- void LevelOrder(Tree* t) {
- Queue* q = (Queue*)malloc(sizeof(Queue));
- initQueue(q);
- enQueue(q, t);
- while (q->front != NULL) {
- Tree* node = deQueue(q);
- printf("%d", node->data);
- if (node->left) {
- enQueue(q, node->left);
- }
- if (node->right) {
- enQueue(q, node->right);
- }
- /*为满足题目输出的格式要求,只有队列非空的时候才输出空格
- 这样输出最后一个出队元素之后就不会有空格啦*/
- if (q->front != NULL) {
- printf(" ");
- }
- }
- }
最后完整代码如下
- #include <stdio.h>
- #include <stdlib.h>
-
- typedef struct Node {
- int data;
- struct Node* left;
- struct Node* right;
- }Tree;
-
- typedef struct LinkNode {
- Tree* data;
- struct LinkNode* next;
- }LinkNode;
-
- typedef struct {
- LinkNode* front, * rear;
- }Queue;
-
- void initQueue(Queue* q) {
- q->front = q->rear = NULL;
- }
-
- void enQueue(Queue* q, Tree* x) {
- LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
- s->data = x;
- s->next = NULL;
- if (q->rear == NULL) {
- q->front = q->rear = s;
- } else {
- q->rear->next = s;
- q->rear = s;
- }
- }
-
- Tree* deQueue(Queue* q) {
- if (q->front == NULL)
- return NULL;
- LinkNode* p = q->front;
- Tree* x = p->data;
- q->front = p->next;
- if (q->front == NULL) {
- q->rear = NULL;
- }
- free(p);
- return x;
- }
-
- Tree* BuildTree(int post[], int in[], int n) {
- if (n == 0)
- return NULL;
- int root = 0;
- while (in[root] != post[n - 1])
- root++; //找到根节点
- Tree* T = (Tree*)malloc(sizeof(Tree));
- T->data = in[root];
- int m = root;
- T->left = BuildTree(post, in, m);
- T->right = BuildTree(post + m, in + m + 1, n - m - 1);
- return T;
- }
-
- void LevelOrder(Tree* t) {
- Queue* q = (Queue*)malloc(sizeof(Queue));
- initQueue(q);
- enQueue(q, t);
- while (q->front != NULL) {
- Tree* node = deQueue(q);
- printf("%d", node->data);
- if (node->left) {
- enQueue(q, node->left);
- }
- if (node->right) {
- enQueue(q, node->right);
- }
- /*为满足题目输出的格式要求,只有队列非空的时候才输出空格
- 这样输出最后一个出队元素之后就不会有空格啦*/
- if (q->front != NULL) {
- printf(" ");
- }
- }
- }
-
- int main() {
- int n;
- scanf("%d", &n);
- int post[n], in[n];
- for (int i = 0; i < n; ++i) {
- scanf("%d", &post[i]);
- }
- for (int i = 0; i < n; ++i) {
- scanf("%d", &in[i]);
- }
- int postIndex = n - 1;
- Tree* t = BuildTree(post, in, n);
- LevelOrder(t);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。