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

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

双亲表示法

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;
}
相关推荐
lixinnnn.6 分钟前
bfs: kotori和迷宫
算法·宽度优先
小智RE0-走在路上8 分钟前
Python学习笔记(9) --文件操作
笔记·python·学习
暗然而日章8 分钟前
C++基础:Stanford CS106L学习笔记 14 类型安全 & `std::optional`
c++·笔记·学习
WongLeer11 分钟前
Redis 学习笔记
redis·笔记·学习·redis缓存·redis发布订阅
gugugu.29 分钟前
Redis持久化机制详解(二):AOF持久化全解析
数据库·redis·缓存
Hello.Reader32 分钟前
Flink SQL 的 RESET 语句一键回到默认配置(SQL CLI 实战)
数据库·sql·flink
PyGata33 分钟前
CMake学习笔记(二):CMake拷贝文件夹
c++·笔记·学习
摇滚侠36 分钟前
Redis 零基础到进阶,Redis 事务,Redis 管道,Redis 发布订阅,笔记47-54
数据库·redis·笔记
UVM_ERROR36 分钟前
UVM实战:RDMA Host侧激励开发全流程问题排查与解决
服务器·网络·数据库
Felven37 分钟前
A. Shizuku Hoshikawa and Farm Legs
算法