当前位置: 首页 > news >正文

[二叉树]关于前序、中序、后序、层序序列

一些概念

满二叉树(Full Binary Tree) 和 完全二叉树(Complete Binary Tree) 是两个不同的概念


🟥 满二叉树(Full Binary Tree)->必须完全填满

  • 每个非叶子节点都有两个孩子
  • 或者说:每个节点要么是叶子节点,要么有 两个孩子
  • 举例:
        A/   \B     C/ \   / \D   E F   G

🟨 完全二叉树(Complete Binary Tree)->最后一层可以不填满

  • 从上到下、从左到右依次填满
  • 只有最后一层可以不满,但必须从左往右连续填充
  • 举例:
        A/   \B     C/ \   / D   E F  

存树方式

一共n个节点
开一个数组int tree[n<<2] 4倍大小
node<<1表示左子树
node<<1|1表示右子树

tree[]中存的就是层序序列

GPT的介绍

✅ 哪些组合能唯一建树?

提供的遍历是否能唯一建树?说明
中序 + 前序✅ 能最常见、能唯一建树
中序 + 后序✅ 能也可以唯一建树
前序 + 后序❌ 一般不行除非是满二叉树才行
只有一种遍历❌ 不能信息不够,多种可能的树

必须有一个中序序列 才能唯一确定一颗二叉树

🤔 那如果是“完全二叉树”呢?

如果你明确知道这棵树是完全二叉树,那情况就不一样了:

✅ 只要你给出:
  • 前序遍历 + 完全二叉树信息 👉 可以唯一建树
  • 后序遍历 + 完全二叉树信息 👉 可以唯一建树
  • 中序遍历 + 完全二叉树信息 👉 可以唯一建树
  • 层序遍历 👉 本身就能唯一确定完全二叉树

🌳 完全二叉树的关键特点是:节点编号是固定的!

比如:

1 -> root
2 -> left of root
3 -> right of root
4 -> left of node 2
...

这就是你前面用 node<<1node<<1|1 的核心!


✅ 小结

遍历方式是否能唯一建树?
前序+中序 / 中序+后序
层序 + 完全二叉树
前序/后序 + 完全二叉树结构
只有一种遍历
前序+后序❌(除非满二叉树)

如何通过给定的序列确定一颗树?

一、中序+X

  • X要么是先序 要么是后序
  • 核心就是通过X确定根在哪里
  • 再从中序中找到根的位置
  • 左右两边就是左右子树 再递归左右两边建树

1.中序+后序->先序

const int N = 10;
int in[N],post[N],tree[N<<2];
int n;//inl表示当前子树在中序序列中的起点 postl 后序序列起点 
//len表示当前子树长度 (节点个数)
//pos用来分配节点在tree数组中的下标(pos<<1 左子树,pos<<1|1 右子树)
void build(int inl,int postl,int len,int pos){int root = post[postl+len-1];tree[pos]=root;if(len==1) return;int i=0;while(in[inl+i]!=root) i++;//在中序序列中找到根的下标int l=i,r=len-i-1;//l,r为左右子树长度//左右子树非空就递归建树if(l) build(inl, postl,l,pos<<1);if(r) build(inl+l+1,postl+l,r,pos<<1|1);
}void preprint(int node){if(node>n*4||tree[node]==0){return;}cout<<(char)(tree[node]-1+'A');preprint(node<<1);preprint(node<<1|1);
}void solve(){string s;cin>>s;for(int i=0;i<s.size();i++){in[i]=s[i]-'A'+1;}cin>>s;for(int i=0;i<s.size();i++){post[i]=s[i]-'A'+1;}n=s.size();build(0,0,n,1);preprint(1);
}

中序+先序->后序

const int N = 2010;
int tree[N<<2],pre[N],in[N];
int n;void build(int inl,int prel,int len,int pos){int root=pre[prel];tree[pos]=root;if(len==1) return;int i=0;while(in[inl+i]!=root) i++;int l=i,r=len-i-1;if(l) build(inl,prel+1,l,pos<<1);if(r) build(inl+l+1,prel+l+1,r,pos<<1|1);
}void postprint(int node){if(tree[node]==-1){return;}postprint(node<<1);postprint(node<<1|1);cout<<(char)(tree[node]-1+'A');
}void solve(){string s;while(cin>>s){n=s.size();memset(tree,-1,sizeof tree);memset(pre,0,sizeof pre);memset(in,0,sizeof in);for(int i=0;i<s.size();i++){pre[i]=s[i]-'A'+1;}cin>>s;for(int i=0;i<s.size();i++){in[i]=s[i]-'A'+1;}build(0,0,n,1);postprint(1);cout<<endl;}
}

