使用到希尔排序和归并排序,文件存储
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include//名字的最大长度
#define NameMax 30//全局的文件指针变量
FILE* file, * file_admin, * file_divorce;//结婚人数
int nums = 0;//定义普通用户的结构体
typedef struct user {
char name[NameMax];
char ID[20]; //身份证位18位
int age; //年龄
char sex; //性别,F位女,M为男
char partner[NameMax]; //配偶的名字
char partner_ID[20]; //配偶的身份证
struct user* next;
} User;//定义管理员的结构体
typedef struct admin {
char name[NameMax]; //管理员的名字
char password[20]; //密码
}Admin;//定义树结点信息
typedef struct node {
int height;
int balance;
User* info;
struct node* left;
struct node* right;
}Node;//离婚人数链表,用来存储离婚人的信息
User* divorce;//判断是否操作确认,确认是返回1,不确认返回0
int GetConfirm()
{
char yes_no[5];
memset(yes_no, 0, sizeof(yes_no));
printf("\n\t\t=======================================\n");
printf(" \n\t\t\t是否执行该操作 ? 此操作不可逆! \n");
printf("\n\t\t=======================================\n");
printf("\n\t\t\t确认? [Y/N]:");
scanf("%s", yes_no);
if (strcmp(yes_no, "y") == 0 || strcmp(yes_no, "Y") == 0)
return 1;
else
return 0;
}//获得树的高度
int getHeight(Node* node) {
if (node == NULL) {
return 0;
}
int leftHeight = getHeight(node->left);
int rightHeight = getHeight(node->right);
return max(leftHeight, rightHeight) + 1;
}//获得当前结点的平衡因子
int getBalanceFactor(Node* tree) {
//如果不为空,当前结点平衡因子为左子树高度-右子树高度
if (tree) {
return getHeight(tree->left) - getHeight(tree->right);
}
return 0;
}//左转
Node* RR(Node* parent) {
//左旋
Node* son = parent->left;
parent->left = son->right;
son->right = parent;
//更新结点的高度
son->height = max(getHeight(son->left), getHeight(son->right)) + 1;
parent->height = max(getHeight(parent->left), getHeight(parent->right)) + 1;
//返回当前在最顶上的结点
return son;
}//左旋
Node* LL(Node* parent) {
//左旋变换
Node* son = parent->right;
parent->right = son->left;
son->left = parent;
//更新结点高度
son->height = max(getHeight(son->left), getHeight(son->right)) + 1;
parent->height = max(getHeight(parent->left), getHeight(parent->right)) + 1;
//返回当前在最顶上的结点
return son;
}
//更新树的平衡
Node* balance(Node* node) {//获取当前节点的平衡因子
int bf = getBalanceFactor(node);//不需要平衡
if (bf == 0)
return node;if (bf > 1) {
//左子树比右子树高
if (getBalanceFactor(node->left) < 0) {
//LR型,先对左节点进行LL旋转再对当前结点进行RR旋转
node->left = LL(node->left);
}
node = RR(node);
}
else if (bf < -1) {
//右子树比左子树高
if (getBalanceFactor(node->right) > 0) {
//RL型,先对右节点进行RR旋转再对当前结点进行LL旋转
node->right = RR(node->right);
}
node = LL(node);
}// 更新节点高度
node->height = max(getHeight(node->left), getHeight(node->right)) + 1;return node;
}//返回一个正确的身份证号
char* correct_ID() {
char* str = (char*)malloc(sizeof(char) * 19);
memset(str, 0, sizeof(str));
scanf("%s", str);
while (strlen(str) != 18) {
printf("\t\t身份证出错,请输入身份证:");
scanf("%s", str);
putchar('\n');
}
return str;
}//插入一个节点数据
Node* insert(Node* tree, User* info) {
// 判断插入节点是否为空
if (info == NULL) {
return tree;
}// 创建插入节点并赋值
if (tree == NULL) {
//判断是否离婚
User* p, * temp;
temp = p = divorce;
while (temp) {
if (!strcmp(temp->ID, info->ID)) {
printf("\n\t 此人已离婚!!!是否继续?\n");
if (GetConfirm()) {
p->next = temp->next;
}
else
return tree;
}
p = temp;
temp = temp->next;
}nums++;
tree = (Node*)malloc(sizeof(Node));
tree->info = (User*)malloc(sizeof(User));
*(tree->info) = *info;
tree->info->next = NULL;
tree->height = 0;
tree->left = tree->right = NULL;
return tree;
}// 存在相同身份证号的情况
if (strcmp(info->ID, tree->info->ID) == 0) {
printf("\t 身份证重复或已存在该人的信息,添加失败!\n");
return NULL;
}
else if (strcmp(info->ID, tree->info->ID) < 0) {
tree->left = insert(tree->left, info);
}
else {
tree->right = insert(tree->right, info);
}// 更新节点高度并进行平衡操作
tree->height = max(getHeight(tree->left), getHeight(tree->right)) + 1;
tree = balance(tree);return tree;
}//按身份证来查找某个结点
User* searchByID(Node* tree, char* ID) {
if (ID == NULL) {
printf("身份证出错");
return NULL;
}if (!tree) {
User* p = divorce->next;
int flag = 0;
while (p) {
if (!(strcmp(p->ID, ID))) {
printf("\t 姓名:%s,\t\t年龄:%d,\t身份证:%s,\t性别:%c,\t前配偶:%s\n",
p->name, p->age, p->ID, p->sex, p->partner);
flag = 1;
}
p = p->next;
}
if (flag == 0)
printf("\n\t 未找到该人的信息!\n");
return NULL;
}
else if (strcmp(ID, tree->info->ID) < 0) {
return searchByID(tree->left, ID);
}
else if (strcmp(ID, tree->info->ID) > 0) {
return searchByID(tree->right, ID);
}
else {
//找到了,输出信息
printf("\t 姓名:%s,\t\t年龄:%d,\t身份证:%s,\t性别:%c,\t配偶:%s\n",
tree->info->name, tree->info->age, tree->info->ID, tree->info->sex, tree->info->partner);
return tree->info;
}
}//通过姓名来查找,通过前序遍历一遍树
int searchByName(Node* tree, char* name, int type) {
//结婚的中选取
if (type == 1) {
if (name == NULL) {
printf("名称输入有误");
return 0;
}if (tree) {
if (!strcmp(tree->info->name, name)) {
//找到了,输出信息
printf("\t 姓名:%s,\t\t年龄:%d,\t身份证:%s,\t性别:%c,\t配偶:%s\n",
tree->info->name, tree->info->age, tree->info->ID, tree->info->sex, tree->info->partner);
return 1;
}
return searchByName(tree->left, name, type) + searchByName(tree->right, name, type);
}
}
else {
//离婚的中查询
if (divorce == NULL)
return 0;User* q = divorce->next;
int times = 0;
while (q) {
if (!strcmp(q->name, name))
{
//找到了相同名字的人
times++;
printf("\t 姓名:%s,\t\t年龄:%d,\t身份证:%s,\t性别:%c,\t配偶:%s\n",
q->name, q->age, q->ID, q->sex, q->partner);
}
q = q->next;
}
if (times > 0)
return 1;
}
return 0;
}//查找替换节点
Node* findrepalceNode(Node* node) {
//找到右子树上最小节点或左子树上的最大节点
if (node->left != NULL) {
//左子树的最大节点
Node* max = node->left;
while (max->right != NULL) {
max = max->right;
}
return max;
}
else if (node->right != NULL) {
//右子树的最小节点
Node* min = node->right;
while (min->left != NULL) {
min = min->left;
}
return min;
}
else {
//两种都不是
return NULL;
}}
//是否确认输入
int yes_no_divorce() {
char yes_no[5];
memset(yes_no, 0, sizeof(yes_no));
printf("\n\t\t=======================================\n");
printf(" \n\t\t\t是否为离婚? \n");
printf("\n\t\t=======================================\n");
printf("\n\t\t\t y 是离婚 n 是删除 [Y/N]:");
scanf("%s", yes_no);
//清空缓存区
fflush(stdin);
if (strcmp(yes_no, "y") == 0 || strcmp(yes_no, "Y") == 0)
return 1;
else
return 0;
}//删除一个结点
Node* del(Node* tree, User* info) {
// 判断传入的 info 是否为空
if (info == NULL || tree == NULL || ((tree->right == NULL) && (tree->left == NULL) && strcmp(tree->info->ID, info->ID)==0)) {
return NULL;
}if (strcmp(info->ID, tree->info->ID) > 0) {
// 递归删除右子树中的节点
tree->right = del(tree->right, info);
}
else if (strcmp(info->ID, tree->info->ID) < 0) {
// 递归删除左子树中的节点
tree->left = del(tree->left, info);
}
else {
// 找到了要删除的节点
nums--;if (tree->left == NULL || tree->right == NULL) {
// 被删除的节点有一个子节点或者没有子节点// 用子节点来代替当前节点
Node* child;
if (tree->left == NULL) {
child = tree->right;
}
else {
child = tree->left;
}
free(tree->info);
free(tree);
return child;
}
else {
// 被删除的节点有两个子节点
Node* replacenode = findrepalceNode(tree);
tree->info = replacenode->info;
tree->right = del(tree->right, replacenode->info);
}
}// 更新节点高度并进行平衡操作
tree->height = max(getHeight(tree->left), getHeight(tree->right)) + 1;
tree = balance(tree);
return tree;
}//显示已结婚所有数据,通过前序遍历实现
void display_tree(Node* tree) {
if (tree) {
printf("\t 姓名:%s,\t\t年龄:%d,\t身份证:%s,\t性别:%c,\t配偶:%s\n",
tree->info->name, tree->info->age, tree->info->ID, tree->info->sex, tree->info->partner);
display_tree(tree->left);
display_tree(tree->right);
}
}//添加一个双方的婚姻信息(添加婚姻信息)
Node* add_both(Node* tree) {
//定义好变量
char name[NameMax];
char partner_name[NameMax];
char* ID;
char* partner_ID;
int age;
int partner_age;
char sex;
int partner_sex;//输入一方的结婚信息
printf("\t\t 请输入姓名:");
scanf("%s", name);
printf("\t\t 请输入身份证:");
ID = correct_ID();
printf("\t\t 请输入年龄:");
getchar();
scanf("%d", &age);
printf("\t\t 请输入性别(M/F):");
getchar();
scanf(" %c", &sex);
printf("\t\t 请输入配偶姓名:");
scanf("%s", partner_name);
printf("\t\t 请输入配偶身份证:");
partner_ID = correct_ID();
printf("\t\t 请输入配偶年龄:");
getchar();
scanf("%d", &partner_age);
printf("\t\t 请输入配偶性别(M/F):");
getchar();
scanf(" %c", &partner_sex);
getchar();User* info = (User*)malloc(sizeof(User));
(info->next) = NULL;
User* info2 = (User*)malloc(sizeof(User));
(info2->next) = NULL;if (GetConfirm()) {
info->age = age;
info->sex = sex;
strcpy(info->name, name);
strcpy(info->ID, ID);
strcpy(info->partner, partner_name);
strcpy(info->partner_ID, partner_ID);
//先插入本人的身份信息到树中
printf("\t 姓名:%s,年龄:%d,身份证:%s,性别:%c,配偶:%s\n",
info->name, info->age, info->ID, info->sex, info->partner);
tree = insert(tree, info);//复制配偶的信息
info2->age = partner_age;
info2->sex = partner_sex;
strcpy(info2->name, partner_name);
strcpy(info2->ID, partner_ID);
strcpy(info2->partner, name);
strcpy(info2->partner_ID, ID);
printf("\t 姓名:%s,年龄:%d,身份证:%s,性别:%c,配偶:%s\n",
info2->name, info2->age, info2->ID, info2->sex, info2->partner);
//先插入配偶的身份信息到树中
tree = insert(tree, info2);}
return tree;
}//删除一个双方婚姻信息
Node* del_node(Node* tree) {
if (nums <= 2) {
printf("\t 节点必须多于两个\n");
return tree;
}
char* del_ID;
char del_partnerID[20];
//输入信息
printf("\t\t 请输入要删除人的身份证:");
del_ID = correct_ID();
//查找节点
User* user1, * user2;
user1 = searchByID(tree, del_ID);
if (user1 == NULL)
return tree;
strcpy(del_partnerID, user1->partner_ID);
user2 = searchByID(tree, del_partnerID);if (GetConfirm()) {
if (yes_no_divorce()) {
//返回值为1,代表离婚
User* p, * q;
p = q = divorce;
if (divorce->next != NULL) {
//遍历到链表的最后一个节点
while (q) {
p = q;
q = q->next;
}
}
//插入离婚两人的信息在链表中
q = (User*)malloc(sizeof(User));
q->next = NULL;
(*q) = (*user1);
(p->next) = q;
p = (p->next);
q = (User*)malloc(sizeof(User));
q->next = NULL;
(*q) = (*user2);
p->next = q;
q->next = NULL;
}
//删除节点
tree = del(tree, user1);
tree = del(tree, user2);}
return tree;}
//登入
Admin* login(Admin* admin) {
if (admin == NULL)
{
printf("admin.txt文件出错");
exit(0);
}char admin_name[NameMax];
char admin_password[20];
int times = 0;
while (1) {
//输入管理信息
printf("\t 请输入管理员账号:");
scanf("%s", admin_name);
printf("\n");
printf("\t 请输入管理员密码:");
scanf("%s", admin_password);//判断管理员信息是否相等
if (!strcmp(admin->name, admin_name)) {
if (!strcmp(admin->password, admin_password))
break;
else
{
printf("\t 密码错误,请重新输入:\n\n");
}
}
else
{
printf("\t 管理员账号错误,请重新输入:\n\n");
}times++;
//如果密码多次出错
if (times > 4) {
printf("\t\t是否需要修改密码:\n");
if (GetConfirm()) {
printf("请输入修改的用户名:\n");
scanf("%s", admin->name);
printf("请输入修改的密码:\n");
scanf("%s", admin->password);
}
}
}
return admin;
}
//调用文件初始化一颗二叉树
Node* readFile(FILE* f) {
Node* tree = (Node*)malloc(sizeof(Node));
tree->info = (User*)malloc(sizeof(User));
tree->info = NULL;
tree = NULL;
User* temp = (User*)malloc(sizeof(User));
temp->next = NULL;
//判断文件是否为空
fseek(f, 0, SEEK_END);
long position = ftell(f);
if (position == 0) {
//printf("文件为空\n");
return NULL;
}
//文件移到开头
fseek(f, 0, SEEK_SET);
while (fscanf(f, "%s %s %d %c %s %s\n", temp->name, temp->ID, &temp->age, &temp->sex, temp->partner, temp->partner_ID) != EOF) {
tree = insert(tree, temp);//注意指针一次只能指向一个地址,新建一棵树的时候要不断的来创建一个地址空间
temp = (User*)malloc(sizeof(User));
temp->next = NULL;
}
return tree;
}//磁盘上读取一个admin文件出来
Admin* readAdmin(FILE* f) {
Admin* temp = (Admin*)malloc(sizeof(Admin));
fseek(f, 0, SEEK_SET);
fscanf(f, "%s\n%s", temp->name, temp->password);
return temp;
}//磁盘上读取一个divorve文件出来
User* readDivorce(FILE* f) {
User* p, * q, * divorce;
p = q = divorce = (User*)malloc(sizeof(User));
p->next = NULL;
q = (User*)malloc(sizeof(User));
q->next = NULL;
//判断文件是否为空
fseek(f, 0, SEEK_END);
long position = ftell(f);
if (position == 0) {
//printf("文件为空\n");
User* temp = (User*)malloc(sizeof(User));
(temp->next) = NULL;
return temp;
}
//文件移到开头
fseek(f, 0, SEEK_SET);
while ((fscanf(f, "%s %s %d %c %s %s\n", q->name, q->ID, &q->age, &q->sex, q->partner, q->partner_ID)) != EOF)
{
p->next = q;
p = p->next;
q = (User*)malloc(sizeof(User));
}
free(q);
p->next = NULL;
return divorce;
}
//前序遍历存储树到文件中
void travel_creatfile(Node* root) {
if (root == NULL || file == NULL) {
return;
}fprintf(file, "%s %s %d %c %s %s\n",
root->info->name, root->info->ID, root->info->age, root->info->sex,
root->info->partner, root->info->partner_ID);
//遍历树
travel_creatfile(root->left);
travel_creatfile(root->right);
}
User* h, * p;//树转换成链表
void User_to_list(Node* root) {
if (root == NULL)
return;
p->next = root->info;
p = p->next;
p->next = NULL;
User_to_list(root->left);
User_to_list(root->right);
}//保存文件
void saveTreeToFile(Node* temp) {
fclose(file);
if ((file = fopen("marriage.txt", "w+")) != NULL) {
//打开成功
;
}
else {
//打开失败
printf("文件打开出错:\n");
exit(0);
}
travel_creatfile(temp);
}//保存离婚信息文件
void saveDivorceToFile(User* divorce_temp) {
fclose(file_divorce);
if ((file_divorce = fopen("divorce.txt", "w+")) != NULL) {
//打开成功
;
}
else {
//打开失败
printf("文件打开出错:\n");
exit(0);
}
if (divorce_temp == NULL)
return;
User* divorce = divorce_temp->next;
//循环遍历链表,将链表数据存储到文件中
while (divorce) {
fprintf(file_divorce, "%s %s %d %c %s %s\n",
divorce->name, divorce->ID, divorce->age, divorce->sex, divorce->partner, divorce->partner_ID);
divorce = divorce->next;
}
}//保存管理员信息文件
void saveAdminToFile(Admin* admin) {fclose(file_admin);
if ((file_admin = fopen("admin.txt", "w+")) != NULL) {
//打开成功
;
}
else {
//打开失败
printf("\t 管理员信息文件打开出错:\n");
exit(0);
}
if (fprintf(file_admin, "%s\n%s", admin->name, admin->password) == EOF) {
printf("\t 管理员信息文件保存出错:\n");
}
}//统计结婚信息
void Statistical(User a[]) {
//定义并初始化数组
int aa[11] = { 0 };for (int i = 0; i < nums; i++) {
aa[a[i].age / 10]++;
}
printf("\n\t\t不同年龄阶段登记结婚统计:\n");
for (int i = 1; i < nums; i++)
printf("\n\t\t%d岁到%d岁之间有:%d人", i * 10, (i + 1) * 10 - 1, aa[i]);
putchar('\n');
}//希尔排序,升序排序
void shell_sort(User arr[], int type) {
// 初始步长
int gap = nums / 2;
while (gap > 0) {
for (int i = gap; i < nums; i++) {
User temp = arr[i];
int j = i - gap;
//进行比较
if (type == 0) {
//升序
while (j >= 0 && arr[j].age > temp.age) {
arr[j + gap] = arr[j];
j -= gap;
}
}
else {
while (j >= 0 && arr[j].age < temp.age) {
arr[j + gap] = arr[j];
j -= gap;
}
}
//交换
arr[j + gap] = temp;
}
gap /= 2; // 缩短步长
}
}//年龄排序
void sort_age(Node* tree) {
if (tree == NULL) {
printf("\t\t无数据\n");
return;
}
p = h = (User*)malloc(sizeof(User));
h->next = NULL;
User_to_list(tree);
p->next = NULL;User* pp, * head = h->next;
if (head == NULL)
{
printf("\t\t无信息\n");
return;
}
User* a = (User*)malloc(sizeof(User) * nums);
int i = 0;
while (head) {
pp = head;
*(a + i) = *head;
i++;
head = head->next;
pp->next = NULL;
}
//进行排序
printf("\t\t升序排序请输入0,降序则输入其他\n");
int type;
printf("\t\t请输入你要输入的:");
scanf("%d", &type);
shell_sort(a, type);
putchar('\n');
for (i = 0; i < nums; i++) {
printf("\t 姓名:%s,\t\t年龄:%d,\t身份证:%s,\t性别:%c,\t配偶:%s\n",
a[i].name, a[i].age, a[i].ID, a[i].sex, a[i].partner);
}
getchar();
Statistical(a);free(a);
}//查看离婚人数列表
void display_divorce() {
int divorce_num = 0;
if (divorce == NULL)
{
printf("\t 无\n");
return;
}
User* p = divorce->next;
while (p) {
printf("\t 姓名:%s,年龄:%d,身份证:%s,性别:%c,前配偶:%s\n",
p->name, p->age, p->ID, p->sex, p->partner);
divorce_num++;
p = p->next;
}
printf("\t\t\t离婚人数有: %d", divorce_num);
}//显示所有信息
void display_all(Node* tree) {
printf("\t\t已结婚:\n");
display_tree(tree);
printf("\t\t已离婚:\n");
display_divorce();
}//查找并改写该结婚信息
Node* searchcorrect_mar(Node** tree, char* ID) {
if (((*tree) == NULL) || ID == NULL)
return *tree;
if (strcmp(ID, (*tree)->info->ID) > 0) {
//在右子树中
searchcorrect_mar(&((*tree)->right), ID);
}
else if (strcmp(ID, (*tree)->info->ID) < 0) {
searchcorrect_mar(&((*tree)->left), ID);
}
else {
//找到节点了
printf("\t\t 请输入要更改的姓名:");
char name[NameMax];
scanf("%s", name);
putchar('\n');
strcpy((*tree)->info->name, name);
printf("\t\t 请输入要更改的性别:");
char sex;
//抵消多余的回车
getchar();
scanf(" %c", &sex);
putchar('\n');
printf("\t\t 请输入要更改的年龄:");getchar();
int age;
scanf("%d", &age);
(*tree)->info->sex = sex;
(*tree)->info->age = age;
return (*tree);
}
}void searchcorrect_mar2(Node** tree, User* info) {
if (((*tree) == NULL) || info->ID == NULL)
return;
if (strcmp(info->ID, (*tree)->info->ID) > 0) {
//在右子树中
searchcorrect_mar2(&((*tree)->right), info);
}
else if (strcmp(info->ID, (*tree)->info->ID) < 0) {
searchcorrect_mar(&((*tree)->left), info);
}
else {
//找到节点了
strcpy((*tree)->info->partner, info->name);
}
}//更改婚姻信息
Node* correct_marriage(Node* tree) {
User* newnode = (User*)malloc(sizeof(User));
char* ID;
printf("\t\t输入你要更改人的身份证: ");
ID = correct_ID();
if (ID == NULL) {
printf("输入出错");
exit(0);
}
Node* temp = searchcorrect_mar(&tree, ID);
if (temp != temp)
searchcorrect_mar2(&tree, temp->info); //在结婚信息中找到节点了
else {
User* p = divorce->next;
printf("\t\t 请输入要更改的姓名:");
char name[NameMax];
scanf("%s", name);
putchar('\n');
printf("\t\t 请输入要更改的性别:");
char sex;
//抵消多余的回车
getchar();
scanf(" %c", &sex);
putchar('\n');
printf("\t\t 请输入要更改的年龄:");
getchar();
int age;
scanf("%d", &age);
while (p) {
if (!strcmp(p->ID, ID)) {
//在离婚信息中找到节点了
strcpy(p->name, name);
p->sex = sex;
p->age = age;
}
p = p->next;
}
}
return tree;
}//更改管理员信息
Admin* correct_admin() {
if (file_admin == NULL) {
printf("Admin信息文件出错");
exit(0);
}
else
fclose(file_admin);Admin* new = (Admin*)malloc(sizeof(Admin));
printf("\t\t输入你要更改人的管理员账号: ");
scanf("%s", new->name);
printf("\t\t输入你要更改人的管理员密码: ");
scanf("%s", new->password);
//判断存储管理员信息的文件是否存在,是否能打开
if ((file_admin = fopen("admin.txt", "w+")) != NULL) {
//打开成功
;
}
else {
//打开失败
printf("\t 管理员信息文件打开出错:\n");
exit(0);
}
if (fprintf(file_admin, "%s\n%s", new->name, new->password) == EOF) {
printf("\t 管理员信息文件保存出错:\n");
}
fclose(file_admin);
return new;
}//打印菜单
void memu() {printf("\n\t\t***************************************\n");
printf("\t\t* 请选择要进行的操作: *\n");
printf("\t\t* 1. 添加婚姻信息 *\n");
printf("\t\t* 2. 删除婚姻信息 *\n");
printf("\t\t* 3. 按身份证查询 *\n");
printf("\t\t* 4. 显示信息 *\n");
printf("\t\t* 5. 修改婚姻信息 *\n");
printf("\t\t* 6. 按姓名查询 *\n");
printf("\t\t* 7. 按年龄进行排序 *\n");
printf("\t\t* 8. 清屏 *\n");
printf("\t\t* 9. 显示菜单 *\n");
printf("\t\t* a. 修改管理员信息 *\n");
printf("\t\t* b. 保存并退出 *\n");
printf("\t\t* c. 保存文件 *\n");
printf("\t\t***************************************\n\n");
}//打开所有的文本文件
void open_allfile() {
//open_file(file, file_admin);
//判断存储婚姻信息的文件是否存在,是否能打开
if ((file = fopen("marriage.txt", "r+")) != NULL) {
//打开成功
;
}
else {
//打开失败
printf("\t\t 婚姻信息文件打开出错:\n");
exit(0);
}//判断存储管理员信息的文件是否存在,是否能打开
if ((file_admin = fopen("admin.txt", "r+")) != NULL) {
//打开成功
;
}
else {
//打开失败
printf("\t 管理员信息文件打开出错:\n");
exit(0);
}//判断存储离婚信息的文件是否存在,是否能打开
if ((file_divorce = fopen("divorce.txt", "r+")) != NULL) {
//打开成功
;
}
else {
//打开失败
printf("\t 离婚信息文件打开出错:\n");
exit(0);
}
}//后序释放空间
void free_tree(Node** root) {
if (*root == NULL)
return;
free_tree(&((*root)->left));
free_tree(&((*root)->right));
free((*root)->info);
free(*root);
}void free_other(User** h, Admin** admin) {
free(*admin);User* p = (*h)->next;
while (p) {
free(*h);
*h = p;
p = p->next;
}
}//运行程序操作
void running() {
//打开所有文件
open_allfile();Admin* admin = readAdmin(file_admin);
Node* tree = readFile(file);
divorce = readDivorce(file_divorce);admin = login(admin);
char option[10];
memu();
while (1) {
printf("\n\t\t请输入您的选项:");
scanf("%s", option);
printf("\n");
switch (option[0]) {
//添加
case '1':
tree = add_both(tree);
break;
case '2':
//删除
tree = del_node(tree);
break;
case '3':
//身份证查询
printf("\t\t 请输入要查询的身份证号: ");
char* ID;
ID = correct_ID();
searchByID(tree, ID);
break;
case '4':
//查看信息
{
int type;
printf("\t\t 请输入要查看的信息:\n ");
printf("\t\t 1、已结婚人的信息 \n");
printf("\t\t 2、已离婚人的信息\n ");
printf("\t\t 3、所有人的信息 \n");
printf("\t\t 请输入要查询选项(1-3): ");
//判断输入的类型
scanf("%d", &type);
switch (type)
{
case 1:
display_tree(tree); break;
case 2:
display_divorce(); break;
case 3:
display_all(tree);
break;
default:
break;
}
putchar('\n');
break;
}
case '5':
//修改婚姻信息
tree = correct_marriage(tree);
break;
case '6':
{
printf("\t\t 请输入查询类别:\n");
printf("\t\t 1、查询结婚人信息:\n");
printf("\t\t 2、查询离婚人的姓名:\n");
int type;
printf("\t\t 请输入要查询的选项(1-2):");
scanf("%d", &type);
printf("\t\t 请输入要查询的姓名:");
char nameToSearch[NameMax];
scanf("%s", nameToSearch);
int judge = searchByName(tree, nameToSearch, type);
if (judge != 1) {
printf("\t\t查无此人,请检查后再试!\n");
}
}
break;
case '7':
//按年龄进行排序
sort_age(tree);
break;
default:
printf("\t\t无效的选项!\n");
break;
break;
case '9':
memu();
break;
case '8':
system("cls");
break;
case 'a':
//修改管理员信息
admin = correct_admin();
break;
case 'b':
system("cls");
printf("\n\n\t\t\t\t 程序已退出!\n");
printf("\n\t\t\t\t 欢迎下次使用!\n");
saveTreeToFile(tree);
saveDivorceToFile(divorce);
saveAdminToFile(admin);fclose(file);
fclose(file_divorce);
fclose(file_admin);free_tree(&tree);
free_other(&divorce, &admin);
exit(0);
case 'c':
saveTreeToFile(tree);
saveDivorceToFile(divorce);
saveAdminToFile(admin);
printf("\t\t 保存成功!\n");
break;
}
}}
int main() {
running();
return 0;
}