码迷,mamicode.com
首页 > 其他好文 > 详细

<每日 1 OJ> -内存文件系统

时间:2019-08-25 20:05:34      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:break   系统   代码   知识   遍历   调用   exist   原来   赋值   

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

代码如下:

******************************************************************************/
#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;
}

 

<每日 1 OJ> -内存文件系统

标签:break   系统   代码   知识   遍历   调用   exist   原来   赋值   

原文地址:https://www.cnblogs.com/mhq-martin/p/11408786.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!