数据结构课设之家谱管理系统暴肝四万字,看完你也可以

Posted _白白不白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构课设之家谱管理系统暴肝四万字,看完你也可以相关的知识,希望对你有一定的参考价值。

前言

好久没有更新博客了,是因为一直在准备期末考试,时间太忙了,此时此刻我还没有全部考完,等我考完之后正常更新!

这个是我数据结构期末的一个课程设计,也算是一个比较庞大的程序了吧,写出来还是蛮不容易的!分享出来希望能对大家有帮助!

课设题目

家谱管理系统
【问题描述】
实现具有下列功能的家谱管理系统
【功能要求】
(1)输入文件以存放最初家谱中各成员的信息,成员的信息中均应包含以下内容:姓名、出生日期、婚否、地址、健在否、死亡日期(若其已死亡),也可附加其它信息、但不是必需的。
(2)实现数据的存盘和读盘。
(3)以图形方式显示家谱。
(4)显示第n代所有人的信息。
(5)按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)。
(6)按照出生日期查询成员名单。
(7)输入两人姓名,确定其关系。
(8)某成员添加孩子。
(9)删除某成员(若其还有后代,则一并删除)。
(10)修改某成员信息。
(11)按出生日期对家谱中所有人排序。
(12)打开一家谱时,提示当天生日的健在成员。
【基本要求】
建立至少30个成员的数据,以较为直观的方式显示结果,并提供文稿形式以便检查。
【界面要求】
有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。
【存储结构】
学生自己根据系统功能要求自己设计,但是要求相关数据要存储在数据文件中。

界面展示

这里展示一小部分,其他的大家后期根据代码慢慢了解


代码实现

这个系统写起来还是比较庞大的,需要定义很多函数来慢慢实现,所以我们把所有需要用到的头文件和函数的定义都存放在我自己定义的头文件里面,这样我们使用时,只需要导入我们自己定义的头文件即可

自定义头文件

文件名为:Head_total.h

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h> 
#include <time.h>

#define len 30


//日期-年月日
struct Date 
 
	int year;     
	int month;     
	int day;      
; 

struct Info 

	int children_count;//孩子数-hzshu
	int alive;
	int alive_day;//活了多少日-ri
    int marry;//婚否-jiehun
	char name[20];//姓名 
	char birth_place[20];//出生地点 -birthplace[20]
	Date birth_date;//结构date定义的出生日期 
	Date death_date;//结构date定义的死亡日期 
	int sex;//性别 
	char wife_or_husband[20];//配偶
	char address[50];//家庭住址
	char resume[100];//简历
	
	//其他信息如下
	int height;//高度 
	char occupation[20];//职业 
	char education[20];//受教育程度 
	char parent_name[20];//父亲姓名,用于添加节点时用 
	int Depth;//二叉树深度,输出二叉树时用 
; 


typedef struct CSNode 
 
	Info data;       //个人信息类型结构 
	CSNode *first_child,*next_brother,*parent;   //csnode的第一个孩子节点,下一个兄弟节点,双亲节点
*person; 


//定义链式队列结点
typedef person QElemType;
typedef struct QNode

	QElemType data;
	struct QNode *next;
QNode,*QueuePtr;


typedef struct 
	QueuePtr front,rear;
LinkQueue;

//函数声明
void start_up(person &T);//给结点置空
void main_menu(person &);//主菜单
int Create_familytree(person &,person &);//创建家谱树
person find_name(person &,char Name[]);//按姓名查找指定成员函数
int birth_date(person &);//输入出生日期
int death_date(person &); //输入死者死亡日期
int judge_birth_date(person &);  //判断出生日期是否在今天之前
int judge_death_date(person &); //判断死亡日期死亡日期是否正确
void survival_day_sum(int &,int &,int &,int &,int &,int &);//计算生存天数

void level(person &); //计算每位家族成员的辈分
void level_every(person &);//计算一位家族成员的辈分
void sort(person &); //排序
void sort_every(person &);//为一个父亲的孩子按出生日期排序
void add_new_member(person &);//添加成员函数  

void preserve(person &);//保存成员信息函数
void preserve_member(person &,FILE *);//保存一个成员信息函数
void preserve_family(person &,FILE *); //保存所有成员信息函数
int DeQueue(LinkQueue &,QElemType &);//出队列操作
void InitQueue(LinkQueue &);//构造一个空队列
int QueueEmpty(LinkQueue );//判断链式队列是否为空
void EnQueue(LinkQueue &,QElemType ); //进队列操作

