1.介绍
本博文将通过C语言的树结构来构造一个简单的类文件系统结构,包含文件/文件夹的新建、复制、重命名、删除等基本功能,同时也支持文件系统结构的整体预览。
2.代码示例
1 #include<stdio.h> 2 #include<stdlib.h> 3 /* 4 * 数据结构:树文件目录系统 5 * C语言实现 6 * 2015-9-13 7 */ 8 typedef struct TreeNode *PtrToNode; 9 typedef PtrToNode Tree; 10 11 /* 12 * 文件或文件夹节点结构体 13 */ 14 struct TreeNode { 15 char* Name; //存储目录或文件名称 16 Tree Parent; //上一级目录 17 Tree FirstChild; //第一个子目录或子文件 18 Tree NextSibling; //下一个弟兄目录或文件 19 }; 20 21 /* 22 * 释放内存 23 */ 24 void MakeEmpty(Tree T) 25 { 26 if (T->FirstChild != NULL) { 27 Tree t = T->FirstChild->NextSibling; 28 MakeEmpty(T->FirstChild); 29 Tree tmp = NULL; 30 while (t != NULL) { 31 tmp = t; 32 t = t->NextSibling; 33 MakeEmpty(tmp); 34 } 35 } 36 free(T); 37 } 38 39 /* 40 * 删除文件或文件夹 41 */ 42 void Delete(Tree T) 43 { 44 Tree tmp = NULL; 45 if (T->Parent != NULL&&T->Parent->FirstChild != T) { 46 tmp = T->Parent->FirstChild; 47 while (tmp->NextSibling != T) { 48 tmp = tmp->NextSibling; 49 } 50 tmp->NextSibling = T->NextSibling; 51 MakeEmpty(T); 52 } 53 else if (T->Parent != NULL&&T->Parent->FirstChild == T) { 54 T->Parent->FirstChild = T->NextSibling; 55 MakeEmpty(T); 56 } 57 else { 58 MakeEmpty(T); 59 } 60 } 61 62 /* 63 * 获取根目录 64 */ 65 Tree GetRootDir(Tree T) 66 { 67 Tree tmp = T; 68 while (tmp->Parent != NULL) { 69 tmp = tmp->Parent; 70 } 71 return tmp; 72 } 73 74 /* 75 * 重命名文件或文件夹 76 */ 77 void Rename(Tree T,char* NewName) 78 { 79 T->Name = NewName; 80 } 81 82 /* 83 * 新建一个文件 84 */ 85 Tree NewFile(char *X) 86 { 87 Tree T = (Tree)malloc(sizeof(struct TreeNode)); 88 T->Name = X; 89 T->FirstChild = T->NextSibling = T->Parent = NULL; 90 return T; 91 } 92 /* 93 * 添加某个文件或目录到指定目录中 94 */ 95 Tree Insert(Tree Des, Tree Src) 96 { 97 Src->Parent = Des; 98 if (Des->FirstChild == NULL) { 99 Des->FirstChild = Src; 100 } 101 else { 102 Tree Tmp = Des->FirstChild; 103 while (Tmp->NextSibling != NULL) { 104 Tmp = Tmp->NextSibling; 105 } 106 Tmp->NextSibling = Src; 107 } 108 return Des; 109 } 110 111 /* 112 * 返回节点的深度 113 */ 114 int GetDepth(Tree T) { 115 int count = 0; 116 Tree tmp = T; 117 Tree Root = GetRootDir(T); 118 while (tmp->Parent != NULL) { 119 count++; 120 tmp = tmp->Parent; 121 } 122 return count; 123 } 124 125 /* 126 * 复制文件,符号复制 127 */ 128 void Copy(Tree File, Tree Dir) 129 { 130 int flag = 1; 131 if (Dir->FirstChild != NULL) { 132 Tree tmp = Dir->FirstChild; 133 while (tmp != NULL) { 134 if (tmp->Name != File->Name) { 135 tmp = tmp->NextSibling; 136 } 137 else { 138 flag = 0; 139 printf("文件已经存在,无法复制!\n"); 140 break; 141 } 142 } 143 } 144 if (flag == 1) { 145 Dir = Insert(Dir, File); 146 } 147 } 148 149 /* 150 * 前序遍历打印所有文件目录结构 151 */ 152 void PrintWithPreorder(Tree T) 153 { 154 if (T != NULL) { 155 int H = 0; 156 if ((H = GetDepth(T)) > 0) { 157 while (H > 0) { 158 printf("\t"); 159 H--; 160 } 161 printf("%s\n", T->Name); 162 } 163 else { 164 printf("%s\n", T->Name); 165 } 166 Tree tmp = T; 167 Tree child = tmp->FirstChild; 168 while (child != NULL) { 169 PrintWithPreorder(child); 170 child = child->NextSibling; 171 } 172 } 173 else { 174 printf("NULL\n"); 175 } 176 } 177 178 /* 179 * 测试程序 180 */ 181 int main() 182 { 183 Tree T = NULL; 184 T = NewFile("root"); 185 Tree T1 = NULL; 186 Tree T2 = NULL; 187 Tree T3 = NULL; 188 Tree T4 = NULL; 189 Tree T5 = NULL; 190 Tree T6 = NULL; 191 Tree T7 = NULL; 192 Tree T8 = NULL; 193 T1 = NewFile("dir1"); 194 T2 = NewFile("dir2"); 195 T3 = NewFile("dir3"); 196 T4 = NewFile("dir4"); 197 T5 = NewFile("dir5"); 198 T6 = NewFile("dir6"); 199 T7 = NewFile("dir7"); 200 T8 = NewFile("dir8"); 201 202 T = Insert(T, T1); 203 T = Insert(T, T2); 204 205 T4 = Insert(T4, T6); 206 T6 = Insert(T6, T8); 207 208 T1 = Insert(T1, T3); 209 T1 = Insert(T1, T4); 210 T1 = Insert(T1, T5); 211 T2 = Insert(T2, T7); 212 213 printf("文件结构如下:\n"); 214 PrintWithPreorder(T); 215 Delete(T4); 216 PrintWithPreorder(T); 217 return 0; 218 }
3.代码说明
这是在学习树数据结构时拓展的一个小练习,整体思想是通过对文件系统进行树形构建,把每一个文件/文件夹看成一个节点,该节点拥有文件名、父节点、子节点、兄弟节点等属性,根据这些属性可以判断这个节点是否是文件夹以及距离根节点的深度,还有通过释放内存可以进行文件/文件夹的删除操作。在复制文件时,本代码中使用的是符号复制,即类似于C++中的引用,与原文件绑定在一起。本代码将持续更新。