一、功能
二、分析
首先,该目录管理系统提供的源数据是一个二进制的.dat文件,可随机文件操作。如图,采用 fread 函数读出后,每一行有三列,分别代表分类号、分类名、双亲结点分类号。
采用结构体数组存储文件内容。由于 “输出树形分类树” 功能,采用双亲表示法 实现 N叉树的顺序存储。
- 增加分类:将新增记录写入文件尾部,同时更新数组;
- 输出分类:打印数组即可;
- 输出树形分类树:对N叉树进行先序遍历,输出的树有层次感,是利用树的层数实现的;
- 修改分类:对文件进行随机文件操作 (先fseek,后fwrite),同时更新数组;
- 删除分类:将 “###” 覆写 (fwrite) 待删除记录和数组元素。
三、代码
//目录管理系统:双亲表示法实现N叉树的顺序存储,编译环境vs 2019
#define _CRT_SECURE_NO_WARNINGS
#define MAX_TREE_SIZE 100 //最多结点个数
#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct Catalog //目录结构类型
{
char key[20] = {
0 }; //编号
char caption[80] = {
0 }; //类名
char parent[20] = {
0 }; //父亲编号
}Catalog;
typedef struct CatalogTree
{
Catalog Node[MAX_TREE_SIZE] = {
0 }; //数据域,Node的下标就表示了某个单元信息在顺序存储中的位置
int root = 0; //根节点位置,根节点默认在0号单元
int num = 0; //最后一个结点的数组编号
}CatalogTree;
CatalogTree tree, * ct; //如果直接用tree接收,应该写作fwrite(&tree->Node[i],sizeof(Catalog),1,fp)
FILE* fp = fopen("catalog3.dat", "rb+");//文件指针
Catalog C = {
"###","###","###" }; //初始化一个结构体
int t = 0; //记录层数
int f = 0; //存储下标
void CreateCatalogTree(); //0 将文件读入数组
void AddCatalog(); //1 增加分类信息,保存至文件
void AlterCatalog(); //2 修改分类信息,保存至文件
void DeleteCatalog(); //3 从文件中删除分类信息
void PrintCatalog(); //4 顺序输出文件中所有分类信息
void CreateCatalogTree(); //5.1 将分类信息用双亲表示法存储。调用PrintCatalogTree()
void PrintCatalogTree(); //5.2 调用PreOrder()函数
void PreOrder(CatalogTree* ct, int i);
void PostOrder(CatalogTree* ct, int i);
bool leaf(CatalogTree* ct, int i);
void menu();
int main()
{
if (fp == NULL)
{
printf("文件打开失败\n"