dl
dl_tree.h
浏览该文件的文档.
1
13#pragma once
14
15#include <vector>
16#include <list>
17#include <functional>
18#include <unordered_map>
19#include <cassert>
20
21#include "io/dl_log.h"
22
23namespace dl
24{
25
27template<typename T>
28class NTree
29{
30public:
31 class Node
32 {
33 friend class NTree<T>;
34 public:
35 Node(const T& v, Node* parent) :
36 _parent{ parent },
37 _v{v}
38 {}
39
40 T& GetValue() { return _v; }
41 const T& GetValue() const { return _v; }
42 Node* GetParent() { return _parent; }
43 const Node* GetParent() const { return _parent; }
44 std::vector<Node*>& GetChild() { return _child; }
45 const std::vector<Node*>& GetChild() const { return _child; }
46 private:
47 T _v;
48 Node* _parent;
49 std::vector<Node*> _child;
50 };
51
53 {}
54
58 Node* AddRoot(const T& v)
59 {
60 if (!_allNode.empty())
61 {
62 log_err0("根节点已经存在,不能重复添加!");
63 return nullptr;
64 }
65 Node* node = new Node(v, nullptr);
66 _allNode.push_back(node);
67 return node;
68 }
69
73 Node* Add(const T& v, Node* node_parent)
74 {
75 if (!node_parent)
76 {
77 return AddRoot(v);
78 }
79 Node* node = new Node(v, node_parent);
80 _allNode.push_back(node);
81 node_parent->_child.push_back(node);
82 return node;
83 }
84 Node* Add(const T& v, const T& parent)
85 {
86 Node* node_parent = Get(parent);
87 if (!node_parent)
88 {
89 log_err0("父节点不存在!");
90 return nullptr;
91 }
92 return Add(v, node_parent);
93 }
94
95 Node* PushBack(const T& v)
96 {
97 if (_allNode.empty())
98 {
99 return AddRoot(v);
100 }
101 Node* node_parent = _allNode.front();
102 Node* node = new Node(v, node_parent);
103 _allNode.push_back(node);
104 node_parent->_child.push_back(node);
105 return node;
106 }
107
111 bool Del(Node* node)
112 {
113 auto iter = std::find(_allNode.begin(), _allNode.end(), node);
114 if (iter == _allNode.end())
115 {
116 log_err0("节点不存在!");
117 return false;
118 }
119 // 从父节点移除
120 auto iter1 = std::find(node->_parent->_child.begin(), node->_parent->_child.end(), node);
121 if (iter1 == node->_parent->_child.end())
122 {
123 log_err0("父节点引用错误!");
124 return false;
125 }
126 node->_parent->_child.erase(iter1);
127
128 // 自己子节点连接到自己父节点
129 for (Node* node_child : node->_child)
130 {
131 node->_parent->_child.push_back(node_child);
132 node_child->_parent = node->_parent;
133 }
134
135 // 从主列表移除
136 delete node;
137 _allNode.erase(iter);
138 return true;
139 }
140
144 {
145 for (Node* node : _allNode)
146 {
147 if (v == node->_v)
148 return node;
149 }
150 return nullptr;
151 }
152
155 bool Has(Node* node)
156 {
157 for (Node* iter : _allNode)
158 {
159 if (iter == node)
160 return true;
161 }
162 return false;
163 }
164
167 void SetParent(Node* node, Node* parent)
168 {
169 if (!parent)
170 {
171 log_err0("parent不能为空!");
172 return;
173 }
174 if (!node->_parent)
175 {
176 log_err0("自己不能为空节点!");
177 return;
178 }
179
180 if (!Has(node))
181 {
182 log_err0("节点不存在!");
183 return;
184 }
185 if (!Has(parent))
186 {
187 log_err0("parent节点不存在!");
188 return;
189 }
190 auto& vec_child = node->_parent->GetChild();
191 auto iter_child = std::find(vec_child.begin(), vec_child.end(), node);
192 if (iter_child == vec_child.end())
193 {
194 log_err0("旧parent不包含自身!");
195 return;
196 }
197 vec_child.erase(iter_child);
198 parent->_child.push_back(node);
199 node->_parent = parent;
200 }
201
204 template<typename F>
205 void ForEach(F func)
206 {
207 if (_allNode.empty())
208 return;
209
210 std::stack<Node*> s;
211 s.push(_allNode.front());
212
213 while (!s.empty())
214 {
215 Node* node_this = s.top();
216 s.pop();
217 func(node_this->_v);
218
219 // 反向遍历
220 auto& c = node_this->_child;
221 for (auto iter = c.rbegin(); iter != c.rend(); ++iter)
222 {
223 Node* node = *iter;
224 s.push(node);
225 }
226 }
227 }
228 //std::function<void(const T1&, T&)> func
232 template<typename T1, typename F>
233 void Copy(const NTree<T1>& b, F func)
234 {
235 using NodeSelf = NTree<T>::Node;
236 using NodeOther = NTree<T1>::Node;
237
238 // 先清空
239 for (NodeSelf* node : _allNode)
240 {
241 delete node;
242 }
243 _allNode.clear();
244
245 // 指针映射表
246 std::unordered_map<const NodeOther*, NodeSelf*> map_ptr;
247 // 构建Node,并生成 指针映射表
248 for (const NodeOther* node_b : b.GetAll())
249 {
250 NodeSelf* node = new NodeSelf(0, nullptr);
251 _allNode.push_back(node);
252
253 map_ptr[node_b] = node;
254 }
255 // 构建 数据
256 for (const NodeOther* node_b : b.GetAll())
257 {
258 NodeSelf* node = map_ptr[node_b];
259 node->_parent = map_ptr[node_b->GetParent()];
260 for (auto& iter : node_b->GetChild())
261 {
262 node->_child.push_back(map_ptr[iter]);
263 }
264 func(node_b->GetValue(), node->_v);
265 }
266 }
267
268 const std::list<Node*>& GetAll() const
269 {
270 return _allNode;
271 }
272
273 const Node* GetRoot() const
274 {
275 if (_allNode.empty())
276 return nullptr;
277 return _allNode.front();
278 }
279
280 size_t GetSize() const
281 {
282 return _allNode.size();
283 }
284
286 auto begin() { return _allNode.begin(); }
287 auto end() { return _allNode.end(); }
288
289
291 {
292 for (Node* node : _allNode)
293 {
294 delete node;
295 }
296 }
297private:
298 std::list<Node*> _allNode;//所有节点,第一个为根节点
299};
300
301
303//template<typename T>
304//class NTreeVec
305//{
306//public:
307// NTreeVec(const NTree<T>& tree)
308// {
309// _node.resize(tree.GetSize());
310// size_t i = 0;
311// tree.ForEach([](const T v) {
312// _node
313// });
314// }
315//private:
316// std::vector<T> _node;
317// std::vector<size_t> _parent;
318//};
319
320
321}
const std::vector< Node * > & GetChild() const
const T & GetValue() const
Node(const T &v, Node *parent)
const Node * GetParent() const
std::vector< Node * > & GetChild()
void ForEach(F func)
遍历,保证父节点先遍历
const Node * GetRoot() const
返回根节点,空树返回空
const std::list< Node * > & GetAll() const
返回所有节点
Node * Get(T v)
查找,失败返回nullptr
auto begin()
标准库迭代方法不保证父节点先遍历
Node * PushBack(const T &v)
第一个添加的为根节点,其他均为根节点的子节点
void Copy(const NTree< T1 > &b, F func)
从另一个树填充
void SetParent(Node *node, Node *parent)
修改父节点
Node * AddRoot(const T &v)
添加根节点
Node * Add(const T &v, Node *node_parent)
添加子节点
Node * Add(const T &v, const T &parent)
bool Del(Node *node)
删除节点
bool Has(Node *node)
包含节点
size_t GetSize() const
返回总数量
日志系统
void log_err0(std::string_view str, DL_SOURCE_LOCATION)