数据结构学习——树的储存结构

三种表示法:双亲表示法,孩子表示法,孩子兄弟表示法

双亲表示法

cpp 复制代码
//树结构------双亲表示法
#include <iostream>

using namespace std;

struct Tree
{
    string data;
    Tree* parent;       //双亲指针
    Tree* firstchild;   //第一个孩子指针
    Tree* nextsibling;  //下一个兄弟指针
};

void CreateTree(Tree*&root,string data,Tree* parent)
{
    Tree* newtree= new Tree;
    newtree->data=data;
    newtree->parent=parent;
    newtree->firstchild=NULL;
    newtree->nextsibling=NULL;
    if(root==NULL)
    {
        root=newtree;
        return;
    }

    if(parent!=NULL){
        //temp指向该父类的第一个孩子
        Tree* temp=parent->firstchild;

        //如果第一个孩子为空,添加为第一个孩子
        if (temp==NULL)
        {
           parent->firstchild=newtree;
        }
        
        else{
        //不为空的情况下
        //如果该父类有兄弟,就遍历到最后一个兄弟,然后添加为兄弟
            while(temp->nextsibling!=NULL){
                temp=temp->nextsibling;
            }

            temp->nextsibling=newtree;
        }
        

    }
}

//前序便利
void printTree(Tree* root){
    if(root==NULL){
        return;
    }
    else{
        
        cout<<root->data<<endl;
        printTree(root->firstchild);
        printTree(root->nextsibling);

    }


}


int main(){
    Tree* root=NULL;
    
    CreateTree(root,"root",NULL);
    CreateTree(root,"root->node1",root);
    CreateTree(root,"root->node2",root);
    CreateTree(root,"root->node3",root);
    CreateTree(root,"root->node1->node1",root->firstchild);
    CreateTree(root,"root->node1->node2",root->firstchild);
    CreateTree(root,"root->node2->node1",root->firstchild->nextsibling);
    CreateTree(root,"root->node3->node1",root->firstchild->nextsibling->nextsibling);

    cout<<"树的结构为:"<<endl;
    printTree(root);

    return 0;


}

好吧这个其实是个综合的表示法,是孩子兄弟加上一个parent指针

孩子表示法

(虽然我感觉看这张图理解可能也会有点晕)

cpp 复制代码
//孩子表示法
#include<iostream>

using namespace std;
//这里要先声明,不然Childlist中引用会出错
struct TreeNode;


/*
简单说一下这里的思路:
TreeNode结构体代表一个节点,data为数据,firstChild为指向第一个孩子的指针
一个节点的孩子我们用Childlist链表来表示,
链表中的每个节点都有一个指向TreeNode的指针和指向下一位的指针

createTree函数创建一个新的节点并返回
addChild函数将返回的节点通过识别两个参数,
第一个是你想要插入位置的父节点,第二个是你想要插入的节点

所有的节点都要先createTree再addChild,
*/

struct Childlist{
    TreeNode* child;
    Childlist* next;
};

struct TreeNode{
    string data;
    Childlist* firstChild;

};

TreeNode* createTree(string data){ 
    TreeNode* newnode=new TreeNode();
    newnode->data=data;
    newnode->firstChild=NULL;
    return newnode;
}


void addChild(TreeNode* parent,TreeNode* your_node){
    if(parent==NULL){
        return;
    }
    Childlist* newnode=new Childlist();
    newnode->child=your_node;
    newnode->next=NULL;
    if(parent->firstChild==NULL){
        parent->firstChild=newnode;
    }
    else{
        Childlist* temp=parent->firstChild;
        while(temp->next!=NULL){
            temp=temp->next;
        }
        temp->next=newnode;

    }
    
}

void printTree(TreeNode* root){
    if(root==NULL){
        return;
    }
    cout<<root->data<<endl;
    Childlist* temp=root->firstChild;
    while(temp!=NULL){
        printTree(temp->child);
        temp=temp->next;
    }
}


int main(){

    //测试可看出为前序便利
    TreeNode* root=createTree("root");
    TreeNode* child1=createTree("root->child1");
    TreeNode* child2=createTree("root->child2");
    TreeNode* child3=createTree("root->child2->child3");
    TreeNode* child4=createTree("root->child1->child4");
    TreeNode* child5=createTree("root->child1->child4->child5");
    TreeNode* child6=createTree("root->child1->child4->child6");
    TreeNode* child7=createTree("root->child1->child7");
    


    addChild(root,child1);
    addChild(root,child2);
    addChild(child2,child3);
    addChild(child1,child4);
    addChild(child4,child5);
    addChild(child4,child6);
    addChild(child1,child7);


    printTree(root);
    return 0;
}

孩子兄弟表示法

cpp 复制代码
//孩子兄弟表示法
//其实原理和孩子表示法差不多,只不过是把孩子表示法中的链表提到了节点上
//类似于一个二叉树
//还有就是感觉先定义然后再链接感觉更直观一点
#include<iostream>

using namespace std;

struct TreeNode{
    string data;
    TreeNode* firstchild;
    TreeNode* next;
};


TreeNode* createTree(string data){
    TreeNode* newnode = new TreeNode;
    newnode->data = data;
    newnode->firstchild = NULL;
    newnode->next = NULL;
    return newnode;
}

void addNode(TreeNode* parent,TreeNode* your_node){
    if(parent->firstchild == NULL){
        parent->firstchild = your_node;
    }
    else{
        TreeNode* temp = parent->firstchild;
        while(temp->next != NULL){
            temp = temp->next;
        }
        temp->next = your_node;
    }
    
}

void printTree(TreeNode* root){
    if(root == NULL){
        return;
    }
    cout<<root->data<<endl;
    TreeNode* temp = root->firstchild;
    while(temp != NULL){
        printTree(temp);
        temp = temp->next;
    }
}

int main(){
    TreeNode* root = createTree("root");
    TreeNode* node1 = createTree("root->ndoe1");
    TreeNode* node2 = createTree("root->node2");
    TreeNode* node3 = createTree("root->node2->node3");
    TreeNode* node4 = createTree("root->node2->node4");

    addNode(root,node1);
    addNode(root,node2);
    addNode(node2,node3);
    addNode(node2,node4);

    printTree(root);

    return 0;
}
相关推荐
二哈不在线9 分钟前
代码随想录二刷之“贪心算法”~GO
算法·贪心算法·golang
快去睡觉~9 分钟前
力扣416:分割等和子集
数据结构·c++·算法·leetcode·职场和发展·动态规划
仙俊红12 分钟前
LeetCode每日一题,2025-9-5
算法·leetcode·职场和发展
阿维的博客日记16 分钟前
LeetCode 240: 搜索二维矩阵 II - 算法详解(秒懂系列
算法·leetcode·矩阵
周杰伦的稻香21 分钟前
MySQL抛出的Public Key Retrieval is not allowed
数据库·mysql
小O的算法实验室44 分钟前
2024年ASOC SCI2区TOP,有效离散人工蜂群算法+变压器制造矩形切割问题,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
悠哉悠哉愿意1 小时前
【数学建模学习笔记】机器学习分类:XGBoost分类
学习·机器学习·数学建模
2301_780789661 小时前
渗透测试与网络安全审计的关系
网络·数据库·安全·web安全·网络安全
我是海飞1 小时前
Tensorflow Lite 的yes/no语音识别音频预处理模型训练教程
python·学习·tensorflow·音视频·嵌入式·语音识别
GEO_JYB1 小时前
从 MMLU 到 HumanEval:为什么评估大型语言模型(LLM)的基准至关重要?
人工智能·算法