数据结构之树结构介绍

接下来几篇文章总结一下树结构,从树开始,到二叉树,二叉搜索树,再到AVL树,红黑树和B树/B+树,由浅如深


前言

此篇文章先简单的介绍一下最基本的树结构和一些树的基本术语
利用树结构来模拟一个linux的文件目录管理


一、树的概念

这是一颗大自然的树
大自然的树
这是数据结构中的树
在这里插入图片描述
二者看起来是如此的相像,现实中的树是根在地上,枝干往上长,叶子在整颗树的最顶端。而数据结构中的树如此相似却又刚好相反,树的根在上面,枝干往下长,叶子在树的最底端。先在脑子里有这么个概念,具体有关于树的术语在下文详细提及。

定义

树是一种非线性结构,由n(n >= 0)个节点组成,当n=0的时候,此时的树被称为空树。当n>0时,此时的树存在一个节点被称为根节点(如上图的A节点),而除根节点外的其它节点可以分为m个集合,每个集合本身又是一颗树,被称为根节点的子树。

分析

在这里插入图片描述这里即将介绍一些树的术语:

  1. 树的根节点:一棵树的根节点位于这个树的最上面,它没有父节点。
  2. 节点的度:一个结点包含子树的数目称为该结点的度。
  3. 叶子节点:度为0的节点称为叶子节点。
  4. 节点的层次:从根节点开始,根节点的层次为1,根节点的子节点为第二层,如此往下类推。
  5. 树的度:树中节点的度的最大值。上图树的度为3.
  6. 树的高度或深度:树中节点的最大层次。
  7. 父节点:每个节点的前驱节点称为父节点。如上图的B是E和F的父节点。
  8. 子节点:每个节点的后继节点称为子节点。如上图的E和F是B的子节点。
  9. 兄弟节点:同个父节点下的子节点称为兄弟节点。如上图的E和F,K和L。
  10. 节点的高度:节点距最底层的叶子节点的距离称为节点的高度。如上图B节点的高度为4。
  11. 节点的深度:节点距根节点的距离称为节点的深度。如上图的B节点的深度为2。

从10和11可以看出一个节点的高度和深度未必相等。但是对于一棵树而言,高度和深度是同一个概念。

二、树的应用(模拟文件系统)

1.定义一个树的节点

代码如下(示例):

typedef struct _tree_node
{
    _tree_node(string name)
    {
        this->name = name;
    }
    string name; //文件或文件夹的名字
    string type; //文件类型(dir or file)
    vector<struct _tree_node *> children; //链式存储子节点的指针
    struct _tree_node* parent; //父节点指针
} tree_node;

2.定义一个文件系统的树结构

代码如下(示例):

class file_system_tree
{

    public:
        file_system_tree()
        {
            root = new tree_node("/"); //初始化根节点,根目录名字为‘/’
            root->parent = NULL; //根节点的父节点置为null
            now = root; //初始化当前目录为根目录
        }
        ~file_system_tree();
        
		//创建目录
        void mkdir(string name);
		//列出当前目录的子目录
        void ls();
		//进入某个目录
        int cd(string name);
		
        tree_node *root;//根节点 即根目录
        tree_node *now; //记录当前目录
};

3.实现树结构的功能

代码如下(示例):

void file_system_tree::mkdir(string name)
{
    if(name[name.length()-1] != '/')
        name += "/";
    
    tree_node *node = new tree_node(name);
    now->children.push_back(node);
    node->parent = this->now;

}

void file_system_tree::ls()
{
    vector<tree_node *>::iterator it = now->children.begin();
    for(; it != now->children.end(); it++)
    {
        cout << (*it)->name << " ";
    }
    cout << endl;
}

int file_system_tree::cd(string name)
{
    if(name[name.length()-1] != '/')
        name += "/";

    if(name == "../")
    {
        now = now->parent;
        return 1;
    }

    vector<tree_node *>::iterator it = now->children.begin();
    for(; it != now->children.end(); it++)
    {
        if((*it)->name == name)
            now = (*it);

        return 1;
    }
    return 0;
}

4.测试代码

代码如下(示例):

int main(){

    file_system_tree *tree = new file_system_tree();
    tree->mkdir("var/");
    tree->mkdir("home");
    tree->mkdir("tmp");
    tree->ls();
    tree->cd("var/");
    tree->mkdir("hello");
    tree->mkdir("world");
    tree->ls();
    tree->cd("../");
    tree->ls();
    return 1;

}

输出如下:

在这里插入图片描述


总结

以上就是树结构的介绍,本文仅仅简单的介绍了树结构和相关术语,以及实现了一个简单的模拟linux的目录管理系统。而接下来的二叉树,二叉搜索树,AVL树,红黑树,B树/B+树才是实际工作中会遇到比较多的数据结构。

附加tips

您的点赞还有评论是我前进的最大动力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值