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

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

双亲表示法

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;
}
相关推荐
遇见尚硅谷15 分钟前
C语言:20250714笔记
c语言·开发语言·数据结构·笔记·算法
焦虑的二狗42 分钟前
Mac下载mysql
数据库·mysql·macos
有谁看见我的剑了?1 小时前
iperf3 网络带宽测试工具学习
学习·测试工具
老神在在0011 小时前
SpringMVC2
java·前端·学习·spring·java-ee
老神在在0011 小时前
SpringMVC3
java·前端·学习·spring·java-ee
chao_7891 小时前
动态规划题解_零钱兑换【LeetCode】
python·算法·leetcode·动态规划
吃着火锅x唱着歌1 小时前
LeetCode 424.替换后的最长重复字符
linux·算法·leetcode
hans汉斯1 小时前
【计算机科学与应用】面向APT攻击调查的溯源图冗余结构压缩
网络·算法·安全·web安全·yolo·目标检测·图搜索算法
Maybyy1 小时前
力扣454.四数相加Ⅱ
java·算法·leetcode
MicroTech20251 小时前
微算法科技技术创新,将量子图像LSQb算法与量子加密技术相结合,构建更加安全的量子信息隐藏和传输系统
科技·算法·量子计算