获取树形结构中,父节点下所有子/孙节点(递归方式)

news2024/10/6 14:38:54

获取树形结构中,父节点下所有子/孙节点(递归方式)

  • 1 树形结构(TreeItem类)
  • 2 测试代码(main函数)
  • 3 运行效果

1 树形结构(TreeItem类)

这里通用型树形结构为TreeItem类,头文件,如下:

#ifndef TREEITEM_H
#define TREEITEM_H

#include <QList>

class TreeItem
{
public:
    explicit TreeItem(QString name, TreeItem *parent = nullptr);
    ~TreeItem();

    void appendChild(TreeItem *item);
    void clearChildren();

    TreeItem *child(int row) { return _children.value(row); }
    QList<TreeItem*> children() { return _children; }
    static QList<TreeItem*> grandchildren(TreeItem* parent);
    QList<TreeItem*> grandchildren();

    TreeItem *parent() { return _parent; }
    int childCount() const { return _children.count(); }
    int row() const { return _row; }
    void setRow(int row){ _row = row; }
    QString name() { return _name; }
    void setName(QString name) { _name = name; }

private:
    TreeItem *_parent;            ///<父节点
    QList<TreeItem*> _children;   ///<子节点列表
    int _row;                     ///<记录本item位于父节点下第几个节点
    QString _name;
};

#endif // TREEITEM_H

源文件,如下:

#include "TreeItem.h"

TreeItem::TreeItem(QString name, TreeItem *parent)
    : _parent(parent),
      _row(0),
      _name(name)
{

}

TreeItem::~TreeItem()
{
    clearChildren();
}

/**
 * @brief TreeItem::appendChild
 * 在此节点下增加子节点
 * @param child 节点
 */
void TreeItem::appendChild(TreeItem *item)
{
    item->setRow(_children.size());   // item存自己是第几个,可以优化效率
    _children.append(item);
}

/**
 * @brief TreeItem::clearChildren
 * 清空所有子节点
 */
void TreeItem::clearChildren()
{
    qDeleteAll(_children);
    _children.clear();
}

/**
 * @brief TreeItem::grandchildren
 * 获取指定父节点parent下的所有子节点(递归包括孙子、重孙子节点)
 * @param parent 父节点
 * @return 子节点列表
 */
QList<TreeItem*> TreeItem::grandchildren(TreeItem* parent)
{
    if (parent->childCount() == 0)
    {
        return QList<TreeItem*>();
    }
    QList<TreeItem*> listItems;
    listItems << parent->children();
    foreach (auto child, parent->children())
    {
        listItems << child->grandchildren(child);
    }
    return listItems;
}

/**
 * @brief TreeItem::grandchildren
 * 获取当前节点下的所有子节点(递归包括孙子、重孙子节点)
 * @return 子节点列表
 */
QList<TreeItem*> TreeItem::grandchildren()
{
    return grandchildren(this);
}

这个类的函数比较简单,就是利用TreeItem类型,彼此依次添加,就可以形成树形结构。
这里需要关注的关键函数为:

QList<TreeItem*> TreeItem::grandchildren(TreeItem* parent)
{
    if (parent->childCount() == 0)
    {
        return QList<TreeItem*>();
    }
    QList<TreeItem*> listItems;
    listItems << parent->children();
    foreach (auto child, parent->children())
    {
        listItems << child->grandchildren(child);
    }
    return listItems;
}

QList<TreeItem*> TreeItem::grandchildren()
{
    return grandchildren(this);
}

利用了递归方式,对形参parent节点下的所有节点进行遍历,并将该parent节点下所有子/孙节点,全部添加到一个List中,并返回给调用者。

2 测试代码(main函数)

测试代码,如下所示:

#include <QCoreApplication>
#include <QDebug>
#include "TreeItem.h"

void print(QList<TreeItem*> items)
{
    for (int i = 0; i < items.size(); i++)
    {
        QString name = items.at(i)->name();
        qDebug() << "Item" << i << ":" << name;
    }
    qDebug() << "Print Over, Total Item Count :" << items.size();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    /*
     *                China
     *      /           |                   \
     *   SiChuan      BeiJing            GuangDong
     *   /      \                 /          |         \
     * ChengDu YiBin           GuangZhou  ShenZhen   FoShan
    */
    // 四川
    TreeItem* sichuan = new TreeItem("SiChuan");
    TreeItem* chengdu = new TreeItem("ChengDu");
    TreeItem* yibin = new TreeItem("YiBin");
    sichuan->appendChild(chengdu);
    sichuan->appendChild(yibin);

    // 北京
    TreeItem* beijing = new TreeItem("BeiJing");

    // 广东
    TreeItem* guangdong = new TreeItem("GuangDong");
    TreeItem* guangzhou = new TreeItem("GuangZhou");
    TreeItem* shenzhen = new TreeItem("ShenZhen");
    TreeItem* foshan = new TreeItem("FoShan");
    guangdong->appendChild(guangzhou);
    guangdong->appendChild(shenzhen);
    guangdong->appendChild(foshan);

    // China
    TreeItem* china = new TreeItem("China");
    china->appendChild(sichuan);
    china->appendChild(beijing);
    china->appendChild(guangdong);

    // 查看China下所有节点
    QList<TreeItem*> items = china->grandchildren();
    print(items);

    // 查看SiChuan下所有节点
    items = sichuan->grandchildren();
    print(items);

    // 查看GuangDong下所有节点
    items = TreeItem::grandchildren(guangdong);
    print(items);

	delete china; // 仅需删除根节点对象
    return a.exec();
}

