题目:新冠轨迹存储与查询(二叉树)
翻译一下:写一个小App,开始界面需要用户选择数据的存储方式(单链表/二叉树),选好后用户要选择action:
- 添加新的用户
- 给已经存在的用户添加新的去过的地方
- 删除用户信息
- 把整个二叉树中的结构体存入文件中
- 从已经存好的文件中载入信息
- 查询哪个用户曾经去过高风险地区
- 退出程序
注意:
- 二叉树的增添,删除,要考虑删除的节点是子节点还是某个父结点
- 把结构体存入文件时记得存入二叉树结点的个数,这样方便我们读取文件时还原
下面的是程序本体
- 程序中有很多地方存在代码重复,(二叉树遍历)(查询特定的信息并输出)要适当进行变换以达到函数的重复利用
主程序
int main(int argc, char *argv){
int mode=0; /* 0 for linked list, 1 for binary tree */
int option;
char user_name[100];
int place;
char file[50];
printf("Welcome to the Covid app\n");
/* Set up mode variable depending on argv */
do{
printf("\nMenu\n");
printf("1-Introduce user\n2-Introduce visit to venue\n3-Remove user\n4-Check users have been in a place\n5-Save to file\n6-Retrieve data from file\n7-Show All users\n8-Exit\n");
printf("Your Choice: ");
scanf("%d",&option);
switch(option)
{
case 1: /* Introduce user */
printf("Enter user name\n");
scanf("%s",user_name);
struct user_bt *usr = (struct user_bt*)malloc(sizeof(struct user_bt));
strcpy(usr->name,user_name);
usr->left =NULL;
usr->right =NULL;
usr->n_places_visited =0;
insert_user_bt(usr);
printf("\n");
break;
case 2: /*2) Introduce visit to venue*/
printf("Enter user name\n");
scanf("%s",user_name);
printf("Enter the place\n");
scanf("%d",&place);
insert_visit_bt(user_name, place);
printf("\n");
break;
case 3: /* Remove user*/
printf("Enter user name\n");
scanf("%s",user_name);
int flag =remove_user_bt(root,user_name);
if(flag){
printf("delet %s successfully\n", user_name);
}
else{
printf("this name does not exist\n");
}
break;
case 4: /*Check users have been in a place*/
printf("Enter the place\n");
scanf("%d",&place);
show_user_bt(root,place,2," ");
break;
case 5: /* Save to file */
printf("Enter the file path\n");
scanf("%s",file);
save_num_to_file_bt(file, count);
//we have to put 4 variable, but in this case, we only need 3 var
//the pointer from root to each node, the purpose is 3(which means the app will store the file)
show_user_bt(root,0,3,file);
printf("\nSave Successfully\n");
break;
case 6: /* Retrieve data from file*/
printf("Enter the file path\n");
scanf("%s",file);
read_from_file_bt(fopen(file,"rb"));
break;
case 7: /*Show All users*/
show_user_bt(root,0,1," ");
printf("\n");
break;
case 8: /* Exit */
printf("Goodbye\n");
break;
default:
break;
}
}
while(option!=8);
return 0;
}
插入用户
//add the user, we store the user Node from the root(if root is not NULL)
void insert_user_bt(struct user_bt *value){
if(value == NULL){
return;
}
if(root == NULL){
root = value;
count ++;
return;
}
char *name = value->name;
// printf("hello");
struct user_bt *cur =root;
// printf("%s %s",name, cur->name);
while(1){
if(strcmp(name,cur->name) < 0 && cur->left != NULL){
cur = cur->left;
}
else if(strcmp(name,cur->name) > 0 && cur->right != NULL){
cur = cur->right;
}
if(cur->left == NULL&& strcmp(name,cur->name) < 0){
cur->left = value;
count ++;
break;
}
else if(cur->right == NULL && strcmp(name,cur->name) > 0){
cur->right = value;
count ++;
break;
}
}
}
删除用户
//remove the user
int remove_user_bt(struct user_bt *begin,char *name)
{
struct user_bt *cur = begin;
//head, if the user is the root Node
if(strcmp(root->name,name) == 0){
count--;
struct user_bt *lp = root->left;
struct user_bt *rp = root->right;
if(rp != NULL){
root = rp;
insert_user_bt(lp);
}else{
root = lp;
}
return 1;
}
//left, if the User Node is in the left area of the tree
if(cur->left != NULL &&strcmp(cur->left->name,name) == 0){
count--;
struct user_bt *temp = cur->left;
struct user_bt *lp = temp->left;
struct user_bt *rp = temp->right;
if(lp==NULL && rp==NULL){
cur->left = NULL;
return 1;
}
cur->left = lp;
insert_user_bt(rp);
return 1;
}
//right area
else if(cur->right != NULL &&strcmp(cur->right->name,name) == 0){
count--;
struct user_bt *temp = cur->right;
struct user_bt *lp = temp->left;
struct user_bt *rp = temp->right;
if(lp==NULL && rp==NULL){
cur->right = NULL;
return 1;
}
cur->right = rp;
insert_user_bt(lp);
return 1;
}
else{
//recursion to search
if(cur->left != NULL && strcmp(name,cur->name) < 0){
return remove_user_bt(cur->left, name);
}
if(cur->right != NULL && strcmp(name,cur->name) > 0){
return remove_user_bt(cur->right, name);
}
}
return 0;
}
添加途径地
//add the place somebody ever been
void insert_visit_bt(char *name, int place)
{
struct user_bt *p = root;
while(1){
if(strcmp(name,p->name)<0){
p = p->left;
}else if(strcmp(name,p->name) >0){
p = p->right;
}else{
p->places[p->n_places_visited] = place;
p->n_places_visited += 1;
return;
}
if(p == NULL){
printf("\nuser name does not exist\n");
break;
}
}
}
文件存储
注意:为了避免程序代码重复,还有一部分文件存储的部分在下面的函数中
//we need to count how many stucts put into the file, so that we can extract them successfully
void save_num_to_file_bt(char *path, int count)
{
remove(path);
FILE *fp = fopen(path,"ab+") ;
fwrite(&count,sizeof(int),1,fp);
fclose(fp);
}
//save struct to file
void save_to_file_bt(FILE *fp, struct user_bt *temp)
{
fwrite(temp, sizeof(struct user_bt),1,fp);
fclose(fp);
}
文件读取
//read structs from file
void read_from_file_bt(FILE *read)
{
if(read==NULL){
printf("\tFile does not exist!!\n");
return;
}
root = NULL;
//read the num from file which is the total number of struct
int num = 0;
fread(&num,sizeof(int),1,read);
int i=0;
//
while(i<num){
struct user_bt *temp= (struct user_bt*)malloc(sizeof(struct user_bt));
fread(temp,sizeof(struct user_bt),1,read);
temp->left = NULL;
temp->right =NULL;
insert_user_bt(temp);
i++;
}
printf("\tLoading Successfully\n");
fclose(read);
}
陈列所有人的信息 / 查询有谁经过了高风险地区 / 文件存储操作后部分
//this function is powerful
/*
struct user_bt *path is the root, the beginning of this binary tree
int place when we use this function to store places users ever been, in other areas, it is showed 0
int purpose it decided which function we will use of this function
1 means print all the information
2 means show somebody who ever been to someplace
3 means store each struct Node into the file
char *file this is the path of the file we store data
*/
void show_user_bt(struct user_bt *path, int place, int purpose, char *file){
if(path == NULL){
printf("Is empty\n");
return;
}
//here is the recursion to the left
if(path->left !=NULL){
show_user_bt(path->left, place, purpose, file);
}
if(purpose ==1){
printf("%s: ",path->name);
int i=0;
// printf("%d",path->n_places_visited);
while(i< path->n_places_visited){
printf("%d ",path->places[i]);
i++;
}
printf("\n");
}
else if(purpose == 2){
int i=0;
while(i<path->n_places_visited){
if(path->places[i] == place){
printf("%s has been to %d\n",path->name, place);
};
i++;
}
}
else if(purpose == 3){
save_to_file_bt(fopen(file,"ab+"),path);
}
//here is the recursion to the right
if(path->right != NULL){
show_user_bt(path->right, place, purpose, file);
}
}
最终合体
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
/* struct for the Binary tree*/
struct user_bt{
char name[100];
int places[100];
int n_places_visited;
struct user_bt *left;
struct user_bt *right;
};
struct user_bt *root=NULL;
int count=0; //count is used to store how many people are store in the file
//add the user, we store the user Node from the root(if root is not NULL)
void insert_user_bt(struct user_bt *value){
if(value == NULL){
return;
}
if(root == NULL){
root = value;
count ++;
return;
}
char *name = value->name;
// printf("hello");
struct user_bt *cur =root;
// printf("%s %s",name, cur->name);
while(1){
if(strcmp(name,cur->name) < 0 && cur->left != NULL){
cur = cur->left;
}
else if(strcmp(name,cur->name) > 0 && cur->right != NULL){
cur = cur->right;
}
if(cur->left == NULL&& strcmp(name,cur->name) < 0){
cur->left = value;
count ++;
break;
}
else if(cur->right == NULL && strcmp(name,cur->name) > 0){
cur->right = value;
count ++;
break;
}
}
}
//remove the user
int remove_user_bt(struct user_bt *begin,char *name)
{
struct user_bt *cur = begin;
//head, if the user is the root Node
if(strcmp(root->name,name) == 0){
count--;
struct user_bt *lp = root->left;
struct user_bt *rp = root->right;
if(rp != NULL){
root = rp;
insert_user_bt(lp);
}else{
root = lp;
}
return 1;
}
//left, if the User Node is in the left area of the tree
if(cur->left != NULL &&strcmp(cur->left->name,name) == 0){
count--;
struct user_bt *temp = cur->left;
struct user_bt *lp = temp->left;
struct user_bt *rp = temp->right;
if(lp==NULL && rp==NULL){
cur->left = NULL;
return 1;
}
cur->left = lp;
insert_user_bt(rp);
return 1;
}
//right area
else if(cur->right != NULL &&strcmp(cur->right->name,name) == 0){
count--;
struct user_bt *temp = cur->right;
struct user_bt *lp = temp->left;
struct user_bt *rp = temp->right;
if(lp==NULL && rp==NULL){
cur->right = NULL;
return 1;
}
cur->right = rp;
insert_user_bt(lp);
return 1;
}
else{
//recursion to search
if(cur->left != NULL && strcmp(name,cur->name) < 0){
return remove_user_bt(cur->left, name);
}
if(cur->right != NULL && strcmp(name,cur->name) > 0){
return remove_user_bt(cur->right, name);
}
}
return 0;
}
//add the place somebody ever been
void insert_visit_bt(char *name, int place)
{
struct user_bt *p = root;
while(1){
if(strcmp(name,p->name)<0){
p = p->left;
}else if(strcmp(name,p->name) >0){
p = p->right;
}else{
p->places[p->n_places_visited] = place;
p->n_places_visited += 1;
return;
}
if(p == NULL){
printf("\nuser name does not exist\n");
break;
}
}
}
//we need to count how many stucts put into the file, so that we can extract them successfully
void save_num_to_file_bt(char *path, int count)
{
remove(path);
FILE *fp = fopen(path,"ab+") ;
fwrite(&count,sizeof(int),1,fp);
fclose(fp);
}
//save struct to file
void save_to_file_bt(FILE *fp, struct user_bt *temp)
{
fwrite(temp, sizeof(struct user_bt),1,fp);
fclose(fp);
}
//read structs from file
void read_from_file_bt(FILE *read)
{
if(read==NULL){
printf("\tFile does not exist!!\n");
return;
}
root = NULL;
//read the num from file which is the total number of struct
int num = 0;
fread(&num,sizeof(int),1,read);
int i=0;
//
while(i<num){
struct user_bt *temp= (struct user_bt*)malloc(sizeof(struct user_bt));
fread(temp,sizeof(struct user_bt),1,read);
temp->left = NULL;
temp->right =NULL;
insert_user_bt(temp);
i++;
}
printf("\tLoading Successfully\n");
fclose(read);
}
//this function is powerful
/*
struct user_bt *path is the root, the beginning of this binary tree
int place when we use this function to store places users ever been, in other areas, it is showed 0
int purpose it decided which function we will use of this function
1 means print all the information
2 means show somebody who ever been to someplace
3 means store each struct Node into the file
char *file this is the path of the file we store data
*/
void show_user_bt(struct user_bt *path, int place, int purpose, char *file){
if(path == NULL){
printf("Is empty\n");
return;
}
//here is the recursion to the left
if(path->left !=NULL){
show_user_bt(path->left, place, purpose, file);
}
if(purpose ==1){
printf("%s: ",path->name);
int i=0;
// printf("%d",path->n_places_visited);
while(i< path->n_places_visited){
printf("%d ",path->places[i]);
i++;
}
printf("\n");
}
else if(purpose == 2){
int i=0;
while(i<path->n_places_visited){
if(path->places[i] == place){
printf("%s has been to %d\n",path->name, place);
};
i++;
}
}
else if(purpose == 3){
save_to_file_bt(fopen(file,"ab+"),path);
}
//here is the recursion to the right
if(path->right != NULL){
show_user_bt(path->right, place, purpose, file);
}
}
int main(int argc, char *argv){
int mode=0; /* 0 for linked list, 1 for binary tree */
int option;
char user_name[100];
int place;
char file[50];
printf("Welcome to the Covid app\n");
/* Set up mode variable depending on argv */
do{
printf("\nMenu\n");
printf("1-Introduce user\n2-Introduce visit to venue\n3-Remove user\n4-Check users have been in a place\n5-Save to file\n6-Retrieve data from file\n7-Show All users\n8-Exit\n");
printf("Your Choice: ");
scanf("%d",&option);
switch(option)
{
case 1: /* Introduce user */
printf("Enter user name\n");
scanf("%s",user_name);
struct user_bt *usr = (struct user_bt*)malloc(sizeof(struct user_bt));
strcpy(usr->name,user_name);
usr->left =NULL;
usr->right =NULL;
usr->n_places_visited =0;
insert_user_bt(usr);
printf("\n");
break;
case 2: /*2) Introduce visit to venue*/
printf("Enter user name\n");
scanf("%s",user_name);
printf("Enter the place\n");
scanf("%d",&place);
insert_visit_bt(user_name, place);
printf("\n");
break;
case 3: /* Remove user*/
printf("Enter user name\n");
scanf("%s",user_name);
int flag =remove_user_bt(root,user_name);
if(flag){
printf("delet %s successfully\n", user_name);
}
else{
printf("this name does not exist\n");
}
break;
case 4: /*Check users have been in a place*/
printf("Enter the place\n");
scanf("%d",&place);
show_user_bt(root,place,2," ");
break;
case 5: /* Save to file */
printf("Enter the file path\n");
scanf("%s",file);
save_num_to_file_bt(file, count);
//we have to put 4 variable, but in this case, we only need 3 var
//the pointer from root to each node, the purpose is 3(which means the app will store the file)
show_user_bt(root,0,3,file);
printf("\nSave Successfully\n");
break;
case 6: /* Retrieve data from file*/
printf("Enter the file path\n");
scanf("%s",file);
read_from_file_bt(fopen(file,"rb"));
break;
case 7: /*Show All users*/
show_user_bt(root,0,1," ");
printf("\n");
break;
case 8: /* Exit */
printf("Goodbye\n");
break;
default:
break;
}
}
while(option!=8);
return 0;
}
实现结果