打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
文件目录结构的树形显示(数据结构课程设计,树、队列,C语言描述)

文件目录结构的树形显示(数据结构课程设计,树、队列,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)



 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
二叉树的遍历:先序中序后序遍历的递归与非递归实现及层序遍历
(浙大-19-夏-数据结构学习笔记)二叉树的遍历(递归 非递归)
trie树
网页视频下载(TS流下载合成)
Sublime text 2/3 [Decode error
用凹入表输出先序二叉树
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服