导航

多节点树结构

Posted on 2021-07-28 13:47  Hosseini  阅读(358)  评论(0编辑  收藏  举报

在某次项目中,需要遍历装配体,装配体中可能含有嵌套,需要用到一中数据结构,类似于二叉树,但节点数量可能大于2,

如下图:

最终需要处理出来的结果如下:

定义树结构如下来存储每个节点的信息,主要结构如下:

1 class TreeNode
2 {
3     string name;
4     vector<TreeNode*> children;//子节点
5     TreeNode* parent;//父节点
6 }    

使用递归来解析,用容器map来存储最后的结果。

完整代码如下:

  1 #include <vector>
  2 #include <string>
  3 #include <map>
  4 using namespace std;
  5 typedef map<string,unsigned> DataMap;
  6 enum NodeType //节点类型
  7 {
  8     UnknownNode,//未知
  9     TopAsmNode,//装配体
 10     SubAsmNode,//子装配体
 11     FileNode,//文件夹
 12     PartNode //零件
 13 };
 14 
 15 class FileData
 16 {
 17 private:
 18     string name;
 19     DataMap dataMap;
 20 public:
 21     FileData(){}
 22     FileData(string s)
 23     {
 24         name = s;
 25     }
 26     string GetName()
 27     {
 28         return name;
 29     }
 30     DataMap GetDataMap()
 31     {
 32         return dataMap;
 33     }
 34     void AddPart(string s)
 35     {
 36         DataMap::iterator i = dataMap.find(s);
 37         if(i!=dataMap.end())
 38         {
 39             if(i->first==s)
 40                 ++( i->second );
 41         }
 42         else
 43             dataMap.insert(pair<string,unsigned>(s,1));
 44     }
 45 };
 46 
 47 class NodeDataVec
 48 {
 49 private:
 50     vector<FileData> FileDataVec;
 51 public:
 52     vector<FileData> GetFileData()
 53     {
 54         return FileDataVec;
 55     }
 56     void AddFileNode(string s)
 57     {
 58         FileData node(s);
 59         FileDataVec.push_back(node);
 60     }
 61     FileData *FindFileNode(string s)
 62     {
 63         for(unsigned i = 0;i<FileDataVec.size();++i)
 64         {
 65             if(FileDataVec[i].GetName() == s)
 66                 return &FileDataVec[i];
 67         }
 68         return NULL;
 69     }
 70 
 71     NodeDataVec(){};
 72     ~NodeDataVec(){};
 73 };
 74 
 75 class TreeNode
 76 {
 77 private:
 78     NodeType nodeType;
 79     vector<TreeNode*> children;//子节点
 80     TreeNode* parent;//父节点
 81     string name;
 82 public:
 83     void AnalyzeData(NodeDataVec &data)
 84     {
 85         for(unsigned i=0;i<children.size();++i)
 86         {
 87             switch (children[i]->GetNodeType())
 88             {
 89             case TopAsmNode:
 90                 children[i]->AnalyzeData(data);
 91                 break;
 92             case SubAsmNode:
 93                 children[i]->AnalyzeData(data);
 94                 break;
 95             case FileNode:    
 96                 if(data.FindFileNode(children[i]->GetName())!=NULL)//已经含有该文件夹节点
 97                 {
 98                     children[i]->AnalyzeData(data);
 99                 }
100                 else
101                 {
102                     data.AddFileNode(children[i]->GetName());
103                     children[i]->AnalyzeData(data);
104                 }
105                 break;
106             case PartNode:
107                 {
108                     FileData * fileNode = data.FindFileNode(name);
109                     fileNode->AddPart(children[i]->GetName());
110                 }
111                     break;
112             default:
113                 break;
114             }
115         }
116 
117     }
118     void AddChildNode(TreeNode *node)
119     {
120         children.push_back(node);
121         node->SetParent(this);
122     }
123     const vector<TreeNode*> GetChildren()
124     {
125         return children;
126     }
127     const TreeNode* GetParent()
128     {
129         return parent;
130     }
131     const NodeType GetNodeType()
132     {
133         return nodeType;
134     }
135     const string GetName()
136     {
137         return name;
138     }
139     void SetName(string &s)
140     {
141         name = s;
142     }
143     void SetNodeType(NodeType &type)
144     {
145         nodeType = type;
146     }
147     void SetParent(TreeNode* p)
148     {
149         parent = p;
150     }
151     void SetChildren(vector<TreeNode*> &c)
152     {
153         children = c;
154     }
155     TreeNode(string s ,NodeType t)
156     {
157         SetName(s);
158         SetNodeType(t);
159     }
160     TreeNode()
161     {
162         children.clear();
163         parent = NULL;
164     }
165     ~TreeNode(){}
166 };
View Code

测试:

 1 int main()
 2 {
 3     TreeNode asmRoot =  TreeNode("TopAsm",TopAsmNode);
 4     TreeNode asmSub01 =  TreeNode("asmSub01", SubAsmNode);
 5     TreeNode asmSub02 =  TreeNode("asmSub02", SubAsmNode);
 6     TreeNode fileNode01 =  TreeNode("工序1", FileNode);
 7     TreeNode fileNode01_2 =  TreeNode("工序1", FileNode);
 8     TreeNode fileNode02 =  TreeNode("工序2", FileNode);
 9     TreeNode part01 =  TreeNode("partA", PartNode);
10     TreeNode part02 =  TreeNode("partB", PartNode);
11     TreeNode part03 =  TreeNode("partC", PartNode);
12     TreeNode part04 =  TreeNode("partD", PartNode);
13 
14     fileNode01.AddChildNode(&part01);
15     fileNode01.AddChildNode(&part03);
16 
17     fileNode02.AddChildNode(&part04);
18 
19     fileNode01_2.AddChildNode(&part01);
20     fileNode01_2.AddChildNode(&part02);
21 
22     asmSub01.AddChildNode(&fileNode01);
23     asmSub01.AddChildNode(&fileNode02);
24     asmSub02.AddChildNode(&fileNode01_2);
25 
26     asmRoot.AddChildNode(&asmSub01);
27     asmRoot.AddChildNode(&asmSub02);
28 
29     NodeDataVec data;
30     asmRoot.AnalyzeData(data);
31 
32     return 0;
33 }
View Code