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

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

双亲表示法

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;
}
相关推荐
NAGNIP28 分钟前
一文搞懂机器学习中的特征降维!
算法·面试
想摆烂的不会研究的研究生33 分钟前
每日八股——Redis(1)
数据库·经验分享·redis·后端·缓存
NAGNIP43 分钟前
一文搞懂机器学习中的特征构造!
算法·面试
码熔burning43 分钟前
MySQL 8.0 新特性爆笑盘点:从青铜到王者的骚操作都在这儿了!(万字详解,建议收藏)
数据库·mysql
猫头虎1 小时前
2025最新OpenEuler系统安装MySQL的详细教程
linux·服务器·数据库·sql·mysql·macos·openeuler
Learn Beyond Limits1 小时前
解构语义:从词向量到神经分类|Decoding Semantics: Word Vectors and Neural Classification
人工智能·算法·机器学习·ai·分类·数据挖掘·nlp
哈库纳玛塔塔1 小时前
放弃 MyBatis,拥抱新一代 Java 数据访问库
java·开发语言·数据库·mybatis·orm·dbvisitor
你怎么知道我是队长2 小时前
C语言---typedef
c语言·c++·算法
气概3 小时前
法奥机器人学习使用
学习·junit·机器人
@LetsTGBot搜索引擎机器人3 小时前
2025 Telegram 最新免费社工库机器人(LetsTG可[特殊字符])搭建指南(含 Python 脚本)
数据库·搜索引擎·机器人·开源·全文检索·facebook·twitter