给定完全二叉树+某一种序列

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;const int MAXN = 2005;
char tree[MAXN];  // 用数组模拟树,编号从1开始
string s;         // 前序输入的字符串(含#)
int pos;          // 当前在字符串中处理到的位置// 建树,参数是当前处理到的节点编号
void build(int node) {if (pos >= s.size()) return;if (s[pos] == '#') {pos++; // 空节点,跳过return;}tree[node] = s[pos++]; // 建立当前节点build(node << 1);      // 左儿子build(node << 1 | 1);  // 右儿子
}// 中序遍历
void inOrder(int node) {if (tree[node] == 0) return;inOrder(node << 1);cout << tree[node];inOrder(node << 1 | 1);
}// 后序遍历
void postOrder(int node) {if (tree[node] == 0) return;postOrder(node << 1);postOrder(node << 1 | 1);cout << tree[node];
}// 层序遍历
void levelOrder(int root) {queue<int> q;if (tree[root]) q.push(root);while (!q.empty()) {int u = q.front(); q.pop();cout << tree[u];if (tree[u << 1]) q.push(u << 1);if (tree[u << 1 | 1]) q.push(u << 1 | 1);}
}void levelOrder(){//这样也可以 因为tree中存的就是层序序列int n=s.size();for(int i=1;i<n*4;i++){if(tree[i]) cout<<tree[i];}
}
int main() {while (cin >> s) {memset(tree, 0, sizeof(tree));pos = 0;build(1); // 从1号节点开始建树inOrder(1);cout << " ";postOrder(1);cout << " ";levelOrder(1);cout << endl;}return 0;
}

先序

void build(int node) {if (pos >= s.size()) return;if (s[pos] == '#') {pos++; // 空节点,跳过return;}tree[node] = s[pos++]; // 建立当前节点build(node << 1);      // 左儿子build(node << 1 | 1);  // 右儿子
}

中序

gpt写的 不太懂

string in;
int tree[N<<2];
int build( int& index, int l, int r) {if (l > r) return -1; // 递归出口// 选择当前节点int mid = (l + r) / 2;if (in[mid] == '#') {return -1; // 当前节点为空}// 生成当前节点,并填充到树中int node = index++;tree[node] = in[mid] - '0'; // 假设树节点的值为数字字符// 递归构建左子树int left = build(index, l, mid - 1);// 递归构建右子树int right = build(index, mid + 1, r);return node;
}

相关文章:

  • 【机器学习】决策树算法中的 “黄金指标”:基尼系数深度剖析
  • w~视觉~3D~合集2
  • C# foreach 循环中获取索引的完整方案
  • VIN解析API开发指南:从年检报告构建智能定损系统
  • [创业之路-377]:企业法务 - 有限责任公司与股份有限公司的优缺点对比
  • 【KWDB 创作者计划】KWDB 2.2.0深度解析:架构设计、性能优化与企业级实践全指南
  • Python 爬虫如何伪装 Referer?从随机生成到动态匹配
  • Kotlin集合全解析:List和Map高频操作手册
  • 01-STM32基本知识点和keil5的安装
  • Cyber SpaceGuidance网安学习指南见解
  • GraphQL接口采集:自动化发现和提取隐藏数据字段
  • C#抽象类和虚方法的作用是什么?
  • [数据结构]树和二叉树
  • 来啦,烫,查询达梦表占用空间
  • 鸣潮赞妮技能机制解析 鸣潮赞妮配队推荐
  • Docker 部署 MySQL 数据库
  • LeetCode 第 262 题全解析:从 SQL 到 Swift 的数据分析实战
  • 正向代理和反向代理
  • 【VS Code】打开远程服务器Docker项目或文件夹
  • FramePack V2版 - 支持首尾帧生成,支持LoRA,支持批量,支持50系显卡,一个强大的AI视频生成软件 本地一键整合包下载
  • 河南省鹤壁市人大常委会副主任李杰接受审查调查
  • 继加州后,美国又有11州起诉特朗普政府滥用关税政策“违法”
  • 甘肃省政府原副省长赵金云严重职务违法被开除公职
  • 书信里的宋人|忠奸难辨的夏竦
  • 正荣地产旗下“H20正荣2”债未能于宽限期内支付分期偿付款,尚未就新兑付方案达成一致
  • 夜读丨秦腔里的乡魂