树形数据结构是一类重要的非线性数据结构。树形数据结构可以表示数据表素之间一对多的关系。其中以树与二叉树最为常用,直观看来,树是以分支关系定义的层次结构。树形数据结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形数据结构来形象表示。
树形结构具有无限拓展的特性,因此非常适合组织节点深度不定的数据,其基本实现方式是一个对象通过保存父对象和子对象的指针,来实现 A-B-C。 ?
实现步骤:
1.定义基类
class BaseNode{
private:
//父节点的指针
BaseNode*m_parent_node = nullptr;
//子节点们
QList<BaseNode*>m_child_nodes;
//节点名称
QString m_name;
//子节点数量
int m_childNum = 0;
public:
//用 name 和 parent 构造,root节点parent = nullptr
BaseNode(QString name,BaseNode*parent = nullptr)
:m_parent_node(parent),m_name(name){
}
void setParentNode(BaseNode*parent){
m_parent_node = parent;
}
void addCildNode(BaseNode* node){
//给子节点设置 parent
node->setParentNode(this);
m_child_nodes.push_back(node);
m_childNum += 1;
}
void setName(QString name){
m_name = name;
}
QString getName(){
return m_name;
}
QList<BaseNode*> childs(){
return m_child_nodes;
}
int childNum(){
return m_childNum;
}
};
2.子类继承
class Step:public BaseNode{
public:
Step(QString name,Step*parent = nullptr)
:BaseNode(name,parent){
}
};
3.实例化连接
int main(int argc, char *argv[])
{
Step * step_Main = new Step("Program");
Step * step_1 = new Step("step_1");
Step * step_2 = new Step("step_2");
Step * step_3 = new Step("step_3");
Step * step_4 = new Step("step_4");
step_Main->addCildNode(step_1);
step_1->addCildNode(step_2);
step_1->addCildNode(step_3);
step_1->addCildNode(step_4);
step_3->addCildNode(new Step("step_3_1"));
step_3->addCildNode(new Step("step_3_1"));
step_3->addCildNode(new Step("step_3_1"));
step_3->addCildNode(new Step("step_3_1"));
}
4.使用树形结构生成XML的方法:递归生成
void BuildNodeToXML(BaseNode*node,QDomDocument&m_domDocument,QDomElement&parent_element){
for(int i = 0;i < node->childNum();i ++){
//创建XML节点
QDomElement this_element = m_domDocument.createElement(node->childs()[i]->getName());
//把刚刚创建的节点追加到父节点parent_element
parent_element.appendChild(this_element);
qDebug()<< node->childs()[i]->getName();
//递归调用
BuildNodeToXML(node->childs().at(i),m_domDocument,this_element);
}
}
bool write(QIODevice *device,QDomDocument &document)
{
const int IndentSize = 4;
QTextStream out(device);
document.save(out, IndentSize);
return true;
}
int main(int argc, char *argv[])
{
Step * step_Main = new Step("Program");
Step * step_1 = new Step("step_1");
Step * step_2 = new Step("step_2");
Step * step_3 = new Step("step_3");
Step * step_4 = new Step("step_4");
step_Main->addCildNode(step_1);
step_1->addCildNode(step_2);
step_1->addCildNode(step_3);
step_1->addCildNode(step_4);
step_3->addCildNode(new Step("step_3_1"));
step_3->addCildNode(new Step("step_3_1"));
step_3->addCildNode(new Step("step_3_1"));
step_3->addCildNode(new Step("step_3_1"));
//Qt 的 XML 文件操作对象
QDomDocument m_domDocument;
//root节点
QDomElement element= m_domDocument.createElement("Program");
//添加root节点到最外层
m_domDocument.appendChild(element);
//从树形结构的起始位置构建XML
BuildNodeToXML(step_Main,m_domDocument,element);
QString fileName = "D:\\optiger2.xml";
QFile file(fileName);
file.open(QFile::WriteOnly | QFile::Text);
write(&file,m_domDocument);
qDebug() << m_domDocument.childNodes().size();
}
后记
1.Step 里可以实现更复杂的数据结构;
2.可以添加析构链,这样在delete 掉 step_Main 后,它下面的子子孙孙都 delete 掉了
~BaseNode(){
for(int i = 0;i < m_childNum;i ++){
delete m_child_nodes[i];
qDebug()<< m_name << " is deleted\n";
}
}
3.生成的XML文件
<Program>
<step_1>
<step_2/>
<step_3>
<step_3_1/>
<step_3_1/>
<step_3_1/>
<step_3_1/>
</step_3>
<step_4/>
</step_1>
</Program>
|