当前位置:网站首页>扁平数组转树结构实现方式
扁平数组转树结构实现方式
2022-08-01 07:39:00 【nwao7890】
背景
今天遇到一个题,需要将扁平数组转树结构,题目大致如下
将扁平数组转为树结构输出 pid0为根节点,id顺序可能不递增,pid可能不存在于数组内
给定输入
[
{id: 1, name: '111', pid: 0},
{id: 2, name: '222', pid: 1},
{id: 3, name: '333', pid: 1},
{id: 4, name: '444', pid: 3},
{id: 5, name: '555', pid: 4},
]
给定输出:
{
"id": 1,
"name": "111",
"pid": 0,
"children": [
{
"id": 2,
"name": "222",
"pid": 1,
"children": []
},
{
"id": 3,
"name": "333",
"pid": 1,
"children": [
// ...
]
}
]
}
思考
这个题当时用c++没有做出来,一看这个输出就是json格式,应该就是个前端的题,后来一搜果然。
不过用c++肯定也能写就是构造个树,递归去查找比较插入唄。额外支持一下要求的特例。后来还是用c++写了一下最后输出格式没弄。算法可能不是最优,先实现了吧。
写完也没明白用这个前端题来考什么,估计是应变能力吧,还是得加强算法练习,才能遇题不慌不乱。
上代码
由于题目要求,这里可能会存在多棵树(pid不在树内的情况)。
考虑到插入树时,若id不是顺序的,则会产生临时的N棵树,后续还要合并这些树,比较麻烦,就先排一下序,这样除非不在当前树内的,否则都能找到对应节点插入。
这里我们使用了preorder先序遍历的算法,在遍历时,判断pid 和id有无和待插入的元素有关系的,找到了就挂在树上。
有个特殊的情况是待插入元素会成为当前树的根,这里需要处理一下
#include <stdio.h>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
// 节点定义
class onenode
{
public:
int id;
int pid;
std::vector<onenode*> childs;
onenode(int idt, int pidt)
{
id = idt,
pid = pidt;
}
~onenode(){
};
};
// 遍历找位置插入树
onenode* preorder(onenode* node, onenode*tmpnode)
{
if (node == nullptr)
return nullptr;
if (node->id == tmpnode->pid)
{
node->childs.push_back(tmpnode);
return node;
}
if (node->pid == tmpnode->id)
{
tmpnode->childs.push_back(node);
return tmpnode;
}
for (auto it = node->childs.begin(); it != node->childs.end(); it++)
{
onenode* tmpnode1 = preorder(*it, tmpnode);
if (tmpnode1 != nullptr)
return tmpnode1;
}
return nullptr;
}
int tryaddtotree(onenode* tmproot, onenode* cur, std::map<int, onenode*>& nodetree)
{
onenode* tmpptr = preorder(tmproot, cur);
if (tmpptr != nullptr)
{
if (tmpptr == cur)
{
for (auto it = tmpptr->childs.begin(); it != tmpptr->childs.end(); it++)
{
if ((*it)== tmproot)
{
return 1;// 新节点是root了 需要换root
}
}
}
return 2;// 树里的一个子节点
}
else
{
//没加进去需要新增树了
return 3;
}
}
int preprint(onenode* root)
{
if (root == nullptr)
return 0;
printf("id: %d, pid %d\n", root->id, root->pid);
for (auto it = root->childs.begin(); it != root->childs.end(); it++)
{
preprint(*it);
}
return 0;
}
int main()
{
std::map<int, onenode*> nodetree;
//std::vector<onenode> srcdata = {
{1,0},{2,1},{3,1},{4,3},{5,4},{6, 99}};
std::vector<onenode> srcdata = {
{
1,0},{
4,3},{
5,4},{
2,1},{
3,1},{
6, 99}};
for (auto it = srcdata.begin(); it != srcdata.end(); it++)
{
printf("%d %d\n", (*it).id, (*it).pid);
}
//for (auto it : srcdata)
//{ printf("%d %d\n", it.id, it.pid);}
sort(srcdata.begin(), srcdata.end(),[](onenode a, onenode b){
return a.id < b.id;
});
for (auto it = srcdata.begin(); it != srcdata.end(); it++)
{
onenode* willaddnode = &(*it);
if (nodetree.empty())
{
nodetree.emplace(std::make_pair(willaddnode->id, willaddnode));
continue;
}
bool added = false;
for (auto itm = nodetree.begin(); itm != nodetree.end(); itm++)
{
onenode* tmproot = itm->second;
int addret = tryaddtotree(tmproot, willaddnode, nodetree);
if (addret == 1)
{
nodetree.emplace(std::make_pair(willaddnode->id, willaddnode));
nodetree.erase(tmproot->id);
added = true;
}
else if (addret == 2)
{
added = true;
}
if (added)
break;
}
if (!added)
{
nodetree.emplace(std::make_pair(willaddnode->id, willaddnode));
}
}
for (auto itm = nodetree.begin(); itm != nodetree.end(); itm++)
{
printf("*****\n");
preprint(itm->second);
}
return 0;
}
总结
虽然是个前端题不过是涉及到树的遍历,用c++还是可以写的,平时还是需要多练习
还有就是这个总是提示大于10字的不足10行?
边栏推荐
- Centos install php7.4, build hyperf, forward RDS
- I have three degrees, and I have five faces. I was "confessed" by the interviewer, and I got an offer of 33*15.
- How to use Photoshop to composite star trail photos, post-processing method of night sky star trail photos
- Offer刷题——1
- 图像基本操作的其他内容
- R语言使用gt包和gtExtras包优雅地、漂亮地显示表格数据:gtExtras包的pad_fn函数与gt::fmt函数一起用于填充包含数值的特定列、对数据列的数值进行十进制对齐(从小数点对齐)
- 七夕来袭——属于程序员的浪漫
- R语言使用tidyquant包的tq_transmute函数计算持有某只股票的天、月、周收益率、ggplot2使用条形图可视化股票月收益率数据、使用百分比显示Y轴坐标数据、使用不同的色彩表征正负收益率
- JSON 与 JS 对象的区别
- pytest接口自动化测试框架 | 集成Allure测试报告
猜你喜欢

