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

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

双亲表示法

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;
}
相关推荐
十八岁讨厌编程几秒前
【算法训练营Day26】动态规划part2
算法·动态规划
hong_zc1 小时前
redis之缓存
数据库·redis·缓存
智者知已应修善业1 小时前
【C++无数组矩阵对角线平均值保留2位小数】2022-11-18
c语言·c++·经验分享·笔记·算法·矩阵
papership1 小时前
【入门级-算法-6、排序算法: 计数排序】
数据结构·算法·排序算法
pengpeng021 小时前
力扣每日一题 611. 有效三角形的个数
算法·leetcode·职场和发展
东临碣石821 小时前
【AI论文】潜在区域划分网络:生成建模、表征学习与分类的统一原理
学习
xinfei08032 小时前
第五天——为什么要学习
学习·每天一篇小感悟
诺青2352 小时前
MongoDB副本集
数据库·mongodb
2401_840105202 小时前
GESP C++5级 2025年6月编程2题解:最大公因数
数据结构·c++·算法
未知陨落2 小时前
LeetCode:56.子集
算法·leetcode·深度优先