<每日 1 OJ> -內存文件系統

蠻有意思的,主要考查鏈表和樹結構的知識。spa

代碼以下:指針

******************************************************************************/
#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;
}
相關文章
相關標籤/搜索