zoukankan      html  css  js  c++  java
  • <每日 1 OJ> -内存文件系统

    蛮有意思的,主要考查链表和树结构的知识。

    代码如下:

    ******************************************************************************/
    #include "FileManager.h"
    //#include <stdafx.h>
    #include "stdio.h"
    #include "string.h"
    #include "map"
    #include "malloc.h"
    #define NO 0
    #define OK 1
    
    //文件定义 链表结构
    //文件定义
    struct file
    {
      char filename[300];
      struct file *nextf;//p310 链表  *nextf 是指针变量,指向结构体变量,存放下一个节点的地址
     
    };
    //
    struct dir
    {
     char dirName[300];
     struct dir* subDir;  //子目录
     struct dir* borDir; //兄弟目录 
     struct dir* parDir;  //父目录
     struct file* fhead;//当前目录的文件
    };
    
    //全局根目录初始化
     struct dir root={"root",NULL,NULL,NULL,NULL};
    
    /*
    功能描述:根据目录名获得目录指针
    参数描述:DirName 目录名称 cur 当前目录指针
    返回值:所查询目录名称的目录指针
    */
    struct dir* getDirByName(const char* DirName,struct dir* cur)
    {
        if(NULL==cur)
        {
            return NULL;
        }
        if(0==strcmp(cur->dirName,DirName))
        {
            return cur;
        }
        struct dir* res;
        res=getDirByName(DirName,cur->borDir);
        if(NULL==res)
        {
            res=getDirByName(DirName,cur->subDir);
        
        }
        return res;
    }
    
     /*
        功能描述:根据文件名获得文件指针
        参数描述:FileName-文件名称 cur-当前目录指针
        返回值:所查询文件名称的目录指针
     */
    struct file* getFileByName(const char * FileName,struct dir*cur)
    {
        struct file* p=cur->fhead;
        while(NULL!=p)
        {
            if(0==strcmp(p->filename,FileName))
            {
                return p;
            }
            p=p->nextf;
        }
        p=NULL;
        if(NULL!=cur->borDir)
            p=getFileByName(FileName,cur->borDir);
        
        if(NULL==p&&NULL!=cur->subDir)
            p=getFileByName(FileName,cur->subDir);
        
        return p;
    }
    /*
        功能描述:判断指定名称目录是否已经存在
        参数描述:DirName-目录名称 
        返回值:OK-存在 NO-不存在
     */
    
    int isDirNameExist(const char* DirName)
    {
        struct dir* cur=getDirByName(DirName,&root);
        if(NULL==cur)
            return NO;
        return OK;
    
    }
    
     /*
        功能描述:判断指定名称文件是否已经存在
        参数描述:FileName-文件名称 
        返回值:OK-存在 NO-不存在
     */
     
    int isFileNameExist(const char* FileName)
    {
        struct file* cur=getFileByName(FileName,&root);
        if(NULL==cur)
            return NO;
        return OK;
    
    }
    
    
     /*
        功能描述:在指定目录下创建新目录
        参数描述:ParentDirName-父目录名称  DirName-新目录名称
        返回值:0-创建成功 -1-创建失败
     */
    int CreateDir(const char * ParentDirName, const char * DirName)
    {
       //检查父目录、待创建目录名称是否已存在
        if(NULL==ParentDirName||OK!=isDirNameExist(ParentDirName)||NULL==DirName||OK==isDirNameExist(DirName))
        {
        return -1;
        }
        struct dir* parDir=getDirByName(ParentDirName,&root);
        struct dir* curDir=(struct dir*)malloc(sizeof(struct dir));
    
        //如果申请空间失败
        if(NULL==curDir)
            return -1;
        if(NULL==parDir)
        {
            free(curDir);
            return -1;
        }
    
    /**********新目录对象赋值开始***************/
        curDir->fhead=NULL ;
        curDir->subDir=NULL;
        curDir->borDir=NULL;
        curDir->parDir=parDir;
        strcpy(curDir->dirName,DirName);
    /**********新目录对象赋值开始***************/
    
        //将新目录插入指定位置
        if(NULL==parDir->subDir)
        {
            parDir->subDir=curDir;
            return 0;
        }
        
        struct dir* p=NULL,*q=NULL;
        p=parDir->subDir;
        q=p->borDir;
        p->borDir=curDir;
        curDir->borDir=q;
        return 0;
    }
     /*
        功能描述:清除子目录
        参数描述:
        返回值:
     */
    void CleanSubDir(struct dir* curDir)
    {
        if(NULL==curDir)
            return;
     
        struct file* fhead=curDir->fhead;
        struct file* fnext=NULL;
        while(NULL!=fhead)
        {
            fnext=fhead->nextf;
            free(fhead);
            fhead=fnext;
        }
        curDir->fhead=NULL;
        if(NULL!= curDir->subDir)
        {
            CleanSubDir(curDir->subDir);
            free(curDir->subDir);
            curDir->subDir=NULL;
        }
        return;
    }
    
    /*
    功能描述:删除指定目录
    参数描述:DirName-目录名称
    返回值:无
    */
    void DeleteDir(const char * DirName)
    {
        //检查目录的存在情况、根目录不能删除
        if(NULL==DirName||OK!=isDirNameExist(DirName)||0==strcmp("root",DirName))
            return;
    
        struct dir* curDir=getDirByName(DirName,&root);
        struct dir* parDir=curDir->parDir;
    
        //清理当前目录下的所有文件及目录
            CleanSubDir(curDir);
    
        //如果父目录下头指针指向这个目录,那么将这个头指针赋给它的兄弟目录,将这个指针free掉
        if(parDir->subDir==curDir)
        {
            parDir->subDir=curDir->borDir;
            free(curDir);
            return;
        
        }
        //如果父目录头指针不是指向这个目录,那么遍历父目录指针的子目录,找到这个目录的指针,将这个指针解放掉。将其释放掉。即a->b->c 删除b ,那么a->c 
        struct dir* p=parDir->subDir;
        struct dir* q=NULL;
        while(NULL!=p)
        {
            q=p;
            p=p->borDir;
            if(p==curDir)
            {
                q->borDir=p->borDir;
                free(p);
                break;
            }    
        }
        return;
    }
    /*
    功能描述:判断两个目录是否存在父子目录关系
    参数描述:parDir-父目录名称  subdir-子目录名称
    返回值:OK-是父子目录关系 NO-非父子目录关系
    */
    int isTheSubDir(struct dir* parDir,struct dir* subdir)
    {
        struct dir* p=subdir;
        while(NULL!=p)
        {
            if(p->parDir==parDir)
                return OK;
            p=p->parDir;
        }
        return NO;
    }
    /*
    功能描述:移动目录
    参数描述:SrcDirName-待移动目录名称  DestDirName-目标移动目录名称
    返回值:0-移动成功 -1-移动失败
    */
    int MoveDir(const char * SrcDirName, const char * DestDirName)
    {
        //检查两个目录的存在情况、根节点不移动、两个目录不能相同
        if(NULL==SrcDirName||NULL==DestDirName||OK!=isDirNameExist(SrcDirName)||OK!=isDirNameExist(DestDirName)||0==strcmp(SrcDirName,DestDirName)||0==strcmp("root",SrcDirName))
            return -1;
    
        struct dir *srcDir=getDirByName(SrcDirName,&root);
        struct dir *desDir=getDirByName(DestDirName,&root);
    
        //目标目录不能使用源目录的子目录、源目录不能是目标目录的直接子目录
        if(OK==isTheSubDir(srcDir,desDir)||srcDir->parDir==desDir)
            return -1;
        
    /********************将源目录从其父目录剥离********************/
        //如果src 的父目录的子目录头指针指向src ,那么将src的父目录的子目录的头指针指向src 的兄弟目录
        if(srcDir->parDir->subDir==srcDir)
        {
            srcDir->parDir->subDir=srcDir->borDir;
        }
        //如果src 的父目录的子目录头指针不是指向src ,那么遍历src的父目录的子目录,找出src,然后将src的指针删除掉 a->b->c   a->c  将b(src)删除
        else
        {
            struct dir* p,*q;
            q=srcDir->parDir->subDir;
            p=q->borDir;
            while(NULL!=p)
            {
                if(0==strcmp(p->dirName,SrcDirName))
                {
                    q->borDir=p->borDir;
                    break;
                }
                q=p;
                p=p->borDir;
            }
        }
    /********************将源目录从其父目录剥离成功********************/
        
        //将源目录移动到目标目录之下
        srcDir->parDir=desDir;
        if(NULL==desDir->subDir)
        {
            desDir->subDir=srcDir;
            srcDir->borDir=NULL;
        }
        else
        {    
            srcDir->borDir=desDir->subDir;
            desDir->subDir=srcDir;
        }    
    
        return 0;
    }
    
    
    /*
    功能描述:在指定目录下创建文件
    参数描述:FileName-文件名称,curDir-当前目录
    返回值:0-创建成功 -1-创建失败
    */
    int CreateFile(const char * DirName, const char * FileName)
    {
    
        //检查目录名称、待创建文件名称的存在情况
        if(NULL==DirName||NULL==FileName||OK!=isDirNameExist(DirName)||OK==isFileNameExist(FileName))
            return -1;
     
        struct dir* curDir=getDirByName( DirName, &root);
        struct file* newFile=(struct file*)malloc(sizeof(struct file));
        //判断申请空间是否成功
        if(NULL==newFile)
        {
            return -1;
        }
        //新文件属性赋值
        newFile->nextf=NULL;
        strcpy(newFile->filename,FileName);
        //将文件插入指定位置
        if(NULL==curDir->fhead)//如果原来的目录下没有文件
        {
            curDir->fhead=newFile;//直接将文件赋给它
        }
        else
        {
            newFile->nextf=curDir->fhead;//先指向当前已有的文件的   兄弟文件指针
            curDir->fhead=newFile; //在赋值
        }
        return 0;
    }
    /*
    功能描述:删除指定名称的文件-由DeleteFile调用
    参数描述:FileName-文件名称,curDir-当前目录
    返回值:NO-未删除 OK-删除成功
    */
    int DeleteFileByName(const char * FileName,struct dir* curDir)
    {
        if(NULL==curDir)
            return NO;
        
        struct file*p=curDir->fhead;
        struct file*q=NULL;
        if(NULL!=p)
        {
            if(0==strcmp(p->filename,FileName))
            {
                curDir->fhead=p->nextf;
                free(p);
                return OK;
            }
            else   //?这是干啥的?
            {
                p=curDir->fhead;
                q=p->nextf;
                while(NULL!=q)
                {
                    if(0==strcmp(q->filename,FileName))
                    {
                        p->nextf=q->nextf;
                        free(q);
                        return OK;
                    }
                    p=q;
                    q=q->nextf;
                }
            }
        }
        int res=NO;
        res=DeleteFileByName(FileName,curDir->borDir);
        if(NO==res)
        res=DeleteFileByName(FileName, curDir->subDir);
     
        return res;
        
    }
     
    /*
    功能描述:删除指定名称的文件
    参数描述:FileName-文件名称
    返回值:无
    */
    void DeleteFile(const char * FileName)
    {
         
        if(NULL==FileName||OK!=isFileNameExist(FileName))
        return;
        DeleteFileByName(FileName,&root);
        return;
    }
    /*
    功能描述:计算指定目录下的文件数量(包括子目录)
    参数描述:DirName-目录名称 fileNum-文件数量(输出参数)
    返回值:无
    */
    void calFileNum(struct dir*curDir,unsigned int *fileNum)
    {
        if(NULL==curDir)
            return ;
     
        struct file* filep=curDir->fhead;
        while(NULL!=filep)
        {
            (*fileNum)++;
            filep=filep->nextf;
        }
        if(NULL!=curDir->borDir)
            calFileNum(curDir->borDir,fileNum);
     
        if(NULL!=curDir->subDir)
            calFileNum(curDir->subDir,fileNum);
            
    }
    /*
    功能描述:获取指定目录下的文件数量(包括子目录)
    参数描述:DirName-目录名称
    返回值:指定目录下的文件数量
    */
    unsigned int GetFileNum(const char * DirName)
    {
        unsigned int fileNum=0;
        if(NULL==DirName||OK!=isDirNameExist(DirName))
            return fileNum;
        struct dir*curDir=getDirByName(DirName, &root);
        if(NULL==curDir)
            return fileNum;
     
        //计算当前目录下的文件数量
        struct file* filep=curDir->fhead;
        while(NULL!=filep)
        {
            fileNum++;
            filep=filep->nextf;
        }
        //计算子目录下文件的数量
        if(NULL!=curDir->subDir)
        calFileNum(curDir->subDir,&fileNum);
        return fileNum;
    }
    /*
    功能描述:清空文件系统所有信息
    参数描述:curDir-当前目录
    返回值:无
    */
    void CleanDir(struct dir*curDir)
    {
     
        if(NULL==curDir)
            return;
     
        struct file* fhead=curDir->fhead;
        struct file* fnext=NULL;
        while(NULL!=fhead)
        {
            fnext=fhead->nextf;
            free(fhead);
            fhead=fnext;
        }
        curDir->fhead=NULL;
        
        if(NULL!= curDir->borDir)
        {
            CleanDir( curDir->borDir);
            free( curDir->borDir);
            curDir->borDir=NULL;
        }
        
        if(NULL!= curDir->subDir)
        {
            CleanDir(curDir->subDir);
            free(curDir->subDir);
            curDir->subDir=NULL;
        }
        return;
    }
    void Clear(void)
    {
          CleanDir(&root);
     
        return;
    }
  • 相关阅读:
    翻转单词顺序列
    和为S的两个数字
    单例模式
    python利用pyinstaller打包常用打包命令
    python 3.8 使用pymssql 向SQL Server插入数据不成功原因
    PyQt5(designer)入门教程
    PyQt5中文教程
    scrapy 图片爬取 多层多页 保存不同的文件夹 重命名full文件夹
    安装Python + PyCharm + PyQt5配套设置
    python用pymysql模块操作数据库MySQL,实现查增删改
  • 原文地址:https://www.cnblogs.com/mhq-martin/p/11408786.html
Copyright © 2011-2022 走看看