完全二叉树前中后序->层序

这篇博客探讨了如何将完全二叉树的后序遍历转化为层序遍历。通过深度优先搜索(DFS)策略,提供了一个递归函数实现,该函数根据后序遍历的节点顺序来重建二叉树,并输出层序遍历的结果。这种方法对于理解二叉树的遍历和结构转换具有重要意义。

题目描述

一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树。对于深度为 D 的,有 N 个结点的二叉树,若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点,这样的树就是完全二叉树。

给定一棵完全二叉树的后序遍历,请你给出这棵树的层序遍历结果
如题,当题目给出二叉树的前中后序遍历时,可直接转为层序遍历

void dfs(int i) {
    if (i > n) return;
    
    //scanf("%d", &tree[i]); // 前->层
    dfs(i*2);
    //scanf("%d", &tree[u]); // 中->层
    dfs(i*2+1);
    scanf("%d", &tree[i]); // 后->层
}

参考资料
完全二叉树的层序遍历Luo_LA

#include <stdio.h> #include <stdlib.h> #include <string.h> //状态码定义 #define OK 1 #define ERROR 0 //数据类型定义 typedef int Status; typedef char TElemType; //树节点的数据类型 //结点数据类型定义 typedef struct Tnode *BiTree; typedef struct Tnode{ TElemType data; BiTree left_child,right_child; }Tnode; //函数声明 Status CreatBTpre(BiTree *T); Status DLR(BiTree T); Status midTraverse(BiTree T); Status midTraverse2(BiTree T); Status LRD(BiTree T); void LayerOrder(BiTree T); int depth(BiTree root); int countNoLeafNodes(BiTree root); void visit(TElemType e); //栈的定义(用于中序非递归遍历) #define STACK_INIT_SIZE 100 #define STACK_INCREMENT 10 typedef struct{ BiTree *base; BiTree *top; int stacksize; }Stack; //栈的基本操作 Status InitStack(Stack *S){ S->base = (BiTree *)malloc(STACK_INIT_SIZE * sizeof(BiTree)); if(!S->base){ return ERROR; } S->top = S->base; S->stacksize = STACK_INIT_SIZE; return OK; } Status Push(Stack *S, BiTree node,int visited){ if (S->top - S->base >= S->stacksize){ S->base = (BiTree *)realloc(S->base, (S->stacksize + STACK_INCREMENT) * sizeof(BiTree)); if (!S->base){ return ERROR; } S->top = S->base + S->stacksize; S->stacksize += STACK_INCREMENT; } S->top->node = node; S->top->visited = visited; S->top++; return OK; } Status Pop(Stack *S, BiTree *e){ if (S->top == S->base){ return ERROR; } S->top--; *node = S->top->node; *visited = S->top->visited; return OK; } Status StackEmpty(Stack S){ return S.top == S.base ? OK : ERROR; } // 队列的定义(用于层序遍历) #define QUEUE_INIT_SIZE 100 #define QUEUE_INCREMENT 10 typedef struct QNode{ BiTree data; struct QNode *next; } QNode, *QueuePtr; typedef struct{ QueuePtr front; // 队头指针 QueuePtr rear; // 队尾指针 } Queue; // 队列的基本操作 Status InitQueue(Queue *Q){ Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode)); if (!Q->front){ return ERROR; } Q->front->next = NULL; return OK; } Status EnQueue(Queue *Q, BiTree e){ QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); if (!p){ return ERROR; } p->data = e; p->next = NULL; Q->rear->next = p; Q->rear = p; return OK; } Status DeQueue(Queue *Q, BiTree *e){ if (Q->front == Q->rear){ return ERROR; } QueuePtr p = Q->front->next; *e = p->data; Q->front->next = p->next; if (Q->rear == p){ Q->rear = Q->front; } free(p); return OK; } Status QueueEmpty(Queue Q){ return Q.front == Q.rear ? OK : ERROR; } //前序遍历建树 Status CreatBTpre(BiTree *T){ TElemType ch; scanf(" %c",&ch); if(ch == '#'){ *T = NULL; } else{ *T=(BiTree)malloc(sizeof(Tnode)); if(!*T){ return ERROR; } (*T)->data = ch; CreatBTpre(&(*T)->left_child); CreatBTpre(&(*T)->right_child); } return OK; } //访问节点数据 void visit(TElemType e){ printf("%c ", e); } //先序遍历(递归) Status DLR(BiTree T){ if(T){ visit(T->data); DLR(T->left_child); //递归遍历左子树 DLR(T->right_child); //递归遍历右子树 } return OK; } //中序遍历(非递归1) Status midTraverse(BiTree T){ Stack S; InitStack(&S); BiTree p = T; while(p || !StackEmpty(S)){ if(p){ Push(&S,p,0); p = p->left_child; }else{ Pop(&S,&p,NULL); visit(p -> data); p = p->right_child; } } printf("\n"); return OK; } //中序遍历(非递归2:标记法) Status midTraverse2(BiTree T){ if(!T){ printf("二叉树为空!\n"); return OK; } Stack S; InitStack(&S); //根节点入栈,标记为未访问 Push(&S,T,0); while(!StackEpty(S)){ BiTree curr; int visited; Pop(&S,&curr,&visited); if(visited == 0){ if(curr->right_child){ Push(&S,curr->right_child,0); } Push(&S,curr,1); if(curr->left_child){ Push(&S,curr->left_child,0); } }else{ visit(curr->data); } } printf("\n"); return OK; } //后序遍历(递归) Status LRD(BiTree T){ if(T){ LRD(T->left_child); LRD(T->right_child); visit(T->data); } return OK; } //层序遍历二叉树 void LayerOrder(BiTree T){ if(!T) return; Queue Q; InitQueue(&Q); EnQueue(&Q, T); while(!QueueEmpty(Q)){ BiTree p; DeQueue(&Q,&p); visit(p -> data); if(p->left_child){ EnQueue(&Q,p->left_child); } if(p->right_child){ EnQueue(&Q,p->right_child); } } } //求二叉树的深度 int depth(BiTree root){ if (!root) return 0; int leftDepth = depth(root->left_child); // 左子树深度 int rightDepth = depth(root->right_child); // 右子树深度 return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1; } //求二叉树中非叶子节点个数 int countNonLeafNodes(BiTree root) { if (!root) return 0; if (!root->left_child && !root->right_child) return 0; // 叶子节点,不计入 return 1 + countNonLeafNodes(root->left_child) + countNonLeafNodes(root->right_child); } int main() { int n = 1; // 控制循环继续的标志 BiTree T =NULL; printf("++输入对应数字指令实现相应功能++\n"); printf("********1---创建二叉树********\n"); printf("********2---先序遍历二叉树(递归)********\n"); printf("********3---中序遍历二叉树(非递归1)********\n"); printf("********4---中序遍历二叉树(非递归2)********\n"); printf("********5---后序遍历二叉树(递归)******\n"); printf("********6---层序遍历二叉树******\n"); printf("********7---求二叉树深度******\n"); printf("********8---求二叉树中非叶子结点的个数******\n"); printf("********9---退出******\n"); while (n) { int s; // 菜单选择 printf("请输入指令编号:\n"); scanf("%d", &s); switch (s) { case 1: printf("请输入二叉树前序序列(以#表示空节点):\n"); CreatBTpre(&T); printf("二叉树创建成功!\n"); break; case 2: if(!T){ printf("二叉树为空!\n"); }else{ printf("先序遍历结果:"); DLR(T); printf("\n"); } break; case 3: if (!T){ printf("二叉树为空!\n"); }else{ printf("中序遍历结果(非递归1):"); midTraverse(T); } break; case 4: if(!T){ printf("二叉树为空!\n"); }else{ printf("中序遍历结果(非递归2):"); midTraverse2(T); } break; case 5: if(!T){ printf("二叉树为空!\n"); }else{ printf("后序遍历结果:"); LRD(T); printf("\n"); } break; case 6: if(!T){ printf("二叉树为空!\n"); }else{ printf("层序遍历结果:"); LayerOrder(T); printf("\n"); } break; case 7: if(!T){ printf("二叉树为空,深度为0!\n"); }else{ printf("二叉树的深度为:%d\n",depth(T)); } break; case 8: if(!T){ printf("二叉树为空,非叶子节点个数为0!\n"); }else{ printf("二叉树中非叶子节点的个数为:%d\n",countNonLeafNodes(T)); } case 9: n = 0; printf("程序退出成功,欢迎下次使用\n"); break; default: printf("您输入的指令有误,请重新输入~\n"); break; } } return 0; } 修改错误
最新发布
11-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeSlogan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值