数据结构实训报告

《数据结构》课程设计指导书

一、课程设计目的

通过《数据结构课程设计》使同学们能够运用数据结构提供的方法与技巧更好地进行算法设计和程序设计,即能最好地实现与课程同步练习,又能培养同学们程序设计及上机调试的能力。希望同学们都能积极的参与课程设计,充分利用这次机会提高自己。
二、课程设计内容及要求
同学们要仔细阅读题目内容,认真主动完成课程设计的要求----题目的设计、程序的调试及书写课程设计报告。
三、课程设计时间
课程设计时间为一周。
四、课程设计考核
由指导教师根据学生完成课程设计任务的情况综合评分,具体项目包括:课题完成情况占60%、课程设计报告质量占10%、课程设计答辩占30%。成绩评定实行优、良、中、及格和不及格五个等级。
五、课程设计报告撰写与要求
(保存在word 文档中,文件名要求 按照"姓名-学号-课程设计报告"起名 )
内容包括:
(1)需求分析:在该部分中叙述,每个模块的功能要求。
(2)概要设计:在此说明每个部分的算法设计说明(可以是描述算法的流程图),每个程序中使用的存储结构设计说明(如果指定存储结构请写出该存储结构的定义。
(3)详细设计:各个算法实现的源程序,对每个题目要有相应的源程序(可以是一组源程序,每个功能模块采用不同的函数实现)源程序要按照写程序的规则来编写。要结构清晰,重点函数的重点变量,重点功能部分要加上清晰的程序注释。
(4)调试分析:测试数据,测试输出的结果。
(5)课设总结:课程设计 过程的收获、遇到问题、遇到问题解决问题过程的思考、程序调试能力的思考、对数据结构这门课程的思考、在课程设计过程中对《数据结构》课程的认识等内容

六、课程设计试题,3选2。
题例1:    
图书管理程序
1、问题描述
     图书管理程序是大家非常熟悉的信息管理软件,高校图书管理系统实现图书馆馆藏图书的信息管理与图书借阅。请使用文件和顺序表分别作为外部与内部存储,设计一个简易的图书管理程序。
2、基本要求
系统应具有以下基本功能:
①新进图书基本信息的输人。
②图书基本信息的查询。
③对撤销图书信息的删除。
④为借书人办理注册。
⑤办理借书手续。
⑥办理还书手续
3、算法分析
    本课程设计主要训练学生应用顺序表存储和管理信息的综合能力,涉及顺序表的删除、查找、插人和排序等基本算法。

题例2:
哈夫曼编/译码器
1、问题描述
利用哈夫曼编码进行信息通信可大大提高信道利用率,缩短信息传输时间,降低传输成本。
要求:在发送端通过一个编码系统对待传数据预先编码;在接收端将传入的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼的编/译码系统。
2、基本要求
系统应具有以下功能。
①I:初始化.从终端读入字符集大小n及n个字符和n个权值,建立哈夫曼树,井将它存
于文件HuffmanTree中。
②C:编码。利用已建立好的哈夫曼树(如不在内存,则从文件HuffmanTree中读入)。对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中。
③D:解码。利用已建立好的哈夫曼树将文件codefile中的代码进行译码,结果存入testfile中。
④P:打印代码文件。将文件codefile以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件codeprint中。
⑤T:打印哈夫曼树。将已在内存中的哈夫曼树直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中。
3、算法分析
本题例主要用到3个算法如下。
①哈夫曼编码。在初始化(I)的过程中,要用输入的字符和权值建立哈夫曼树并求得哈夫曼编码。先将输入的字符和权值放到一个结构体数据中,建立哈夫曼树,将计算所得的哈夫曼编码存储到另一个结构体数组中。
②串的匹配。在解码(D)的过程中,要对已经编码过的代码进行译码,可利用循环,将代码中与哈夫曼编码长度相同的串与这个哈夫曼编码进行比较,如果相等就回显并存入文件。
③二叉树的遍历。在打印哈夫曼树(T)的过程中,因为哈夫曼树也是二叉树,所以就要利用二叉树的前序遍历将哈夫曼树输出。
解题一:

#include <stdio.h>
#include <string.h>
#define OK 1
#define ERROR 0
#define MAXSIZE 256
FILE* fpWrite;

typedef struct BOOK {
	int bookid;
	char bname[20];
	char press[20];
	int state;
}BOOK;
typedef struct BOOKARR {
	BOOK *book;
	int length;
};
typedef struct Person {
	char name[20];
	char sex[5];
	int id;
}Person;
typedef struct Personarr {
	Person *per;
	int length;
};
void storage(BOOKARR barr) {
	fpWrite = fopen("tushu.txt", "w");
	fprintf(fpWrite, "图书id\t图书名字\t出版社\t图书状态\n");
	for (int i = 0; i < barr.length; i++) {
		fprintf(fpWrite, "%d\t%s\t%s\t", barr.book[i].bookid, barr.book[i].bname, barr.book[i].press);
		if (barr.book[i].state == 0) {
			fprintf(fpWrite, "未借出\n");
		}
		else {
			fprintf(fpWrite,"已借出\n");
		}
	}
	fclose(fpWrite);
}
int Createbook(BOOKARR &barr) {
	barr.book = new BOOK[MAXSIZE];
	barr.length = 0;
	printf("图书管理初始化成功\n");
	return OK;
}
int insert(BOOKARR &barr,int n,BOOK book) {
	int i;
	if (n<1 || n > barr.length + 1) {
		printf("插入位置有误插入失败\n");
		return ERROR;
	}
	if (barr.length >= MAXSIZE) {
		printf("数组已满插入失败\n");
		return ERROR;
	}
	for (i = barr.length - 1; i >= n - 1; i--) {
		barr.book[i + 1] = barr.book[i];
	}
	barr.book[n - 1] = book;
	barr.length++;
	printf("插入成功\n");
	storage(barr);
	return OK;
}
int getinfo(BOOKARR barr,int n) {
	if (barr.length == 0) {
		printf("没有数据\n");
		return OK;
	}
	printf("图书id\t图书名字\t出版社\t图书状态\n");
	for (int i = 0; i < barr.length; i++) {
		if (n == barr.book[i].bookid) {
			printf("%d\t%s\t\t%s\t",barr.book[i].bookid,barr.book[i].bname,barr.book[i].press,barr);
			if (barr.book[i].state == 0) {
				printf("未借出\n");
			}
			else {
				printf("已借出\n");
			}
			return OK;
		}
		else {
			printf("没有查到相应数据\n");
		}
	}
	return OK;
}
int del(BOOKARR &barr,int n) {
	if (barr.length == 0) {
		printf("没有数据删除失败\n");
		return ERROR;
	}
	for (int i = 0; i < barr.length; i++) {
		if (n == barr.book[i].bookid && barr.book[i].state == 0) {
			for (int j = i; j < barr.length; j++) {
				barr.book[j] = barr.book[j + 1];
			}
			barr.length--;
			printf("删除成功\n");
			storage(barr);
			return OK;
		}
	}
	
	printf("没有找到对应数据或者图书被借出删除失败\n");
	return OK;
}
int show(BOOKARR barr) {
	if (barr.length < 1) {
		printf("没有数据\n");
		return ERROR;
	}
	printf("位置\t图书id\t图书名字\t出版社\t图书状态\n");
	for (int i = 0; i < barr.length; i++) {
		printf("%d\t%d\t%s\t\t%s\t",i + 1, barr.book[i].bookid, barr.book[i].bname, barr.book[i].press);
		if (barr.book[i].state == 0) {
			printf("未借出\n");
		}
		else {
			printf("已借出\n");
		}
	}
	return OK;
}
int initial(Personarr &parr) {
	parr.per = new Person[MAXSIZE];
	parr.length = 0;
	printf("读者初始化成功\n");
	return OK;
}
int regist(Personarr &parr,Person per) {
	if (parr.length >= MAXSIZE) {
		printf("数组已满注册失败\n");
		return ERROR;
	}
	parr.per[parr.length++] = per;
	return OK;
}
int check(Personarr parr,int reiid) {
	for (int i = 0; i < parr.length; i++) {
		if (reiid == parr.per[i].id) {
			printf("欢迎借书\n");
			return OK;
		}
	}
	printf("你不是读者,不能借书\n");
	return ERROR;
}
int borrow(BOOKARR &barr,int id) {
	
	for (int i = 0; i < barr.length; i++) {
		if (id == barr.book[i].bookid) {
			if (barr.book[i].state == 0) {
				barr.book[i].state = 1;
				printf("借书成功\n");
				storage(barr);
				return OK;
			}
			else {
				printf("该图书已被借出\n");
				return OK;
			}
		}
	}
	printf("该图书不存在\n");
	return ERROR;
}
int back(BOOKARR &barr,int id) {
	for (int i = 0; i < barr.length; i++) {
		if (id == barr.book[i].bookid) {
			barr.book[i].state = 0;
			storage(barr);
			printf("还书成功\n");
			return OK;
		}
	}
	printf("该图书不在库中,还书错误\n");
	return ERROR;
}
void showre(Personarr parr) {
	printf("读者编号\t读者姓名\t读者性别\t借书证号\n");
	for (int i = 0; i < parr.length; i++) {
		printf("%d\t\t%s\t%s\t%d\n",i + 1,parr.per[i].name,parr.per[i].sex,parr.per[i].id);
	}
}
void meun() {
	printf("图书管理系统\n");
	printf("1-插入图书数据\n");
	printf("2-删除图书数据\n");
	printf("3-查询指定图书数据\n");
	printf("4-显示所有图书数据\n");
	printf("5-退出\n");
	printf("请选择-");
}
void meun1() {
	printf("1.图书管理系统\n");
	printf("2.读者管理系统\n");
	printf("请选择-\n");
}
void menu2() {
	printf("读者管理系统\n");
	printf("1-读者注册\n");
	printf("2-借书\n");
	printf("3-还书\n");
	printf("4-显示所有注册读者\n");
	printf("5-退出\n");
	printf("请选择:");
}
void main() {
	int k;//用来接受check()的返回值
	int reiid;//用来接受借书证号
	int id;//用来接受图书id
	int n;//用来接受图书插入的位置
	int pos;//用来接受功能选择
	Personarr parr;
	Person per;
	BOOK book;
	BOOKARR barr;
	Createbook(barr);
	initial(parr);
	bool flag = true;
	
	while (flag) {
		meun1();
		scanf("%d", &n);
		if (n == 1) {
			bool flag1 = true;
			while (flag1) {
				meun();
				scanf("%d", &pos);
				getchar();
				switch (pos) {
				case 1:
					printf("请输入要插入的位置:");
					scanf("%d", &n);
					printf("\n请输入要插入的图书id:");
					scanf("%d", &book.bookid);
					printf("\n请输入要插入的图书名字:");
					scanf("%s", book.bname);
					printf("\n请输入要插入的图书出版社:");
					scanf("%s", book.press);
					//printf("\n请输入要插入的图书状态(0表示未借出,1表示已借出):");
					//scanf("%d", &book.state);
					book.state = 0;
					getchar();
					insert(barr, n, book);
					break;
				case 2:
					printf("\n请输入要删除的图书id:");
					scanf("%d", &id);
					del(barr, id);
					break;
				case 3:
					printf("\n请输入要查找的图书id:");
					scanf("%d", &id);
					getinfo(barr, id);
					break;
				case 4:
					show(barr);
					break;
				case 5:
					flag1 = false;
				}
			}
		}
		else {
			bool flag2 = true;
			while (flag2) {
				menu2();
				scanf("%d", &pos);
				switch (pos) {
				case 1:
					printf("请输入注册读者的姓名");
					scanf("%s", per.name);
					printf("请输入注册读者的性别");
					scanf("%s", per.sex);
					printf("请输入注册读者的借书id");
					scanf("%d", &per.id);
					regist(parr, per);
					break;
				case 2:
					printf("请输入你的借书id");
					scanf("%d", &reiid);
					 k = check(parr, reiid);
					if (k == 1) {
						printf("请输入你要借书的图书id");
						scanf("%d", &id);
						borrow(barr, id);
					}
					break;
				case 3:
					printf("请输入所还图书id");
					scanf("%d",&id);
					back(barr, id);
					break;
				case 4:
					showre(parr);
					break;
				case 5:
					flag2 = false;
					break;
				}
			}
		}
	}
}

运行截图

 

 

解题二:

#include <stdio.h>
#include <string.h>
#define MAXSIZE 999
FILE* fpWirte;
FILE* fpread;
FILE* tobetrans;
typedef struct Hafumantree {
	char e;
	int weigth;
	int parent;
	int lchild;
	int rchild;
}Hafumantree,*Hafutree;
typedef struct Hafumancode{
	char *ch;
}Hafumancode, *hacode;
void select(Hafutree ha,int &s1,int &s2,int n) {
	int min = MAXSIZE;
	for (int i = 1; i <= n; i++) {
		if (ha[i].weigth < min && ha[i].parent == 0) {
			min = ha[i].weigth;
			s1 = i;
		}
	}
	min = MAXSIZE;
	for (int i = 1; i <= n; i++) {
		if (i != s1) {
			if (ha[i].weigth < min && ha[i].parent == 0) {
				min = ha[i].weigth;
				s2 = i;;
			}
		}
	}
}
void Create(Hafutree& ha, int n) {
	int s1, s2;
	if (n <= 1) {
		return;
	}
	int m = 2 * n - 1;
	ha = new Hafumantree[m + 1];
	for (int i = 1; i <= m; i++) {
		ha[i].lchild = 0;
		ha[i].rchild = 0;
		ha[i].parent = 0;
		ha[i].weigth = 0;
	}
	printf("请输入各个叶子结点的权值:");
	for (int i = 1; i <= n; i++) {
		scanf("%d",&ha[i].weigth);
	}
	getchar();
	printf("请输入各个叶子结点的字符");
	for (int i = 1; i <= n; i++) {
		scanf("%c",&ha[i].e);
	}
	for (int i = n + 1; i <= m; i++) {
		select(ha, s1, s2, i - 1);
		ha[s1].parent = i;
		ha[s2].parent = i;
		ha[i].lchild = s1;
		ha[i].rchild = s2;
		ha[i].weigth = ha[s1].weigth + ha[s2].weigth;
	}
}
void readtxttree(Hafutree &ha,int &n) {
	
	char c;
	fpread = fopen("HuffmanTree.txt", "r");
	fscanf(fpread, "%d%c", &n, &c);
	int m = 2 * n - 1;

	ha = new Hafumantree[m + 1];
	for (int i = 1; i <= m; i++) {
		if (i <= n) {
			fscanf(fpread, "%c%d%d%d%d%c", &ha[i].e,&ha[i].lchild,&ha[i].rchild,&ha[i].parent,&ha[i].weigth,&c);
		}
		else {
			fscanf(fpread, "%d%d%d%d%c",&ha[i].lchild,&ha[i].rchild, &ha[i].parent,&ha[i].weigth, &c);
		}
	}
	fclose(fpread);
}
void show(Hafutree ha,int n) {
	fpWirte = fopen("HuffmanTree.txt", "w");
	fprintf(fpWirte, "%d\n", n);
	printf("位置\t字符\t左孩子\t右孩子\t父亲\t权值\n");
	for (int i = 1; i <= 2 * n - 1; i++) {
		if (i <= n){
			printf("%d\t%c\t%d\t%d\t%d\t%d\n", i, ha[i].e, ha[i].lchild, ha[i].rchild, ha[i].parent, ha[i].weigth);
			
			fprintf(fpWirte,"%c\t%d\t%d\t%d\t%d\n", ha[i].e, ha[i].lchild, ha[i].rchild, ha[i].parent, ha[i].weigth);
		}
		else {
			printf("%d\t\t%d\t%d\t%d\t%d\n", i, ha[i].lchild, ha[i].rchild, ha[i].parent, ha[i].weigth);
			fprintf(fpWirte, "\t%d\t%d\t%d\t%d\n", ha[i].lchild, ha[i].rchild, ha[i].parent, ha[i].weigth);
		}
	}
	fclose(fpWirte);
}
void createhafumancode(hacode &HC,Hafutree ha,int n) {
	HC = new Hafumancode[n + 1];
	char* cd = new char[n];
	int start ;
	cd[n - 1] = '\0';
	for (int i = 1; i <= n; i++) {
		start = n - 1;
		int c = i;
		int f = ha[i].parent;
		while (f != 0) {
			start--;
			if (ha[f].lchild == c) {
				cd[start] = '0';
			}
			else {
				cd[start] = '1';
			}
			c = f;
			f = ha[f].parent;
		}
		HC[i].ch = new char[n - start];
		strcpy(HC[i].ch,&cd[start]);
	}
	delete cd;
}
void showtreecode(hacode HC,int n) {
	for (int i = 1; i <= n; i++) {
		printf("%s\n", HC[i].ch);
	}
}
void testcode(Hafutree ha,hacode HC,int n,char **&codefile) {
	int u = 0;
	codefile = new char* [n];
	char ch;
	printf("请输入需要编码的字符串以#号结束\n");
	tobetrans = fopen("tobetrans.txt", "w");
	getchar();
	scanf("%c", &ch);
	while (ch != '#') {
		int j = 1;
		while (ch != ha[j].e && j <= n) {
			j++;
		}
		if (j <= n) {
			codefile[u++] = HC[j].ch;
		}
		fprintf(tobetrans, "%c", ch);
		scanf("%c", &ch);
	}
	fclose(tobetrans);
	codefile[u] = NULL;
}
void readtobetrans(Hafutree ha, hacode HC, int n, char**& codefile) {
	int i = 0;
	int u = 0;
	
	codefile = new char* [n];
	char *ch = new char[256];
	tobetrans = fopen("tobetrans.txt", "r");
	fscanf(tobetrans,"%s",ch);
	while (ch[i] != '\0') {
		int j = 1;
		while (ch[i] != ha[j].e && j <= n) {
			j++;
		}
		if (j <= n) {
			codefile[u++] = HC[j].ch;
		}
		i++;
	}
	fclose(tobetrans);
	codefile[u] = NULL;
}
void showtestcode(char **codefile) {
	int i = 0;
	while (codefile[i] != NULL) {
		printf("%s", codefile[i++]);
	}
}
void Decode(Hafutree ha,int n) {
	Hafutree kl = ha;
		char k[20];
		int arr = 0;
		int j = 2 * n - 1;
		printf("请输入编码#号结束");
		char ch;
		scanf("%c",&ch);
		while (ch != '#') {
			if (ch == '0') {
				j = kl[j].lchild;
			}
			else if (ch == '1') {
				j = kl[j].rchild;
			}
			if (kl[j].lchild == 0 || kl[j].rchild == 0) {
				k[arr++] = kl[j].e;
				j = 2 * n - 1;
			}
			scanf("%c",&ch);
		}
		k[arr] = '\0';
		printf("%s", k);
}
void readDecode(Hafutree ha,int n) {
	int u = 0;
	char k[256];
	int j = 2 * n - 1;
	int i = 0;
	FILE *readtxtcode = fopen("codefiletxt.txt","r");
	char* ch = new char[256];
	fscanf(readtxtcode,"%s",ch);
	while (ch[i] != '\0') {
		if (ch[i] == '0') {
			j = ha[j].lchild;
		}
		else if(ch[i] =='1') {
			j = ha[j].rchild;
		}
		if (ha[j].lchild == 0 || ha[j].rchild == 0) {
			k[u++] = ha[j].e;
			j = 2 * n - 1;
		}
		i++;
	}
	k[u] = '\0';
	printf("%s", k);
}
void menu() {
	printf("哈夫曼编码译码系统");
	printf("1-手动创建哈夫曼树");
	printf("2-从以知文件中读取哈夫曼树");
	printf("3-手动输入需要编码的字符串");
	printf("4-从以知文件中读入需要编码的字符串");
}
int main() {
	int pos;
	char c;
	char** codefile =NULL;
	char ch;
	hacode HC;
	Hafutree ha = NULL;
	int n;
	//printf("请输入叶子结点个数\n");
	//scanf("%d",&n);
	//Create(ha, n);
	//readtxttree(ha,n);
	while (true) {
		printf("\n哈夫曼编码译码系统\n");
		printf("1-手动创建哈夫曼树\n");
		printf("2-从以知文件中读取哈夫曼树\n");
		printf("请选择:");
		scanf("%d",&pos);
		switch (pos) {
		case 1:
			printf("请输入叶子结点个数\n");
			scanf("%d",&n);
			Create(ha, n);
			break;
		case 2:
			readtxttree(ha, n);
			break;
		}
		show(ha, n);
		createhafumancode(HC, ha, n);
		showtreecode(HC, n);
		printf("1-手动输入需要编码的字符串\n");
		printf("2-从以知文件中读入需要编码的字符串\n");
		printf("请选择:");
		scanf("%d",&pos);
		switch (pos) {
		case 1:
			testcode(ha, HC, n, codefile);
			break;
		case 2:
			readtobetrans(ha, HC, n, codefile);
			break;
		}
		showtestcode(codefile);
		FILE* codefiletxt = fopen("codefiletxt.txt","w");
		int q = 0;
		while (codefile[q] != NULL) {
			fprintf(codefiletxt,"%s",codefile[q++]);
		}
		fclose(codefiletxt);
		printf("\n1-手动输入编码进行解译\n");
		printf("2-从文件中读入编码进行解译\n");
		printf("请选择:");
		scanf("%d",&pos);
		switch (pos) {
		case 1:
			Decode(ha,n);
			break;
		case 2:
			readDecode(ha, n);
			break;
		}
	}
}

运行截图

 

 

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

223文阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值