该测试代码,首先生成一个,如下图所示的树形结构:
在这里插入图片描述

3 运行效果

最后,分别打印输出China、SiChuan、GuangDong节点下的所有子/孙节点名称。

在这里插入图片描述

需要注意
最后释放内存时,仅需删除根节点对象(china)即可,在析构函数中,会自动依次删除所有子/孙节点内存。

具体工程代码,详见:https://gitee.com/bailiyang/cdemo/tree/master/Qt/67TreeDataTest/TreeDataTest

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初学Java web(七)RequestResponse

Request&Response Request:获取请求数据 Response:设置响应数据 一.Request对象 1.Request继承体系 Tomcat需要解析请求数据&#xff0c;封装为requestx对象并且创建requestx对象传递到service方法中 使用request对象&#xff0c;查阅JavaEE API文档的HttpServletReque…

rocketMq架构原理精华分析(一)

rocketMq架构原理精华分析是我们这篇文章的核心&#xff0c;从消息中间件的对比、架构模型、消息模型、常见问题等逐一分析&#xff1a; 一、中间件对比&#xff1a; RabbitMq 集群效果不太好&#xff0c;底层不是java 语言&#xff0c;研究原理比较困难&#xff1b; Kafka是…

前端面试题之计算机网络篇 OSI七层网络参考模型

互联网数据传输原理 &#xff5c;OSI七层网络参考模型 OSI七层网络参考模型 应用层&#xff1a;产生网络流量的程序表示层&#xff1a;传输之前是否进行加密或者压缩处理会话层&#xff1a;查看会话&#xff0c;查木马 netstat-n传输层&#xff1a;可靠传输、流量控制、不可…

亿级流量的互联网项目如何快速构建?手把手教你构建思路

一. 大流量的互联网项目 1.项目背景 索尔老师之前负责的一个项目&#xff0c;业务背景是这样的。城市的基础设施建设是每个城市和地区都会涉及到的&#xff0c;如何在基建工地中实现人性化管理&#xff0c;是当前项目的主要诉求。该项目要实现如下目标&#xff1a; 工地工人的…

C语言实现http下载器(附代码)

C语言实现http的下载器。 例&#xff1a;做OTA升级功能时&#xff0c;我们能直接拿到的往往只是升级包的链接&#xff0c;需要我们自己去下载&#xff0c;这时候就需要用到http下载器。 这里分享一个&#xff1a; 功能&#xff1a; 1、支持chunked方式传输的下载 2、被重定…

Apollo开放平台8.0发布:多维升级“为开发者而生”

Apollo开放平台8.0重磅发布&#xff1a;多维升级“为开发者而生” Apollo开放平台迎来8.0版本&#xff0c;百度自动驾驶开放平台迈向易用性时代 百度Apollo EDU计划进展公布&#xff1a;已覆盖自动驾驶技术人才33.5万、700多所院校 Apollo Studio学习实践社区上线&#xff0c;新…

剑指offer----C语言版----第一天

目录 1. 数组中重复的数字Ⅰ 1.1 题目描述 1.2 思路一 1.3 思路二 1.4 思路三&#xff08;最优解&#xff09; 1. 数组中重复的数字Ⅰ 原题&#xff1a;剑指 Offer 03. 数组中重复的数字 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/shu-zu-zhong-…

Python语言快速入门上

目录 1、前言 2、变量和常量 1&#xff09;Python对象模型 2&#xff09;Python变量 二、运算符和表达式 【运算符和表达式】 【位运算符】 【逻辑运算符】 【成员运算符】 【身份运算符】 【常用内置函数】 【基本输入输出】 【模块导入与使用】 【Python代码编…

【PCB专题】Allegro导出3D文件

