接下来几篇文章总结一下树结构,从树开始,到二叉树,二叉搜索树,再到AVL树,红黑树和B树/B+树,由浅如深
前言
此篇文章先简单的介绍一下最基本的树结构和一些树的基本术语
利用树结构来模拟一个linux的文件目录管理
一、树的概念
这是一颗大自然的树
这是数据结构中的树
二者看起来是如此的相像,现实中的树是根在地上,枝干往上长,叶子在整颗树的最顶端。而数据结构中的树如此相似却又刚好相反,树的根在上面,枝干往下长,叶子在树的最底端。先在脑子里有这么个概念,具体有关于树的术语在下文详细提及。
定义
树是一种非线性结构,由n(n >= 0)个节点组成,当n=0的时候,此时的树被称为空树。当n>0时,此时的树存在一个节点被称为根节点(如上图的A节点),而除根节点外的其它节点可以分为m个集合,每个集合本身又是一颗树,被称为根节点的子树。
分析
这里即将介绍一些树的术语:
- 树的根节点:一棵树的根节点位于这个树的最上面,它没有父节点。
- 节点的度:一个结点包含子树的数目称为该结点的度。
- 叶子节点:度为0的节点称为叶子节点。
- 节点的层次:从根节点开始,根节点的层次为1,根节点的子节点为第二层,如此往下类推。
- 树的度:树中节点的度的最大值。上图树的度为3.
- 树的高度或深度:树中节点的最大层次。
- 父节点:每个节点的前驱节点称为父节点。如上图的B是E和F的父节点。
- 子节点:每个节点的后继节点称为子节点。如上图的E和F是B的子节点。
- 兄弟节点:同个父节点下的子节点称为兄弟节点。如上图的E和F,K和L。
- 节点的高度:节点距最底层的叶子节点的距离称为节点的高度。如上图B节点的高度为4。
- 节点的深度:节点距根节点的距离称为节点的深度。如上图的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
您的点赞还有评论是我前进的最大动力。