void start_correct(person &);//该函数的作用是每次从打开家谱,都会根据现在的时间重新计算活着的成员的寿命
void show(person &); //显示家谱树函数
void read_node(person &,FILE *);//从文件中读取所有成员节点
void read_node_every(person &,FILE *); //从文件中读取一个成员节点
void show_tree_member(person &);//每一个具体展现
void show_tree(person &);//把家谱成员姓名通过一个层次化的家谱树显示出来

void lookup(person &);//通过名字查找相应的成员,并显示其信息
void show_member(person &); //显示一个成员所有信息的函数
void Delete(person &);//采用后续遍历的方法删除成员节点
void find(person &);  //通过关键字搜索家谱成员
int kmp(char str[], char ptrn[]); //KMP算法,用于搜索简历内容
void member_message_num(person &);  //统计家谱成员信息函数
void relation(person &);
void QuickSort(person e[], int , int ); //快速排序算法,用于寿命排序

主函数

准备工作结束之后,接下来看看主函数

主函数就是产生一个空结点,用于家族谱的判空操作,然后进入这个系统的主界面

#include "Head_total.h"

void main()        //主函数

    person T;
	T=(person)malloc(sizeof(CSNode));
	start_up(T);
	strcpy(T->data.name,"0");         //首先设置第一个节点的成员姓名为0,用于家族谱的判空操作
	main_menu(T);
	return;



void start_up(person &T)       //初始化,把指针置为空

	T->parent=NULL;
	T->first_child=NULL;
	T->next_brother=NULL;
	return;

菜单界面

接下来看看这个系统的主界面

它主要通过while循环与switch来实现功能,并且通过 SetConsoleTextAttribute()函数来控制控制台窗口字体颜色和背景色,使界面更加优美

原谅我调不出好看的颜色。。

#include "Head_total.h"

void main_menu(person &T)        //主菜单程序

	int j=1;
	char i;
	while (j)
	
		system("cls");     //清屏
		HANDLE consolehwnd;
		consolehwnd = GetStdHandle(STD_OUTPUT_HANDLE); 
		SetConsoleTextAttribute(consolehwnd,FOREGROUND_INTENSITY|FOREGROUND_GREEN);    //设置屏幕字体颜色
		printf("\\t"); 
		printf("\\n\\n\\t              *******家谱管理系统课设版1.0*******    ");
		SetConsoleTextAttribute(consolehwnd,FOREGROUND_INTENSITY  | FOREGROUND_BLUE);
		printf("\\n\\t\\t---------------------------------------------\\n\\t");
		SetConsoleTextAttribute(consolehwnd,FOREGROUND_INTENSITY |FOREGROUND_GREEN | FOREGROUND_BLUE); 		
		//printf("\\t\\t       家谱管理系统\\n\\t");
		printf("\\t\\t   0. 退出系统              \\n\\t");
		printf("\\t\\t   1. 新创建家谱树          \\t\\n\\t");
		printf("\\t\\t   2. 添加家谱成员          \\t\\n\\t");
		printf("\\t\\t   3. 保存家谱信息到文件    \\t\\n\\t");
		printf("\\t\\t   4. 从文件读取显示家谱    \\t\\n\\t");
		printf("\\t\\t   5. 按姓名查找家谱成员    \\t\\n\\t");
		printf("\\t\\t   6. 按关键字查找家谱成员  \\t\\n\\t");
		printf("\\t\\t   7. 统计家谱成员          \\t\\n\\t");
		printf("\\t\\t   8. 通过名字确定两人关系  \\t\\n\\t");
		SetConsoleTextAttribute(consolehwnd,FOREGROUND_INTENSITY  | FOREGROUND_BLUE); 
		printf("\\t---------------------------------------------\\n\\t");
		printf("\\t请输入你的操作(0~8):\\n");
		i=getchar();
		fflush(stdin);//刷新缓冲区,将缓冲区内的数据清空并丢弃
		switch(i)
		
		case '0':
			j=0;
			break;
		case '1':
			system("cls");     //清屏
			if(strcmp(T->data.name,"0")==0)
			
				printf("下面请输入祖先的信息\\n");
				person b;
				b=(person)malloc(sizeof(CSNode));
				start_up(b);
				if(Create_familytree(b,T))
				
					T=b;
					level(T);
					sort(T);
					printf("\\n\\t        *****    家谱树已建立完成    ***** \\n\\t");
				
			
			else
				printf("家谱树已存在,要新建家谱树请先删除原有家谱树!\\n");
			
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");          //程序运行到此处会暂停,等待键盘命令
			break;
		case '2':
			system("cls");     //清屏
			add_new_member(T);
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");
			break;
		case '3':
			system("cls");     //清屏
			if(strcmp(T->data.name,"0"))
				preserve(T);
			else
				printf("家谱树为空,无法保存!\\n");
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");
			break;
		case '4':
			system("cls");     //清屏
			show(T);
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");
			break;
		case '5':
			system("cls");     //清屏
			lookup(T);
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");
			break;
		case '6':
			system("cls");     //清屏
			find(T);
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");
			break;
		case '7':
			system("cls");     //清屏
			member_message_num(T);
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");
			break;
		case '8':
			system("cls");     //清屏
			relation(T);
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");
			break;
		default:
			printf("你的操作有误,请重新选择!\\n");
			fflush(stdin);
			system("pause");	
		
	
	return;

