如果我没有理解错的话, 感觉就是很普通的树结构, 不过每一层的节点类型都不同罢了
其实你自己的方法也很不错, 差不多就是这样 :
程序代码:
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编辑过]