在PCB布局时,已经决定了大部分器件要放置的位置。如接口、主要的芯片、模块等。因为放置好器件后可能与结构干涉,如果没有发现,那么不得不在Layout的后期调整器件位置,增加工作量。所以前期布局基本确定后就需要导出3D文件给结构工程师,由他查看是否有器件与结构、螺丝孔等…

全志Tina Linux Display 开发指南支持百问网T113 D1-H哪吒DongshanPI-D1s V853-Pro等开发板

1 概述 让显示应用开发人员了解显示驱动的接口及使用流程&#xff0c;快速上手&#xff0c;进行开发&#xff1b;让新人接手工作时能快速地了解驱动接口&#xff0c;进行调试排查问题。sunxi 平台DE1.0/DE2.0。与显示相关的应用开发人员&#xff0c;及与显示相关的其他模块的开…

操作系统期末考试必会题库1——引言+用户界面

1.请简要描述操作系统的定义及其功能。 操作系统定义&#xff1a; 是计算机系统中的一个系统软件&#xff0c;是一些程序模块的集合 &#xff0c;它们管理和控制计算机系统中的软硬件资源&#xff0c;合理的组织计算机的工作流程&#xff0c;以便有效的利用这些资源为用户提供一…

Linux用户权限详解

为什么有人冲了钱就能享受至尊VIP待遇&#xff1f;为什么冲了黄钻、绿钻、紫钻就会享受一些特殊活动呢&#xff1f;我们起初都是一群普通用户&#xff0c;为什么有些人就能通过某些手段得到一些异于常人的服务呢&#xff1f;这其中的奥秘是什么呢&#xff1f;接下来带大家了解这…

【Vue】course_1

一、vue简介 Vue是一款用于构建用户界面的 JavaScript 框架。 它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 无论是简单还是复杂的界面&#xff0c;Vue 都可以胜任。 二、vue3选项式…

ASEMI肖特基二极管MBR30100CT和MBR40200PT有什么区别

编辑-Z 别看ASEMI肖特基二极管MBR30100CT和MBR40200PT两种型号从名字上看很像&#xff0c;其实他们的参数和封装都是不一样的&#xff0c;具体MBR30100CT和MBR40200PT有什么区别呢&#xff1f; 肖特基二极管MBR30100CT参数&#xff1a; 型号&#xff1a;MBR30100CT 封装&…

[开源工具]使用Fiddler/Postman简单计算QPS[新手开箱可用]

使用Fiddler/Postman简单计算QPS1.什么是QPS?2.怎么计算QPS?3.如何使用Fiddler/Postman得到一个API接口的QPS?3.1Fiddler使用3.2Postman使用4.如何得到本机的核心数?5.根据公式计算QPS?6.扩展计算单机可支撑PV(理论值)?1.什么是QPS? qps即每秒查询率&#xff0c;是对一…

Postfix + Extmail 企业邮件服务器搭建

ExtMail套件用于提供从浏览器中登录、使用邮件系统的Web操作界面&#xff0c;而Extman套件用于提供从浏览器中管理邮件系统的Web操作界面。它以GPL版权释出&#xff0c;设计初衷是希望设计一个适应当前高速发展的IT应用环境&#xff0c;满足用户多变的需求&#xff0c;能快速进…

数据预处理和特征工程-sklearn

数据挖掘的五大流程&#xff1a; 获取数据数据预处理 数据预处理是从数据中检测&#xff0c;纠正或删除损坏&#xff0c;不准确或不适用于模型的记录的过程。 数据预处理的目的&#xff1a;让数据适应模型&#xff0c;匹配模型的需求特征工程 特征工程是将原始数据转换为更能代…

NLP 中文智能纠错 API 数据接口

NLP 中文智能纠错 API 数据接口 专注于中文语句智能纠错&#xff0c;基于 NLP&#xff0c;多模型参与纠错。 1. 产品功能 秒级 NLP 智能纠错性能&#xff1b;NLP 加载多个模型进行纠错处理&#xff1b;返回纠正字符以及对应位置索引&#xff1b;底层模型以及语料库持续更新集…

正大国际期货:五十句期货投资理念

1.许多期货投资人交易时没有计划。交易前&#xff0c;他们既不设定风险限度&#xff0c;也不设定盈利目标。即使是制定了计划&#xff0c;他们总是“半路出家”&#xff0c;并不坚持既定的计划&#xff0c;尤其是在出现亏损的情况下。结果往往是过量操作&#xff0c;把自己逼在…

Android 操作系统简介

Android 操作系统简介1. 起源2. 操作系统市场占有率3. Android 系统架构3.1 Linux Kernel3.2 Hardware Abstraction Layer (HAL)3.3 运行时 系统库3.3.1 Android Runtime3.3.1 Native C/C Libraries3.4 Java API Framework3.5 System Apps1. 起源 安卓&#xff08;Android&…