《算法与数据结构》课程设计报告
数据结构课程设计是在学完数据结构课程之后的实践教学环节。本实践教学是培养学生数据抽象能力,进行复杂程序设计的训练过程。要求学生能对所涉及问题选择合适的数据结构、存储结构及算法,并编写出结构清楚且正确易读的程序,提高程序设计基本技能和技巧。
一.设计目的
1.提高数据抽象能力。根据实际问题,能利用数据结构理论课中所学到的知识选择合适的逻辑结构以及存储结构,并设计出有效解决问题的算法。
2.提高程序设计和调试能力。学生通过上机练习,验证自己设计的算法的正确性。学会有效利用基本调试方法,迅速找出程序代码中的错误并且修改。
3.初步了解开发过程中问题分析、整体设计、程序编码、测试等基本方法和技能。
二.设计方案
设计方案如下:
1. 单链表的基本操作及应用
首先用InitList_L()函数初始化线性表,构造一个空表,再使用CreateList_L( )函数创建一个想要的线性表。剩余的基本操作ListInsert_L( )插入,ListDelete_L( )删除,LocateElem_L( )查找,即可相应完成。
2. 栈的基本操作及应用
同线性表,首先用InitStack(STACK&S)初始化,构造一个空栈,再使用Push(STACK&S, ElemType e)向栈内压入元素,出栈则使用Pop(STACK &S, ElemType &e),取出栈内元素,用函数GetTop(STACK S, ElemType &e)获取栈顶元素。
3. 数组的基本操作及应用
利用函数CreateSMatrix(TSMatrix&M)创建一个稀疏矩阵,则需要一个数组Triple data[MAXSIZE+1]记录非零元素的行序、列序和数值。再将三元数组中元素的行序和列序和矩阵的行序和列序作比较,不相等的矩阵元素则为零,相等则为稀疏因子的值。再利用函数PrintSMatrix(TSMatrix M)输出稀疏矩阵。
4. 二叉树的基本操作及应用
首先使用函数CreateBiTree(BiTree&T)递归创建二叉树的左子树和右子树,随后利用函数PreOrder(T)、InOrder(T)和PostOrder(T)递归先序、中序和后序遍历二叉树的值,再函数Visit(BiTree T)输出二叉树节点的值。计算二叉树的深度,比较二叉树节点左子树和右子树的孩子都为空的时候的记录的值大,即为树的深度。计算二叉树叶子节点的个数,当节点的左右孩子都为空的时候,节点为叶子,则可以使用计数,当节点左右孩子为空,计数加1,知道计算所有的树,总和为叶子的个数。求赫夫曼编码,各字符的编码长度不等,所以按实际长度动态分配空间,从叶子到根逆向处理求得各个叶子节点所表示的字符的赫夫曼编码。
5. 图的基本操作及应用
利用邻接矩阵表示法构造图,网则要记录权值,构造邻接矩阵arcs存储图。访问初始点Vi,并标志其已被访问。此时定义一指向边结点的指针p,并建立一个while()循环,以指针所指对象不为空为控制条件,当Vi的邻接点未被访问时,递归调用深度优先遍历函数访问之。然后将p指针指向下一个边结点。求有向图的拓扑排序,在头结点中增加一个存放顶点入度的数组(indegree)。入度为零的顶点即为没有前驱的顶点,删除顶点及以它为尾的弧的操作,即可换为弧头顶点的入度减1来实现。
三.设计流程图
四.实现代码(部分)
第一步:设计主菜单。
void main(){
int n;
do{
ShowMainMenu();
printf("请选择:");
scanf("%d",&n);
switch(n){
case 1:LinkList();break;
case 2:Stack();break;
case 3:Array();break;
case 4:BiTree();break;
case 5:Graph();break;
case 6:break;
default:printf("ERROR!");break;
}
}while(n!=6);
}
void ShowMainMenu() {
printf("\n");
printf("*******************算法与数据结构******************\n");
printf("* 1 单链表的基本操作及应用 *\n");
printf("* 2 栈的基本操作及应用 *\n");
printf("* 3 数组的基本操作及应用 *\n");
printf("* 4 树的基本操作及应用 *\n");
printf("* 5 图的基本操作及应用 *\n");
printf("* 6 退出 *\n");
printf("***************************************************\n");
}
第二步:添加功能函数。
在程序合适的位置添加相应的函数实现各功能模块。
1、在语句printf("* 1 单链表的基本操作及应用 *\n”)添加实现单链表操作的函数。
StatusCreateList_L(LinkList&L, int n)//创建线性表
{
InitList_L(L);
int i;
cout << "输入要插入的链表个数:";
cin >> n;
ElemTypee;
for (i = 1; i <= n; i++)
{
cin >> e;
ListInsert_L(L,i, e);
}
return OK;
}
2、在语句printf("* 2 栈的基本操作及应用 *\n");添加实现栈基本操作的函数:
void Push(STACK&S, ElemType e) //压栈
{
SLinkList p;
p =(SLinkList)malloc(sizeof(LNode));
if (!p) exit(OVERFLOW);
p->data = e;
p->next = S.top;
S.top = p;
}
3、稀疏矩阵
StatusCreateSMatrix(TSMatrix&M)
{
cout << "请输入稀疏矩阵的行数、列数和非零元个数:" <<endl;
cin >> M.mu;
cin >> M.nu;
cin >> M.tu;
for (int i = 1; i <= M.tu; i++)
{
cout << "请按行序输入非零元素的值、行标和列标:" <<endl;
cin >> M.data[i].e;
cin >> M.data[i].i;
cin >> M.data[i].j;
}
return OK;
}
4、二叉树
intCreateBiTree(BiTree &T) {
char data;
//按次序输入二叉树中结点的值(一个字符),‘#’表示空树
cin >> data;
if (data == '#') {
T = NULL;
}
else {
if (!(T =(BiTNode*)malloc(sizeof(BiTNode))))
exit(OVERFLOW);
//生成根结点
T->data = data;
//构造左子树
CreateBiTree(T->lchild);
//构造右子树
CreateBiTree(T->rchild);
}
return 0;
}
5、图的基本操作
Status CreateUDG(ALGraph&G) //构造无向图
{
G.kind =1;
cout<< "请输入无向图的顶点数和边数:" << endl;
cin>> G.vernum >> G.arcnum;
int i, e;
cout<< "输入每个顶点的值:" << endl;
for (i =1; i <= G.vernum; i++)
{
cin>> e;
G.vertices[i- 1].data = e;
G.vertices[i- 1].firstarc = 0;
}
int v1,v2;
for (i =0; i < G.arcnum; i++)
{
cout<< "请输入第" << i << "条弧所关联的两个点的位置:" << endl;
cin>> v1 >> v2;
ArcNode*q= (ArcNode*)malloc(sizeof(ArcNode));
q->adjvex= v2 - 1;
q->nextarc= G.vertices[v1 - 1].firstarc;
G.vertices[v1- 1].firstarc = q;
q =(ArcNode*)malloc(sizeof(ArcNode));
q->adjvex= v1 - 1;
q->nextarc= G.vertices[v2 - 1].firstarc;
G.vertices[v2- 1].firstarc = q;
}
return OK;
}
五.实现结果
展示二叉树部分运行结果:
1、创建二叉树ABC##DE#G##F###
2、 计算树的深度
3、遍历二叉树
4、赫夫曼编码
六.心得总结
指导老师意见:
成绩: 教师签名:
年 月 日