既然是switch控制各个功能的实现那么我们就一个case一个case的看吧!

case1——新建家谱树

第一个case是实现新家谱树的创建的,下面是主界面中case1的部分

case '1':
			system("cls");     //清屏
			if(strcmp(T->data.name,"0")==0)
			
				printf("下面请输入祖先的信息\\n");
				person b;
				b=(person)malloc(sizeof(CSNode));
				start_up(b);
				if(Create_familytree(b,T))
				
					T=b;
					level(T);
					sort(T);
					printf("\\n\\t        *****    家谱树已建立完成    ***** \\n\\t");
				
			
			else
				printf("家谱树已存在,要新建家谱树请先删除原有家谱树!\\n");
			
			fflush(stdin);
			printf("\\n即将返回主菜单!\\n");
			system("pause");          //程序运行到此处会暂停,等待键盘命令
			break;

首先还是判断家谱树是否为空,如果为空才能建立家谱树,因为一个家谱里面只能记录一个家族,只有家谱树为空时才能继续建立,建立函数如下:

#include "Head_total.h"

//创建家谱树函数,即为空家谱添加一个祖先
int Create_familytree(person &F,person &T)          

	int i,j=1;
	person a; 
    a=(person)malloc(sizeof(CSNode));
	start_up(a);
	printf("请输入此人名字:\\n");
	scanf("%s",F->data.name);
    fflush(stdin);
	a=find_name(T,F->data.name);
	if(a)
	
		printf("此人已存在该家谱中!\\n");
		return 0;
	
	printf("请输入此人性别(男输入1,女输入0):\\n");
	while(j)
	
        scanf("%d",&(F->data.sex));
		fflush(stdin);
		switch(F->data.sex)
		
		case 1:
			j=0;
			break;
		case 0:
			j=0;
			break;
		default:
			printf("输入数据有误,请重新输入!\\n");
			fflush(stdin);
			break;
		
	
	printf("请输入此人身高(单位:cm):\\n");
	scanf("%d",&(F->data.height));
	fflush(stdin);
	printf("请输入此人居住地址:\\n");
	scanf("%s",F->data.address);
	fflush(stdin);
    printf("请输入此人父亲的名字(无父亲请输入0):\\n你有3次机会\\n");
	i=3;
    while(i)
	
		scanf("%s",F->data.parent_name);
		fflush(stdin);
		if(strcmp(F->data.parent_name,"0")==0)
			break;
		else
		
			

以上是关于数据结构课设之家谱管理系统暴肝四万字,看完你也可以的主要内容,如果未能解决你的问题,请参考以下文章

大学课设之Mysql图书管理设计

Android 课设之个人音乐播放器

一文讲透链表操作,看完你也能轻松写出正确的链表代码

两周从爬虫小白变大神,看完你就知道我不是标题党了五万字教程,建议收藏

一文讲透链表操作,看完你也能轻松写出正确的链表代码

一文讲透链表操作,看完你也能轻松写出正确的链表代码