一、树
树是一种非线性的数据结构,它由节点和边组成,可以表示分层或分支的关系,树是由n个结点组成的有限集合,如果n=0,称为空树;如果n>0,则:有一个特定的称之为根的结点,它只有直接后继,但没有直接前驱;除根以外的其他结点划分为m个互不相交的有限集合,每个集合又是一棵树,并且称之为根的子树。
树有很多种不同的类型,例如二叉树、平衡树、红黑树、B树等,它们各有各的特点和应用。树的遍历是指按照一定的顺序访问树中的每个节点,常见的遍历方式有先序遍历、中序遍历、后序遍历和层次遍历,它们可以用递归或非递归的方法实现。
二、树的一些基本的术语和性质
根节点:树中没有父节点的唯一节点,是树的起点和最高层的节点。
子节点:树中有父节点的节点,是父节点的下一层的节点。
叶节点:树中没有子节点的节点,是树的终点和最低层的节点。
父节点:树中有子节点的节点,是子节点的上一层的节点。
兄弟节点:树中有相同父节点的节点,是同一层的节点。
节点的度:树中某个节点的子节点的个数,表示该节点的分支的数量。 树的度:树中所有节点的度的最大值,表示树的分支的复杂程度。
节点的层次:树中某个节点到根节点的距离,根节点的层次为 1,其子节点的层次为 2,依次类推。
树的深度:树中所有节点的层次的最大值,表示树的层次的高度。
路径:树中从一个节点到另一个节点的连续的边的序列,表示两个节点之间的关系。
路径长度:树中某个路径上的边的个数,表示两个节点之间的距离。
树的路径长度:树中所有路径长度的总和,表示树的结构的复杂程度。
森林:树中去掉根节点后,剩下的若干个子树的集合,表示树的分解。
树中的结点数等于所有结点的度数加1。
度为m的树中,第i层上至多有m^(i-1)个结点。
高度为h的m叉树至多有(m^h-1)/(m-1)个结点。
具有n个结点的m叉树的最小高度为⌈log_m(n(m-1)+1)⌉。
树中任意两个结点之间有唯一的路径。
树中不存在回路。
树的高度等于树中最长路径的长度。
三、demo(文件夹的结构就是典型的树结构)
void ExploreDirectory(const char *path,TNode *node)
{
//文件夹结构体
//打开一个文件夹,获取文件夹指针
DIR * d=opendir(path);
//这是一个函数调用,用来打开一个文件夹,返回一个指向该文件夹的指针
//如果打开失败,返回NULL
//path是一个字符串,表示文件夹的路径
if(d==NULL)
return;
//这是一个变量声明,用来存储文件夹中的一个文件或子文件夹的信息
//struct dirent是一个结构体类型,包含了文件名,文件类型等字段
//e是一个指向struct dirent的指针,初始化为NULL
struct dirent* e=NULL;
while((e=readdir(d))!=NULL)
//这是一个循环语句,用来遍历文件夹中的所有文件或子文件夹
//readdir是一个函数,用来读取文件夹中的下一个文件或子文件夹,返回一个指向struct dirent的指针
//如果没有更多的文件或子文件夹,返回NULL
//每次循环,e指向文件夹中的一个文件或子文件夹
{
//"."表示当前文件夹,".."表示上一级文件夹,这两个不需要遍历
if(strcmp(e->d_name,".")==0||strcmp(e->d_name,"..")==0)
{
continue;
}
//根据文件名创建一个全新节点
TNode* fileNode=CreateTreeNode(GetString(e->d_name).string);
ConnectBranch(node,fileNode);
//该文件是文件夹
if(e->d_type==4)
{
char filepath[1024]={0};
strcpy(filepath,path);
strcat(filepath,"/");
strcat(filepath,e->d_name);
ExploreDirectory(filepath,fileNode);
}
}
closedir(d);
}
void Print(void*ptr)
{
printf("|_____%s\n",(char*)ptr);
}
int main(int argc,char *argv[])
{
if(argc!=1&&argc!=2)
{
printf("invalud values\n");
return -1;
}
char * path=NULL;
if(argc==1)
{
path="./";
}
else
{
path=argv[1];
}
LTree *t=InitLinkTree();
TNode *pathNode=CreateTreeNode(path);
ConnectBranch(GetRoot(t),pathNode);
ExploreDirectory(path,pathNode);
TravelTree(t,Print);
ClearLinkTree(t);
return 0;
}
运行结果