![]() |
#2
Jonny02012020-08-31 02:10
如果我没有理解错的话, 感觉就是很普通的树结构, 不过每一层的节点类型都不同罢了
其实你自己的方法也很不错, 差不多就是这样 : ![]() struct B; struct C; struct A { T value; B *next; }; struct B { T value; C *next; }; struct C { T value; }; 平时写的链表 next 的类型都是一样的, 上面只不过是 next 的类型和 this 的类型不一样 我假设 A 层不可以直接访问 C 层, 需要通过 B 层作为中介. 那么 A 映射到 B, B 下面是 C. 那么可以用标准库提供的 map, 我想应该用 std::unordered_map using head_type = std::unordered_multimap<volatile A, std::unordered_multimap<volatile B, C>>; 这样就免去了自己写插入删除的麻烦. 但是缺点就是所有标准库提供的 map 中 key_type 默认带有 const 属性, 所以需要加一个 volatile, 方便修改 但是由于后期会增加层数, 所以类似于这种类型 std::unordered_multimap<volatile A, std::unordered_multimap<volatile B, std::unordered_multimap<volatile C, D>>> 会越写越长. 考虑元编程, 可以在写别名的时候少写一些 : ![]() #include <iostream> #include <unordered_map> using namespace std; template <typename ...> struct map_type; template <typename ...Ts> using map_t = typename map_type<Ts...>::type; template <typename T, typename U> struct map_type<T, U> { using type = std::unordered_multimap<add_volatile_t<T>, U>; }; template <typename T, typename U, typename ...Ts> struct map_type<T, U, Ts...> { using type = std::unordered_multimap<add_volatile_t<T>, map_t<U, Ts...>>; }; struct A {}; struct B {}; struct C {}; struct D {}; struct E {}; struct F {}; int main(int argc, char *argv[]) { cout << is_same_v<map_t<A, B, C>, std::unordered_multimap<volatile A, std::unordered_multimap<volatile B, C>>> << endl; //true cout << is_same_v<map_t<A, B, C, D, E, F>, std::unordered_multimap<volatile A, std::unordered_multimap<volatile B, std::unordered_multimap<volatile C, std::unordered_multimap<volatile D, std::unordered_multimap<volatile E, F>>>>>> << endl; //true } 只要能够表示出来, 图像界面操作不在话下 这是考虑每一层的节点类型中的成员都不太一样的情况下, 如果可以保证每一个节点类型中有相同的成员, 就可以考虑写一个普通的树 : ![]() template <typename T> struct tree_node { T value; tree_node **next; size_t next_size; tree_node *previous; }; template <typename Node, bool IsConst> class tree_iterator; template <typename T, typename Allocator> class tree { public: //部分别名例如 value_type, reference 等此处删除 //... using iterator = tree_iterator<tree_node<T>, false>; using const_iterator = tree_iterator<tree_node<T>, true>; public: void insert_under(const_iterator pos, const T &value); //在某一个节点下插入一个新的节点, 当然这是默认插在最后, 可以再给一个重载插入到指定位置 void erase_under(const_iterator pos, size_t n); }; 因为 tree 只接受一个类型, 所以借助 std::variant 进行类型擦除即可 : using tree_t = tree<std::variant<A, B, C, D, E, F>>; 甚至干脆一点, 直接用 void * 进行类型擦除 个人意见仅供参考, 你的想法已经比较简单了, 而且实现起来也不会特别难 [此贴子已经被作者于2020-8-31 02:14编辑过] |
我需要从一个xml文件读取数据,数据为三层树状结构,我读取数据后以什么形式存储才能实现数据的修改、删除、添加等功能。
struct A //第一层结点
{
属性1;
属性2;
}
struct B //第二层结点,有n个
{
属性1;
属性2;
}
struct C //第三层结点,每个节点B下有m个
{
属性1;
属性2;
}
如何实现对第二层和第三层数据的操作。节点内属性的增删添改。节点个数的增删添改。
我目前将结构A下面的结构B使用list进行管理,每个结构B再建立一个list去管理结构B下面的结构C。但是感觉效率不高且操作繁琐,虽然数据目前只有三层,但后期可能增加到五六层,有没有什么好的方法给想一个。
我使用的是qt,和c++的mfc差不多,都是图形界面。通过图形界面的操作,对数据进行反写存储,我目前的结构反写删除、插入节点等操作比较复杂,是否有操作更简洁的数据存储的方法。