华为软件训练营的一个高级练习题,比较有意思,值得练习一下!
题目不是很难,主要是考察一下几个知识点:
(1)数据结构中树的操作,包括树的定义、树的遍历、节点的插入和删除,这里采用了带双亲的孩子兄弟表示法,实际上可以转换为二叉树,可以采用中序遍历的方式访问树的节点。
(2)内存管理。树节点中存放有树的信息,在每次插入一个新节点的时候需要malloc内存,最后需要统一free。
现将代码共享如下,希望能跟感兴趣的同学一起探讨:
FileManager.h:
#ifndef _FILE_MANAGER_H_ #define _FILE_MANAGER_H_ //定义用于表示文件系统的树结构 typedef struct CSNode{ char * name; bool isDir; struct CSNode * firstChild, * nextSibling, * parent; }CSNode, * CSTree; int CreateDir(const char * ParentDirName, const char * DirName); void DeleteDir(const char * DirName); int MoveDir(const char * SrcDirName, const char * DestDirName); int CreateFile(const char * DirName, const char * FileName); void DeleteFile(const char * FileName); unsigned int GetFileNum(const char * DirName); void Clear(void); #endif
FileManager.cpp:
/****************************************************************************** Copyright (C), 2001-2013, Huawei Tech. Co., Ltd. ****************************************************************************** File Name : Version : Author : Created : 2013/9 Last Modified : Description : Function List : History : 1.Date : 2013/9 Author : Modification: Created file ******************************************************************************/ #include "FileManager.h" #include <stdio.h> #include <malloc.h> #include <stddef.h> #include <string.h> #include <stack> using namespace std; CSNode *root = NULL; void FreeCSTree(CSNode *root) { if(root == NULL) { return; } FreeCSTree(root->firstChild); FreeCSTree(root->nextSibling); free(root); } CSNode * FindNode(CSNode * start, const char * nodeName, bool isDir) { if (start == NULL || nodeName == NULL) { return NULL; } stack<CSNode *> s; CSNode * node = NULL; s.push(start); while (!s.empty()) { CSNode *p; while((p = s.top()) && p) s.push(p->firstChild); s.pop(); if (!s.empty()) { p = s.top(); s.pop(); if (strcmp(p->name, nodeName) == 0) { if (isDir == p->isDir) { node = p; return node; } } s.push(p->nextSibling); } } return node; } int CreateDir(const char * ParentDirName, const char * DirName) { if (strcmp(ParentDirName,"root") == 0) { if (root == NULL) { root = (CSNode *)malloc(sizeof(CSNode)); memset(root, 0, sizeof(CSNode)); root->firstChild = NULL; root->nextSibling = NULL; root->isDir = true; root->name = (char *)malloc(strlen(ParentDirName)); strcpy(root->name,ParentDirName); root->parent = NULL; } } CSNode * parentDir = FindNode(root, ParentDirName, true); if (parentDir == NULL) { printf("The parent dir is non-existent!\n"); return -1; } CSNode * dir = FindNode(root, DirName, true); if(dir != NULL) { printf("The directory being created already exists!\n"); return -1; } CSNode * dirNode = (CSNode *)malloc(sizeof(CSNode)); memset(dirNode,0,sizeof(CSNode)); dirNode->name = (char *)malloc(strlen(DirName)); strcpy(dirNode->name,DirName); dirNode->isDir = true; dirNode->nextSibling = NULL; dirNode->firstChild = NULL; dirNode->parent = parentDir; CSNode * p = parentDir->firstChild; if (p == NULL) { parentDir->firstChild = dirNode; } else { while(p->nextSibling != NULL) { p = p->nextSibling; } p->nextSibling = dirNode; } //printf("成功创建文件夹:%s\n",DirName); return 0; } void DeleteDir(const char * DirName) { CSNode * dir = FindNode(root, DirName, true); if(dir == NULL) { printf("The directory being deleted is non-existent!\n"); return; } CSNode * parent = dir->parent; CSNode * p = parent->firstChild; if (strcmp(p->name, DirName) == 0) { parent->firstChild = dir->nextSibling; FreeCSTree(dir->firstChild); free(dir); return; } while(strcmp(p->nextSibling->name, DirName) != 0) { p = p->nextSibling; } p->nextSibling = p->nextSibling->nextSibling; FreeCSTree(dir->firstChild); free(dir); return; } int MoveDir(const char * SrcDirName, const char * DestDirName) { // 目标目录是直接父目录 if (strcmp(DestDirName, SrcDirName) == 0) { printf("The destination directory name is the same as the source!\n"); return -1; } CSNode * srcDir = FindNode(root, SrcDirName, true); CSNode * destDir = FindNode(root, DestDirName, true); // 目标目录或者源目录为空 if(srcDir == NULL || destDir == NULL) { printf("The directory is non-existed!\n"); return -1; } CSNode * r = FindNode(srcDir->firstChild, DestDirName, true); // 目标目录是源目录的子目录 if(r) { printf("The destination directory is wrong!\n"); return -1; } CSNode * parent = srcDir->parent; CSNode * p; //被移动目录是父目录第一个孩子 if (strcmp(parent->firstChild->name,SrcDirName) == 0) { parent->firstChild = srcDir->nextSibling; } else { p = parent->firstChild; while(strcmp(p->nextSibling->name, SrcDirName) != 0) { p = p->nextSibling; } p->nextSibling = p->nextSibling->nextSibling; } srcDir->nextSibling = NULL; srcDir->parent = NULL; if (destDir->firstChild == NULL) { destDir->firstChild = srcDir; srcDir->parent = destDir; return 0; } p = destDir->firstChild; while(p->nextSibling) { p = p->nextSibling; } p->nextSibling = srcDir; srcDir->parent = destDir; return 0; } int CreateFile(const char * DirName, const char * FileName) { if (strcmp(DirName,"root") == 0) { if (root == NULL) { root = (CSNode *)malloc(sizeof(CSNode)); memset(root, 0, sizeof(CSNode)); root->firstChild = NULL; root->nextSibling = NULL; root->isDir = true; root->name = (char *)malloc(strlen(DirName)); strcpy(root->name,DirName); root->parent = NULL; } } CSNode * parentDir = FindNode(root, DirName, true); if (parentDir == NULL) { printf("The parent dir is non-existent!\n"); return -1; } CSNode * file = FindNode(root, FileName, false); if(file != NULL) { printf("The file being created already exists!\n"); return -1; } CSNode * dirNode = (CSNode *)malloc(sizeof(CSNode)); memset(dirNode,0,sizeof(CSNode)); dirNode->name = (char *)malloc(strlen(FileName)); strcpy(dirNode->name ,FileName); dirNode->isDir = false; dirNode->nextSibling = NULL; dirNode->firstChild = NULL; dirNode->parent = parentDir; CSNode * p = parentDir->firstChild; if (p == NULL) { parentDir->firstChild = dirNode; } else { while(p->nextSibling != NULL) { p = p->nextSibling; } p->nextSibling = dirNode; } return 0; } void DeleteFile(const char * FileName) { CSNode * dir = FindNode(root, FileName, false); if(dir == NULL) { printf("The file is non-existent!\n"); return; } CSNode * parent = dir->parent; CSNode * p = parent->firstChild; if (strcmp(p->name, FileName) == 0) { parent->firstChild = dir->nextSibling; free(dir); return; } while(strcmp(p->nextSibling->name, FileName) != 0) { p = p->nextSibling; } p->nextSibling = p->nextSibling->nextSibling; free(dir); return; } int GetFileNumOfDir(CSNode * dir) { static int count = 0; if (dir == NULL) { return 0; } if (dir->isDir == false) { count++; } GetFileNumOfDir(dir->firstChild) + GetFileNumOfDir(dir->nextSibling); return count; } unsigned int GetFileNum(const char * DirName) { CSNode * dir = FindNode(root, DirName, true); if(dir == NULL) { printf("The dir is non-existent!\n"); return 0; } int i = 0; i = GetFileNumOfDir(dir->firstChild); return i; } void Clear(void) { FreeCSTree(root->firstChild); free(root); return; }
原文:http://blog.csdn.net/onejune2013/article/details/20650683