文件目录结构的树形显示(数据结构课程设计,树、队列,C语言描述)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
⽂件⽬录结构的树形显⽰(数据结构课程设计,树、队列,C语
⾔描述)
⼀、要解决的问题
给出某⼀个操作系统下⽬录和⽂件信息,输⼊的数据第⼀⾏为根⽬录节点。
若是⽬录节点,那么它的孩⼦节点将在第⼆⾏中被列出,同时⽤⼀对圆括号“()”界定。
同样,如果这些孩⼦节点中某⼀个也是⽬录的话,那么这个⽬录所包含的内容将在随后的⼀⾏中列出,由⼀对圆括号“()”界定。
⽬录的输⼊输⼊格式为:*name size,⽂件的输⼊输⼊格式为:name size。
Name为⼀串不超过10个字符组成,并且字符串中不能有‘(’,‘)’,‘[‘,’]’和’*’。
Size是该⽂件/⽬录的⼤⼩,⽂件的size输⼊值为该⽂件的⼤⼩,⽬录的size输⼊值都为1。
树结构最多10层,每⼀层最多2个⽂件/⽬录。
要求编程实现将其排列成⼀棵有⼀定缩进的树,输出要求:第d层的⽂件/⽬录名前⾯需要缩进8*d个空格,兄弟节点要在同⼀列上。
并计算每⼀个⽬录⼤⼩,⽬录⼤⼩为所包含的所有⼦⽬录和⽂件⼤⼩以及⾃⾝⼤⼩的总和。
例如输⼊:
*/usr 1
(*mark 1 *alex 1)
(hw.c 3 *course 1) (hw.c 5)
(aa.txt 12)
输出
|_*/usr[24]
|_*mark[17]
| |_hw.c[3]
| |_*course[13]
| |_aa.txt[12]
|_*alex[6]
|_hw.c[3]
⼆、算法基本思想描述:
采⽤孩⼦兄弟双亲链表的数据存储结构建⽴⼆叉树,再先序遍历该⼆叉树输出所有节点。
输出时,通过parent节点的第⼀个孩⼦是否有兄弟节点控制缩进输出” | ”或” ”;⽬录的⼤⼩为该⽬录左⼦树(以其第⼀个孩⼦为根的树)所有节点的size和加上它本⾝⼤⼩。
三、设计
1. 数据结构的设计和说明
在⼀开始设计要采⽤的数据结构时,虽然课题只要求“树结构最多10层(树的深度),每⼀层最多2个⽂件/⽬录”,考虑到问题的实际意义,我决定把它优化消除这⼀限制,于是采⽤孩⼦兄弟的数据结构,后来由于缩进输出的需要⼜增加了parent域。
2. 关键算法的设计
(1)输⼊处理:从外部⽂件每读⼊⼀⾏处理⼀⾏,数据结构的构造与读⼊同时进⾏,提取节点的name[]域和size域建⽴该⾏所有节点。
其间,利⽤队列设⽴parentArray[]⽤来记录所有的⽬录节点地址,设置两个虚拟指针rear和head,每增加⼀个⽬录rear+1,head标记可作为当前节点parent域的⽬录,每遇到⼀个‘)’ head+1处理下⼀个⽬录包含的节点。
当输⼊⽂件结束时所采⽤的孩⼦兄弟双亲链表⼆叉树也就建⽴完成。
(2)输出处理:先序遍历所建⽴的⼆叉树,每个节点输出⼀⾏,都是先通过其parent节点的第⼀个孩⼦是否有兄弟节点标记flag[0]~flag[i],然后从flag[i]~flag[0]控制输出缩进符” | ”或” ”后再输出该节点信息。
3.数据结构图:
四、源程序清单(Win7系统WinTC环境下编译运⾏通过):
/*
========================================================课题:⽂件⽬录结构的显⽰
Author:Estrong. All Rights Reserved.
指导⽼师:LinFang
2011年1⽉7⽇写于福建⼯程学院.
========================================================
*/
#include "stdio.h"
#include "string.h"
#define Null 0
#define MAX 200
/*输⼊⽂件每⾏应不超过MAX个字符*/
typedef struct node /*采⽤孩⼦兄弟双亲链表的存储结构*/
{
char name[12];
unsigned int size;
struct node *parent,*first_child,*next_sibling;
}BinTNode,*BinTree;
/* 添加新节点 */
BinTree New_BinTNode(char str[],int *I,BinTree parentArray[],int *head,int *rear) { int i=0;
BinTree bt;
bt=(BinTNode *)malloc(sizeof(BinTNode));
bt->parent=parentArray[*head]; /*链接双亲结点确定归属⽬录*/
bt->first_child=Null;
bt->next_sibling=Null;
if(str[*I]=='*')
{(*rear)++; parentArray[*rear]=bt;}
while(str[*I]!=' ')
{
bt->name[i]=str[*I];
(*I)++;i++;
}
bt->name[i]='\0';(*I)++;
bt->size=str[*I]-'0';(*I)++;
while ((str[*I]!=' ')&&(str[*I]!=')')&&((*I)<strlen(str)-1)) /*条件(*I)<strlen(str)-1)是考虑到根节点没有‘ ’和')'*/ {
bt->size=bt->size*10+(str[*I]-'0');
(*I)++;
}
return bt;
}
/* 创建数据(将输⼊数据转化为所采⽤的树结构) */
BinTree Create_BinTree(FILE *input)
{ int I=0,rear=0,head=1; /*parentArray[head]⽤来记录当前节点应指向的parent⽬录节点*/
/*parentArray[rear]⽤来记录最后⼀个⽬录节点*/
BinTree parentArray[MAX];/*parentArray[]⽤来记录所有的⽬录节点地址*/
BinTree root,bt,pbt;
char str[MAX];
fgets(str,MAX,input);
root=New_BinTNode(str,&I,parentArray,&head,&rear);
root->parent=Null; /* 在创建根节点时其parent的赋值是随机的,这⾥给它赋回空 */
while(!feof(input))
{I=1; /*I是输⼊⽂件每⾏字符串中的下标,贯穿该⾏字符处理始末*/
fgets(str,MAX,input);
while(I<=(strlen(str)-1))
{
if(str[I]!=')')
{
bt=New_BinTNode(str,&I,parentArray,&head,&rear);
parentArray[head]->first_child=bt;
pbt=bt;
do /*创建并链接⼀对括号⾥的所有兄弟节点*/
{
if(str[I]==' ')
{
I++;
pbt->next_sibling=New_BinTNode(str,&I,parentArray,&head,&rear); /*创建兄弟节点*/
pbt=pbt->next_sibling;
}
}while(str[I]!=')') ;
head++; I=I+3; /* 此时遇到右括号head+1处理下⼀个⽬录;I+3跳过") (" */
}
else
{head++ ; I=I+3;} /* 此时也遇到右括号 */
}
}
return root;
}
/* 求⽬录⼤⼩ */
int SIZE(BinTree bt) /*返回当前⽬录左⼦树的⼤⼩(未加上原⽬录⼤⼩)*/
{ int size;
if(bt)
size=bt->size+SIZE(bt->first_child)+SIZE(bt->next_sibling);
else size=0;
return size;
}
/* 输出单个节点 */
void out(BinTree bt,FILE *output)
{ char size_str[10];
BinTree pbt=bt->parent;
int i=-1,j=0,k;
int flag[11]; /*flag[i]⽤来控制缩进,⼦⽬录深度可以设置,⽬前设为11*/
for(k=0;k<11;k++) flag[k]=0;
if(bt->name[0]=='*') bt->size=bt->size+SIZE(bt->first_child);
/*⽬录的⼤⼩为该⽬录本⾝⼤⼩及其左⼦树(以其第⼀个孩⼦为根的树)所有节点的size和*/ while(pbt!=Null)
{
i++;
if(pbt->next_sibling) flag[j]=1; /*输出时flag[i]=1缩进"| " */
else flag[j]=0; /*输出时flag[i]=0缩进" " */
pbt=pbt->parent;
j++;
}
while(i>=0)
{
if(flag[i]) {printf("| ");fprintf(output,"| ");}
else {printf(" ");fprintf(output," ");}
i--;
}
printf("|_%s[%d]\n",bt->name,bt->size);
fprintf(output,"|_%s[%d]\n",bt->name,bt->size);
}
/* 先序遍历输出整棵树 */
void OUTPUT(BinTree bt,FILE *output)
{
if(bt)
{
out(bt,output);
OUTPUT(bt->first_child,output);
OUTPUT(bt->next_sibling,output);
}
}
/* 主函数 */
main()
{ FILE *input,*output;
BinTree root;
if((input=fopen("input.txt","r"))==NULL)
{
printf("Cannot find the file! Strike any key to exit!"); getch();
exit(1);
}
output=fopen("output.txt","w");
root=Create_BinTree(input);
OUTPUT(root,output);
getch();
fclose(input);fclose(output);
}
五、测试数据及测试结果:
(注:以下测试数据置于外部⽂件input.txt⾥)
*/kqss 1
(*mark 1 *alex 1 *course 1 aa.txt 12 hw.c 5 hjh.c 4 gffg.c 5)
() (kkhw.c 3 *course 1) (ghw.c 5 *test 1 abcd.exe 13 *fdg 1 hw.c 5 hjh.c 4) (aa.txt 2 kqss.c 100 hgfgsdf.h 35 ghgjh.mp3 7) () (arfe.txt 12 kqss.c 100 fdfs.h 35)。