special day to remember

22牛客多校1 J.Serval and Essay (启发式合并)

电磁兼容简明教程(6)测试项目

Datagrip error "The specified database userpassword combination is rejected..."Solutions

类似 MS Project 的项目管理工具有哪些

MATLAB程序设计与应用 2.5 MATLAB运算

LabVIEW中局部变量和全局变量的分配

Electromagnetic compatibility introductory tutorial (6) test project

USB 协议 (二) 术语

"By sharing" northwestern university life service | | bytes a second interview on three sides by HR
随机推荐
Golang:go模版引擎的使用
支付宝如何生成及配置公钥证书
阿里三面:MQ 消息丢失、重复、积压问题,该如何解决?
pytest interface automation testing framework | parametrize source code analysis
Data organization -- singly linked list of the linear table
Three aspects of Ali: How to solve the problem of MQ message loss, duplication and backlog?
The log causes these pits in the thread block, you have to prevent
NIO programming
华为深度学习课程第九章——卷积神经网络以及案例实践
22牛客多校1 I. Chiitoitsu (概率dp)
How to use Photoshop to composite star trail photos, post-processing method of night sky star trail photos
七夕来袭——属于程序员的浪漫
华为深度学习课程第六、七章
JVM:运行时数据区-PC寄存器(程序计数器)
"By sharing" northwestern university life service | | bytes a second interview on three sides by HR
POJ2421道路建设题解
POJ2031空间站题解
小程序通过云函数操作数据库【使用get取数据库】
Golang:go开启web服务
三维坐标系距离