题目要求:
编写一个资源管理器模拟程序,管理目录和文件的层次化存储结构,主要包括以下功能:
1. 根据输入的目录名和文件名建立目录树
2. 采用凹入法显示目录树
3. 显示指定文件或目录所在的全路径
4. 插入目录或文件
5. 删除目录或文件
6. 销毁目录树
实现要求:
1.采用树的孩子兄弟链表存储结构
2.实现两种创建方式:一是输入边创建树、二是根据树对应的二叉树的先序遍历字符串创建树
代码如下
//头文件
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#define MAX 10
#define QMAX 100
#define SMAX 100
enum Opion {
EXIT,
CREATEPREORDER,
CREATETREE,
AORU,
INSERT,
DELET,
DESTROY,
PATH,
PREORDER
};
typedef char TDataType[MAX];
typedef struct TreeNode {
TDataType val;
struct TreeNode* Child;
struct TreeNode* Sibling;
}TreeNode;
//先序字符串创建
void Creaetepreorder(TreeNode**root);
//输入边创建
void CreateTree(TreeNode**root);
//先序遍历
void preorder(TreeNode*root);
//凹入输出
void AoRu(TreeNode*root,int depth);
//销毁
void Destroy(TreeNode** root);
//删除
void Delet(TreeNode** root, TDataType x);
//路径
void Path(TreeNode*root,TDataType x);
//插入
void Insert(TreeNode*root,TDataType x,TDataType fa);
//函数实现
TreeNode* BuyTNode(TDataType x)
{
TreeNode* newnode = (TreeNode*)malloc(sizeof(TreeNode));
if (newnode == NULL)
{
perror("malloc");
return NULL;
}
strcpy(newnode->val,x);
newnode->Child = newnode->Sibling = NULL;
return newnode;
}
//先序输入树
void Creaetepreorder(TreeNode** root)
{
TDataType tmp = { 0 };
scanf("%s",tmp);
if (strcmp(tmp, "#") == 0)
return;
else
{
TreeNode* node = BuyTNode(tmp);
*root = node;
Creaetepreorder(&((*root)->Child));
Creaetepreorder(&((*root)->Sibling));
}
}
//输入边创建
void CreateTree(TreeNode** root)
{
TDataType fa = { 0 }, val = { 0 };
TreeNode* Queue[QMAX] = { 0 };
int head = 0, tail = 0;
printf("请输入父结点和子结点(用空格隔开,结束时输入end)\n");
scanf("%s%s", fa, val);
while (strcmp(val, "end") != 0)
{
TreeNode* node = BuyTNode(val);
if (strcmp(fa, "#") == 0)
*root = node;
else
{
TreeNode* tmp = Queue[head];
while (strcmp(tmp->val, fa) != 0)
{
head++;
head %= QMAX;
tmp = Queue[head];
}
if (tmp->Child == NULL)
{
tmp->Child = node;
//r=node,记录一下兄弟结点,方便后面的查找
}
else//找到该父节点的孩子节点的最后一个兄弟节点
{
TreeNode* T = tmp->Child;
while (T->Sibling)//或者直接遍历找兄弟节点
{
T=T->Sibling;
}
T->Sibling = node;
}
}
Queue[tail++] = node;
tail %= QMAX;
printf("请输入父结点和子结点(用空格隔开,结束时输入end)\n");
scanf("%s%s", fa, val);
}
}
//先序打印
void preorder(TreeNode* root)
{
if (root == NULL)
return;
printf("%s ", root->val);
preorder(root->Child);
preorder(root->Sibling);
}
//凹入输出
void AoRu(TreeNode* root,int depth)
{
if (root == NULL)
return;
for (int i = 0; i < depth; i++)
printf("\t");
printf("%s\n",root->val);
AoRu(root->Child, depth + 1);
AoRu(root->Sibling, depth);
}
//销毁
void Destroy(TreeNode** root)
{
assert(root);
if (*root == NULL)
return;
else
{
Destroy(&((*root)->Child));
Destroy(&((*root)->Sibling));
free(*root);
*root = NULL;
}
}
//删除结点
//是删除的孩子结点,该结点的兄弟结点要保留
void Delet(TreeNode** root,TDataType x)
{
assert(root);
if(*root)
{
if (strcmp((*root)->val, x) == 0)
{
TreeNode* tmp = *root;
*root = (*root)->Sibling;
tmp->Sibling = NULL;
Destroy(root);
}
else
{
Delet(&((*root)->Child), x);
Delet(&((*root)->Sibling), x);
}
}
}
void StackPrint(TreeNode*Stack[],int top)
{
for (int i = 0; i <= top; i++)
{
printf("%s ",Stack[i]->val);
}
printf("\n");
}
//路径
void Path(TreeNode* root,TDataType x,TreeNode* stack[],int depth)
{
if (root == NULL)
return;
else
{
stack[depth] = root;
if (strcmp(root->val, x) == 0)
{
StackPrint(stack, depth);
return;
}
Path(root->Child, x, stack, depth + 1);
Path(root->Sibling, x, stack, depth + 1);
}
}
//查找
TreeNode* Find(TreeNode* root, TDataType x)
{
if (root == NULL)
return NULL;
else
{
if (strcmp(root->val, x) == 0)
return root;
TreeNode*node=Find(root->Child, x);
if (node)
return node;
node = Find(root->Sibling, x);
if (node)
return node;
return NULL;
}
}
//插入
void Insert(TreeNode* root, TDataType x, TDataType fa)
{
TreeNode* pfa = Find(root,fa);
if (pfa)
{
if (pfa->Child == NULL)
pfa->Child = BuyTNode(x);
else
{
//查看兄弟节点是否包含要插入的节点
TreeNode* bro = pfa->Child;
while (bro)
{
if (strcmp(bro->val, x) == 0)
{
printf("该节点已经存在\n");
return;
}
bro = bro->Sibling;
}
bro = pfa->Child;
TreeNode* node = BuyTNode(x);
node->Sibling = pfa->Child;
pfa->Child = node;
}
}
else
{
printf("父节点不存在\n");
}
}
//运行代码
void menu()
{
printf("1----先序字符串创建\n");
printf("2----输入边创建\n");
printf("3----凹入显示\n");
printf("4----插入\n");
printf("5----删除\n");
printf("6----销毁\n");
printf("7----路径\n");
printf("8----先序\n");
printf("0----退出\n");
printf("请选择:>");
}
void test()
{
int input = 0;
TDataType x;
TDataType fa;
TreeNode* stack[SMAX];
TreeNode* root = NULL;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case CREATEPREORDER:
printf("请输入先序顺序的二叉树:\n");
Creaetepreorder(&root);
break;
case CREATETREE:
CreateTree(&root);
break;
case AORU:
AoRu(root,0);
break;
case INSERT:
printf("请输入要插入的节点名称和父节点名称:");
scanf("%s%s",x,fa);
Insert(root,x,fa);
break;
case DELET:
printf("输入要删除的节点的名称:\n");
scanf("%s",x);
Delet(&root,x);
break;
case DESTROY:
Destroy(&root);
break;
case PATH:
printf("输入要找的节点的名称:\n");
scanf("%s", x);
Path(root,x,stack,0);
break;
case PREORDER:
preorder(root);
printf("\n");
break;
case EXIT:
printf("退出程序\n");
break;
default:
printf("无该选项\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}