中南大学数据结构实验报告(五)

合集下载

中南大学数据结构演示系统课程设计实验报告

中南大学数据结构演示系统课程设计实验报告

中南大学数据结构演示系统课程设计实验报告一、需求分析1、课程设计题目数据结构演示系统1(1)、顺序表的插入、删除和合并等基本操作(2)、利用插入运算建立链表;实现链表的查找、删除、计数、输出等功能以及有序链表的合并。

(3)、串的模式匹配(包括求next和nextval的值)。

2程序模块的功能要求(1)输入的形式和输入值的范围(2)顺序表和链表的输入形式是整形,输入值的范围是-32768~~32767。

串的输入形式是字符型(3)输出的形式顺序表和链表的输出形式是整形;串的输出形式是字符型。

(4)程序所能达到的功能;实现顺序表的创建、插入、删除和合并实现链表的创建、查找、删除、计数、输出和有序链表的合并实现串的模式匹配(包括求next和nextval的值)(5)测试数据:包括正确的输入及其输出结果和含有错误的输入及其输出结果顺序表的输入:12/26/65/65/216/898/989/2156链表输入:12/32/35/56/65/654/985二、概要设计1、定义定义顺序表的结构体typedef struct lnode{int data;struct lnode *next;}linklist;定义链表的的结构体typedef struct{int len;linklist *point;}indexlink;typedef struct{int data[MAXSIZE][MAXSIZE1+1];int len;定义串的结构体}sqlist;typedef struct{char string[MAXSIZE1];int len;}sstring;int next[MAXSIZE1];int nextval[MAXSIZE1];2 流程图(1)主界面(2)顺序表主流程图(3)顺序表插入流程图(4)链表主流程图)链表删除元素流程图(5(6)模式匹配主流程图(7)KMP求next【】流程图3各程序模块之间的层次关系(1)第一层为主界面函数,第二层为顺序表界面函数、链表界面函数、模式匹配界面函数第三层为顺序表子函数、链表子函数、模式匹配子函数(2)主界面函数调用的函数有sqlistfuc()、linklistfuc()、indexfuc()顺序表界面调用的函数有creatsq()、listinsert()、listdelete()、mergelist()链表界面调用的函数有creat()、insert()、delete()、search()、num()、linktraverse()、mergelink()、模式匹配界面调用的函数有creatstring()、KMP()三、详细设计见附录四、调试分析1、调试过程中遇到的问题是如何解决的以及对设计与实现的讨论和分析(1)一开始在在调试程序时遇到了内存错误,最终通过网上查资料找到了出错的原因:在建立对头指针和队尾指针时没有对指针进行初始化,即没有为指针动态分配空间。

中南大学数据库实验报告

中南大学数据库实验报告

中南大学数据库实验实验题目班级姓名学号一、实验内容实验一:创建表、更新表和实施数据完整性1.运行给定的SQL Script,建立数据库GlobalToyz。

2.创建所有表的关系图。

3.列出所有表中出现的约束(包括Primary key, Foreign key, check constraint, default, unique)4.对Recipient表和Country表中的cCountryId属性定义一个用户自定义数据类型,并将该属性的类型定义为这个自定义数据类型。

5.把价格在$20以上的所有玩具的材料拷贝到称为PremiumToys 的新表中。

6.对表Toys实施下面数据完整性规则:(1)玩具的现有数量应在0到200之间;(2)玩具适宜的最低年龄缺省为1。

7.不修改已创建的Toys表,利用规则实现以下数据完整性:(1)玩具的价格应大于0;(2)玩具的重量应缺省为1。

8.给id为‘000001’玩具的价格增加$1。

实验二:查询数据库1.显示属于California和Illinoi州的顾客的名、姓和emailID。

2.显示定单号码、商店ID,定单的总价值,并以定单的总价值的升序排列。

3.显示在orderDetail表中vMessage为空值的行。

4.显示玩具名字中有“Racer”字样的所有玩具的材料。

5.根据2000年的玩具销售总数,显示“Pick of the Month”玩具的前五名玩具的ID。

6.根据OrderDetail表,显示玩具总价值大于¥50的定单的号码和玩具总价值。

7.显示一份包含所有装运信息的报表,包括:Order Number,Shipment Date, Actual Delivery Date, Days in Transit. (提示:Days in Transit = Actual Delivery Date –Shipment Date)8.显示所有玩具的名称、商标和种类(Toy Name, Brand, Category)。

数据结构实验报告_实验报告_

数据结构实验报告_实验报告_

数据结构实验报告想必学计算机专业的同学都知道数据结构是一门比较重要的课程,那么,下面是小编给大家整理收集的数据结构实验报告,供大家阅读参考。

数据结构实验报告1一、实验目的及要求1)掌握栈和队列这两种特殊的线性表,熟悉它们的特性,在实际问题背景下灵活运用它们。

本实验训练的要点是“栈”和“队列”的观点;二、实验内容1) 利用栈,实现数制转换。

2) 利用栈,实现任一个表达式中的语法检查(选做)。

3) 编程实现队列在两种存储结构中的基本操作(队列的初始化、判队列空、入队列、出队列);三、实验流程、操作步骤或核心代码、算法片段顺序栈:Status InitStack(SqStack &S){S.base=(ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemTyp e));if(!S.base)return ERROR;S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}Status DestoryStack(SqStack &S){free(S.base);return OK;}Status ClearStack(SqStack &S){S.top=S.base;return OK;}Status StackEmpty(SqStack S){if(S.base==S.top)return OK;return ERROR;}int StackLength(SqStack S){return S.top-S.base;}Status GetTop(SqStack S,ElemType &e){if(S.top-S.base>=S.stacksize){S.base=(ElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemTyp e));if(!S.base) return ERROR;S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return OK;Status Push(SqStack &S,ElemType e){if(S.top-S.base>=S.stacksize){S.base=(ElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemTyp e));if(!S.base)return ERROR;S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return OK;}Status Pop(SqStack &S,ElemType &e){if(S.top==S.base)return ERROR;e=*--S.top;return OK;}Status StackTraverse(SqStack S){ElemType *p;p=(ElemType *)malloc(sizeof(ElemType));if(!p) return ERROR;p=S.top;while(p!=S.base)//S.top上面一个...p--;printf("%d ",*p);}return OK;}Status Compare(SqStack &S){int flag,TURE=OK,FALSE=ERROR; ElemType e,x;InitStack(S);flag=OK;printf("请输入要进栈或出栈的元素:"); while((x= getchar)!='#'&&flag) {switch (x){case '(':case '[':case '{':if(Push(S,x)==OK)printf("括号匹配成功!\n\n"); break;case ')':if(Pop(S,e)==ERROR || e!='('){printf("没有满足条件\n");flag=FALSE;}break;case ']':if ( Pop(S,e)==ERROR || e!='[')flag=FALSE;break;case '}':if ( Pop(S,e)==ERROR || e!='{')flag=FALSE;break;}}if (flag && x=='#' && StackEmpty(S)) return OK;elsereturn ERROR;}链队列:Status InitQueue(LinkQueue &Q) {Q.front =Q.rear=(QueuePtr)malloc(sizeof(QNode));if (!Q.front) return ERROR;Q.front->next = NULL;return OK;}Status DestoryQueue(LinkQueue &Q) {while(Q.front){Q.rear=Q.front->next;free(Q.front);Q.front=Q.rear;}return OK;}Status QueueEmpty(LinkQueue &Q){if(Q.front->next==NULL)return OK;return ERROR;}Status QueueLength(LinkQueue Q){int i=0;QueuePtr p,q;p=Q.front;while(p->next){i++;p=Q.front;q=p->next;p=q;}return i;}Status GetHead(LinkQueue Q,ElemType &e) {QueuePtr p;p=Q.front->next;if(!p)return ERROR;e=p->data;return e;}Status ClearQueue(LinkQueue &Q){QueuePtr p;while(Q.front->next ){p=Q.front->next;free(Q.front);Q.front=p;}Q.front->next=NULL;Q.rear->next=NULL;return OK;}Status EnQueue(LinkQueue &Q,ElemType e) {QueuePtr p;p=(QueuePtr)malloc(sizeof (QNode));if(!p)return ERROR;p->data=e;p->next=NULL;Q.rear->next = p;Q.rear=p; //p->next 为空return OK;}Status DeQueue(LinkQueue &Q,ElemType &e) {QueuePtr p;if (Q.front == Q.rear)return ERROR;p = Q.front->next;e = p->data;Q.front->next = p->next;if (Q.rear == p)Q.rear = Q.front; //只有一个元素时(不存在指向尾指针) free (p);return OK;}Status QueueTraverse(LinkQueue Q){QueuePtr p,q;if( QueueEmpty(Q)==OK){printf("这是一个空队列!\n");return ERROR;}p=Q.front->next;while(p){q=p;printf("%d<-\n",q->data);q=p->next;p=q;}return OK;}循环队列:Status InitQueue(SqQueue &Q){Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType)); if(!Q.base)exit(OWERFLOW);Q.front=Q.rear=0;return OK;}Status EnQueue(SqQueue &Q,QElemType e){if((Q.rear+1)%MAXQSIZE==Q.front)return ERROR;Q.base[Q.rear]=e;Q.rear=(Q.rear+1)%MAXQSIZE;return OK;}Status DeQueue(SqQueue &Q,QElemType &e){if(Q.front==Q.rear)return ERROR;e=Q.base[Q.front];Q.front=(Q.front+1)%MAXQSIZE;return OK;}int QueueLength(SqQueue Q){return(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;}Status DestoryQueue(SqQueue &Q){free(Q.base);return OK;}Status QueueEmpty(SqQueue Q) //判空{if(Q.front ==Q.rear)return OK;return ERROR;}Status QueueTraverse(SqQueue Q){if(Q.front==Q.rear)printf("这是一个空队列!");while(Q.front%MAXQSIZE!=Q.rear){printf("%d<- ",Q.base[Q.front]);Q.front++;}return OK;}数据结构实验报告2一.实验内容:实现哈夫曼编码的生成算法。

数据结构实验报告实验5

数据结构实验报告实验5

数据结构实验报告实验5一、实验目的本次实验的主要目的是深入理解和掌握常见的数据结构,如链表、栈、队列、树和图等,并通过实际编程实现,提高对数据结构的操作和应用能力。

同时,培养解决实际问题的思维和编程能力,提高代码的可读性、可维护性和效率。

二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。

三、实验内容1、链表的基本操作创建链表插入节点删除节点遍历链表2、栈的实现与应用用数组实现栈用链表实现栈栈的应用:括号匹配3、队列的实现与应用用数组实现队列用链表实现队列队列的应用:排队模拟4、二叉树的遍历前序遍历中序遍历后序遍历5、图的表示与遍历邻接矩阵表示法邻接表表示法深度优先遍历广度优先遍历四、实验步骤1、链表的基本操作创建链表:首先定义一个链表节点结构体,包含数据域和指向下一个节点的指针域。

然后通过动态内存分配创建链表节点,并将节点逐个连接起来,形成链表。

插入节点:根据插入位置的不同,分为在表头插入、在表尾插入和在指定位置插入。

在指定位置插入时,需要先找到插入位置的前一个节点,然后进行节点的连接操作。

删除节点:同样需要根据删除位置的不同进行处理。

删除表头节点时,直接将头指针指向下一个节点;删除表尾节点时,找到倒数第二个节点,将其指针置为空;删除指定位置节点时,找到要删除节点的前一个节点,然后调整指针。

遍历链表:通过从链表头开始,依次访问每个节点,输出节点的数据。

2、栈的实现与应用用数组实现栈:定义一个固定大小的数组作为栈的存储空间,同时用一个变量记录栈顶位置。

入栈操作时,先判断栈是否已满,如果未满则将元素放入栈顶位置,并更新栈顶位置;出栈操作时,先判断栈是否为空,如果不空则取出栈顶元素,并更新栈顶位置。

用链表实现栈:与链表的操作类似,将新元素添加在链表头部作为栈顶。

括号匹配:输入一个包含括号的字符串,使用栈来判断括号是否匹配。

遇到左括号入栈,遇到右括号时与栈顶的左括号进行匹配,如果匹配成功则出栈,否则括号不匹配。

数据结构实验实训报告范文

数据结构实验实训报告范文

一、实验目的1. 理解并掌握数据结构的基本概念和常用算法。

2. 学会使用C语言实现线性表、栈、队列、树和图等基本数据结构。

3. 培养动手实践能力,提高编程水平。

二、实验内容1. 线性表(1)顺序表(2)链表2. 栈(1)顺序栈(2)链栈3. 队列(1)顺序队列(2)链队列4. 树(1)二叉树(2)二叉搜索树5. 图(1)邻接矩阵表示法(2)邻接表表示法三、实验环境1. 操作系统:Windows 102. 编程语言:C语言3. 编译器:Visual Studio 20194. 实验软件:C语言开发环境四、实验步骤1. 线性表(1)顺序表1)定义顺序表结构体2)实现顺序表的初始化、插入、删除、查找等基本操作3)编写测试程序,验证顺序表的基本操作(2)链表1)定义链表结构体2)实现链表的创建、插入、删除、查找等基本操作3)编写测试程序,验证链表的基本操作2. 栈(1)顺序栈1)定义顺序栈结构体2)实现顺序栈的初始化、入栈、出栈、判空等基本操作3)编写测试程序,验证顺序栈的基本操作(2)链栈1)定义链栈结构体2)实现链栈的初始化、入栈、出栈、判空等基本操作3)编写测试程序,验证链栈的基本操作3. 队列(1)顺序队列1)定义顺序队列结构体2)实现顺序队列的初始化、入队、出队、判空等基本操作3)编写测试程序,验证顺序队列的基本操作(2)链队列1)定义链队列结构体2)实现链队列的初始化、入队、出队、判空等基本操作3)编写测试程序,验证链队列的基本操作4. 树(1)二叉树1)定义二叉树结构体2)实现二叉树的创建、遍历、查找等基本操作3)编写测试程序,验证二叉树的基本操作(2)二叉搜索树1)定义二叉搜索树结构体2)实现二叉搜索树的创建、遍历、查找等基本操作3)编写测试程序,验证二叉搜索树的基本操作5. 图(1)邻接矩阵表示法1)定义邻接矩阵结构体2)实现图的创建、添加边、删除边、遍历等基本操作3)编写测试程序,验证邻接矩阵表示法的基本操作(2)邻接表表示法1)定义邻接表结构体2)实现图的创建、添加边、删除边、遍历等基本操作3)编写测试程序,验证邻接表表示法的基本操作五、实验结果与分析1. 线性表(1)顺序表实验结果表明,顺序表的基本操作实现正确,测试程序运行稳定。

数据结构实验报告5(电大)

数据结构实验报告5(电大)

实验报告五查找(学科:数据结构)姓名单位班级学号实验日期成绩评定教师签名批改日期实验名称:实验五查找5.1 折半查找【问题描述】某班学生成绩信息表中,每个学生的记录已按平均成绩由高到低排好序,后来发现某个学生的成绩没有登记到信息表中,使用折半查找法把该同学的记录插入到信息表中,使信息表中的记录仍按平均成绩有序。

【基本信息】(1)建立现有学生信息表,平均成绩已有序。

(2)输入插入学生的记录信息。

(3)用折半查找找到插入位置,并插入记录。

【测试数据】自行设计。

【实验提示】(1)用结构数组存储成绩信息表。

(2)对记录中的平均成绩进行折半查找。

【实验报告内容】设计程序代码如下:#include<stdio.h>#include<string.h>#define N 5struct student{char name[10];float avg;}void insort(struct student s[],int n){int low,hight,mid,k;char y[10];float x;low=1;hight=n;strcpy(y,s[0].name );x=s[0].avg ;while(low<=hight){mid=(low+hight)/2;if(x>s[mid].avg )hight=mid-1;elselow=mid+1;}for(k=0;k<low-1;k++){strcpy(s[k].name,s[k+1].name) ;s[k].avg =s[k+1].avg ;}printf("%d",low);strcpy(s[low-1].name ,y) ;s[low-1].avg =x;}void main(){Struct student a[N]={{"caozh",96},{"cheng",95},{"zhao",93},{"wang",92},{"chen",91}};struct student stu[N];int i;for(i=0;i<N;i++)stu[i+1]=a[i];printf("初始%d 位同学的信息表\n",MAX);printf("排名姓名平均分数\n");for(i=1;i<=N;i++)printf("%d: %6s %3.2f\n",i,stu[i].name,stu[i].avg);printf("\n");printf("\n");printf("请输入学生的姓名:");scanf("%s",stu[0].name );printf("\n");printf("请输入平均成绩:");scanf("%f",&stu[0].avg );printf("\n");insort(stu,N);printf("折半排序后同学的信息表\n",MAX);printf("排名姓名平均分数\n");for(i=0;i<=N;i++){printf("%d: %6s %3.2f\n",i+1,stu[i].name,stu[i].avg);}printf("\n");}程序运行结果如下:5.2 二叉排序树的建立【问题描述】参阅相关资料,阅读建立二叉排序树的程序。

数据结构实训实验报告

数据结构实训实验报告

一、实验背景数据结构是计算机科学中一个重要的基础学科,它研究如何有效地组织和存储数据,并实现对数据的检索、插入、删除等操作。

为了更好地理解数据结构的概念和原理,我们进行了一次数据结构实训实验,通过实际操作来加深对数据结构的认识。

二、实验目的1. 掌握常见数据结构(如线性表、栈、队列、树、图等)的定义、特点及操作方法。

2. 熟练运用数据结构解决实际问题,提高算法设计能力。

3. 培养团队合作精神,提高实验报告撰写能力。

三、实验内容本次实验主要包括以下内容:1. 线性表(1)实现线性表的顺序存储和链式存储。

(2)实现线性表的插入、删除、查找等操作。

2. 栈与队列(1)实现栈的顺序存储和链式存储。

(2)实现栈的入栈、出栈、判断栈空等操作。

(3)实现队列的顺序存储和链式存储。

(4)实现队列的入队、出队、判断队空等操作。

3. 树与图(1)实现二叉树的顺序存储和链式存储。

(2)实现二叉树的遍历、查找、插入、删除等操作。

(3)实现图的邻接矩阵和邻接表存储。

(4)实现图的深度优先遍历和广度优先遍历。

4. 算法设计与应用(1)实现冒泡排序、选择排序、插入排序等基本排序算法。

(2)实现二分查找算法。

(3)设计并实现一个简单的学生成绩管理系统。

四、实验步骤1. 熟悉实验要求,明确实验目的和内容。

2. 编写代码实现实验内容,对每个数据结构进行测试。

3. 对实验结果进行分析,总结实验过程中的问题和经验。

4. 撰写实验报告,包括实验目的、内容、步骤、结果分析等。

五、实验结果与分析1. 线性表(1)顺序存储的线性表实现简单,但插入和删除操作效率较低。

(2)链式存储的线性表插入和删除操作效率较高,但存储空间占用较大。

2. 栈与队列(1)栈和队列的顺序存储和链式存储实现简单,但顺序存储空间利用率较低。

(2)栈和队列的入栈、出队、判断空等操作实现简单,但需要考虑数据结构的边界条件。

3. 树与图(1)二叉树和图的存储结构实现复杂,但能够有效地表示和处理数据。

数据结构实验报告

数据结构实验报告

数据结构实验报告一、实验目的数据结构是计算机科学中重要的基础课程,通过本次实验,旨在深入理解和掌握常见数据结构的基本概念、操作方法以及在实际问题中的应用。

具体目的包括:1、熟练掌握线性表(如顺序表、链表)的基本操作,如插入、删除、查找等。

2、理解栈和队列的特性,并能够实现其基本操作。

3、掌握树(二叉树、二叉搜索树)的遍历算法和基本操作。

4、学会使用图的数据结构,并实现图的遍历和相关算法。

二、实验环境本次实验使用的编程环境为具体编程环境名称,编程语言为具体编程语言名称。

三、实验内容及步骤(一)线性表的实现与操作1、顺序表的实现定义顺序表的数据结构,包括数组和表的长度等。

实现顺序表的初始化、插入、删除和查找操作。

2、链表的实现定义链表的节点结构,包含数据域和指针域。

实现链表的创建、插入、删除和查找操作。

(二)栈和队列的实现1、栈的实现使用数组或链表实现栈的数据结构。

实现栈的入栈、出栈和栈顶元素获取操作。

2、队列的实现采用循环队列的方式实现队列的数据结构。

完成队列的入队、出队和队头队尾元素获取操作。

(三)树的实现与遍历1、二叉树的创建以递归或迭代的方式创建二叉树。

2、二叉树的遍历实现前序遍历、中序遍历和后序遍历算法。

3、二叉搜索树的操作实现二叉搜索树的插入、删除和查找操作。

(四)图的实现与遍历1、图的表示使用邻接矩阵或邻接表来表示图的数据结构。

2、图的遍历实现深度优先遍历和广度优先遍历算法。

四、实验结果与分析(一)线性表1、顺序表插入操作在表尾进行时效率较高,在表头或中间位置插入时需要移动大量元素,时间复杂度较高。

删除操作同理,在表尾删除效率高,在表头或中间删除需要移动元素。

2、链表插入和删除操作只需修改指针,时间复杂度较低,但查找操作需要遍历链表,效率相对较低。

(二)栈和队列1、栈栈的特点是先进后出,适用于函数调用、表达式求值等场景。

入栈和出栈操作的时间复杂度均为 O(1)。

2、队列队列的特点是先进先出,常用于排队、任务调度等场景。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验1.需求分析的任意结点之间的两个数据元素都可以相关。

本实验希望读者理解图的数据结构,掌握图的邻接表存储结构,建立邻接表的算法,以及如何应用图解决具体问题(即原理与应用的结合)等。

1.从键盘输入的数据建立图,并进行深度优先搜索和广度优先搜索(验证性实验)问题描述很多涉及图上操作的算法都是以图的遍历操作为基础的。

试编写一个程序,演示无向图的遍历操作。

在主程序中提供下列菜单:(1)“1”代表图的建立;(2)“2”代表深度优先遍历图;(3)“3”代表广度优先遍历图;(4)“0”代表结束。

基本要求以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。

以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。

测试数据由读者依据软件工程的测试技术自己确定。

注意测试边界数据,如单个结点。

实现提示设图的结点不超过30个,每个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1, 2, …, n)。

通过输入图的所有边输入一个图,每个边为一个数对,可以对边的输入顺序作出某种限制。

注意,生成树的边是有向边,端点顺序不能颠倒。

2.利用最小生成树算法解决通信网的总造价最低问题(设计性实验)问题描述若在n个城市之间建通信网络,只需架设n1条线路即可。

如何以最低的经济代价建设这个通信网是一个网的最小生成树问题。

基本要求以邻接表为存储结构,利用Prim算法或Kruskal算法求网的最小生成树。

测试数据由读者依据软件工程的测试技术自己确定。

注意测试边界数据,如单个结点。

实现提示设通信线路一旦建立,必然是双向的。

因此,构造最小生成树的网一定是无向网。

为简单起见,图的顶点数不超过10,网中边的权值设置成小于100。

4.导游问题(综合性实验)问题描述给出一张某公园的导游图,游客通过终端询问可知:(1) 从某一景点到另一个景点的最短路径;(2) 游客从公园大门进入,选一条最佳路线,使游客可以不重复的游览各景点,最后回到出口。

基本要求(1) 将导游图看作一张带权无向图,顶点表示公园的各个景点,边表示各景点之间的道路,边上的权值表示距离,选择适当的数据结构。

(2) 为游客提供图中任意景点相关信息的查询。

(3) 为游客提供任意两个景点之间最短的简单路径。

(4) 为游客选择最佳游览路径。

测试数据由读者依据软件工程的测试技术自己确定。

注意测试边界数据,如单个结点。

实现提示以邻接表为存储结构,利用Dijkstra算法或Floyd算法求最短路径,利用搜索求最佳路径2.概要设计⏹验证性实验函数:⏹设计性实验函数:⏹综合性实验函数:3.详细设计⏹验证性实验typedef int QElemType;typedef struct QNode{//节点QElemType data;struct QNode *next;//链队列} QNode;typedef struct{QNode *front;//头指针,带空头节点QNode *rear;//尾节点} LinkQueue;int InitQueue(LinkQueue *q){//初始化q->front=q->rear=(QNode *)malloc(sizeof(QNode));//申请空间,front指向头节点(空的)if(q->front==NULL){//若是申请失败printf("malloc fail in InitQueue");return fail;}q->front->next=NULL;//空队的头节点下一个自然为空return ok;}int EnQueue(LinkQueue *q, QElemType e){//插入QNode *p =(QNode *)malloc(sizeof(QNode));//将要插入的节点if(p ==NULL){printf("malloc fail in EnQueue");return fail;}p->data= e;//p的值为ep->next=NULL;//在尾部插入,其下一个为空q->rear->next= p;//接到尾节点的下一个q->rear= p;//p为新的尾节点return ok;}int DeQueue(LinkQueue *q, QElemType *e){//删除if(q->front==q->rear){//空队无法删除printf("underflow\n");return underflow;}QNode *p =q->front->next;//需要删除的节点*e =p->data;//用e带出删掉的值q->front->next=p->next;//将要删除的节点从链中断开if(q->rear= p){//加入原来队中只有一个节点q->rear=q->front;//删完后为空队,头节点与尾节点指到一起}free(p);return ok;}#define empty0#define notempty1int isempty(LinkQueue q){if(q.front==q.rear){return empty;}else{return notempty;}}//图typedef char vertexType;//顶点数据类型typedef enum{DG,DN,UDG,UDN}GraphKind;//图的类型typedef struct arcNode{//边int adjvex;//边上数据,指向其父节点下一个邻接点在顶点数组中的位置struct arcNode *nextarc;//指向下一条边}arcNode;typedef struct vnode{//顶点vertexType vexData;//顶点数据arcNode *firstarc;//指向第一个邻接点的边}vnode;typedef struct{//图vnode* vertices;//顶点数组int vexnum,arcnum;//顶点数目,边的数目GraphKind kind;//图类型}alGraph;void printVertices(alGraph* g){//打印邻接表for(int i=0;i<g->vexnum;i++){//遍历顶点数组printf("%c ",g->vertices[i].vexData);//遍历每个顶点的所有边arcNode* a=(arcNode*)malloc(sizeof(arcNode));a=g->vertices[i].firstarc;while(a!=NULL){printf("%d ",a->adjvex);a=a->nextarc;}printf("\n");}}int locateVex(alGraph* g,char vex){//确定点vex在邻接表中的位置for(int i=0;i<g->vexnum;i++){//遍历比较if(g->vertices[i].vexData==vex){return i;}}printf("vex not exist in locateVex:%c\n",vex);return-1;//没找到返回-1}void CreateGraph(alGraph* g){//先序输入图printf("输入顶点数,边数和图类\n");scanf("%d%d%d",&(g->vexnum),&(g->arcnum),&(g->kind));g->vertices=(vnode*)malloc(g->vexnum*sizeof(vnode));// printf("%d %d %d",g->vexnum,g->arcnum,g->kind);printf("输入顶点\n");for(int i=0;i<g->vexnum;i++){printf("第%d个顶点:\n",i+1);getchar();//清掉回车g->vertices[i].vexData=getchar();// putchar(g->vertices[i].vexData);g->vertices[i].firstarc=NULL;//尾部置空}// printVertices(g);printf("输入边\n");for(int i=0;i<g->arcnum;i++){char sv;char tv;getchar();//清掉回车printf("第%d条边:\n",i+1);scanf("%c%c",&sv,&tv);// printf("%c,%c\n",sv,tv);int s=locateVex(g,sv);int t=locateVex(g,tv);arcNode* pi=(arcNode*)malloc(sizeof(arcNode));pi->adjvex=t;pi->nextarc=g->vertices[s].firstarc;//头插法g->vertices[s].firstarc=pi;if(g->kind==UDG ||g->kind==UDN){//若是无向图或无向网,在边的另一端也要加入边arcNode* pj=(arcNode*)malloc(sizeof(arcNode));pj->adjvex=s;pj->nextarc=g->vertices[t].firstarc;//头插法g->vertices[t].firstarc=pj;}}// printVertices(g);}int*createVisted(int size){//返回一个size大小的置0数组int* visited=(int*)malloc(size*sizeof(int));memset(visited,0,size*sizeof(int));return visited;}void visit(vertexType v){//访问顶点数据printf("%c",v);}int firstAdjVex(alGraph* g,int v){//返回某顶点的第一个邻接点if(g->vertices[v].firstarc==NULL)return-1;//无邻接点时,返回-1return g->vertices[v].firstarc->adjvex;}int nextAdjVex(alGraph* g,int v,int w){//返回某顶点的w之后的一个邻接点,v是当前父节点,w为上一个访问的邻接点arcNode* a=(arcNode*)malloc(sizeof(arcNode));a=g->vertices[v].firstarc;if(a==NULL)return-1;while(a->adjvex!=w){//遍历寻找wif(a==NULL)return-1;//到底返回-1a=a->nextarc;}if(a->nextarc==NULL)return-1;//若是最后一个点,返回-1return a->nextarc->adjvex;//找到就返回下一个邻接点}void DFS(alGraph* g,int v,int* visited){//深度优先遍历visited[v]=1;//已访问,置1visit(g->vertices[v].vexData);for(int w=firstAdjVex(g,v);w!=-1;w=nextAdjVex(g,v,w)){//遍历所有邻接点,深度优先访问它们// printf("#%d#",w);if(visited[w]==0){DFS(g,w,visited);}}}void DFS_unconnected(alGraph* g,int v,int* visited){//非连通图的深度优先遍历for(int i=0;i<g->vexnum;i++){//遍历该图所有点,对未访问的顶点,深度优先遍历// printf("%d",i);if(visited[i]==0){DFS(g,i,visited);}// printf("hhh");}printf("\n");}void BFS(alGraph* g,int v,int* visited,LinkQueue* q){//广度优先遍历visited[v]=1;visit(g->vertices[v].vexData);EnQueue(q,v);//入队要访问的顶点while(isempty(*q)==notempty){//当队列不为空时int u;DeQueue(q,&u);//从队列取出要访问的点,置为ufor(int w=firstAdjVex(g,u);w!=-1;w=nextAdjVex(g,u,w)){//遍历u的所有邻接点if(visited[w]==0){//若未访问就访问visited[w]=1;visit(g->vertices[w].vexData);EnQueue(q,w);//将u的邻接点入队}}}}void BFS_unconnected(alGraph* g,int v,int* visited){//非连通图的广度优先遍历LinkQueue* q=(LinkQueue*)malloc(sizeof(LinkQueue));//设置一个队列,用来存放将要访问的顶点InitQueue(q);for(int v=0;v<g->vexnum;v++){//遍历该图所有点,广度优先访问if(visited[v]==0){BFS(g,v,visited,q);}}}int main(){//测试alGraph* g=(alGraph*)malloc(sizeof(alGraph));if(g==NULL){printf("malloc fail in main for g\n");return-1;}CreateGraph(g);// printVertices(g);//查看邻接表printf("输入遍历起点:\n");getchar();//清掉回车char start=getchar();printf("深度优先遍历结果:\n");// DFS(g,locateVex(g,start),createVisted(g->vexnum));DFS_unconnected(g,locateVex(g,start),createVisted(g->vexnum));printf("广度优先遍历结果:\n");// BFS(g,locateVex(g,start),createVisted(g->vexnum));BFS_unconnected(g,locateVex(g,start),createVisted(g->vexnum));return0;}设计性实验#include<iostream>#include<string>#include<cstring>using namespace std;#define MAX_VERTEX_NUM30//图的最大顶点数目//图typedef char vertexType;//顶点数据类型typedef enum{DG,DN,UDG,UDN}GraphKind;// 定义图的类型 { 有向图, 有向网,无向图, 无向网} typedef struct arcNode{//边int adjvex;//边上数据,指向其父节点下一个邻接点在顶点数组中的位置int weight;//边权重struct arcNode*nextarc;//指向下一条边}arcNode;typedef struct vnode{//顶点vertexType vexData;//顶点数据arcNode *firstarc;//指向第一个邻接点的边}vnode;typedef struct{//图vnode* vertices;//顶点数组int vexnum,arcnum;//顶点数目,边的数目GraphKind kind;//图类型}alGraph;void printVertices(alGraph* g){//打印邻接表for(int i=0;i<g->vexnum;i++){//遍历顶点数组printf("%c ",g->vertices[i].vexData);//遍历每个顶点的所有边arcNode* a=(arcNode*)malloc(sizeof(arcNode));a=g->vertices[i].firstarc;while(a!=NULL){printf("%d&%d ",a->adjvex,a->weight);a=a->nextarc;}printf("\n");}}int locateVex(alGraph* g,char vex){//确定点vex在邻接表中的位置for(int i=0;i<g->vexnum;i++){//遍历比较if(g->vertices[i].vexData==vex){return i;}}printf("vex not exist in locateVex:%c\n",vex);return-1;//没找到返回-1}void CreateGraph(alGraph* g){//先序输入图printf("输入顶点数,边数和图类\n");scanf("%d%d%d",&(g->vexnum),&(g->arcnum),&(g->kind));g->vertices=(vnode*)malloc(g->vexnum*sizeof(vnode));printf("输入顶点\n");for(int i=0;i<g->vexnum;i++){printf("第%d个顶点:\n",i+1);getchar();//清掉回车g->vertices[i].vexData=getchar();g->vertices[i].firstarc=NULL;//尾部置空}printf("输入边和权重\n");for(int i=0;i<g->arcnum;i++){char sv;char tv;int w;getchar();//清掉回车printf("第%d条边和权重:\n",i+1);scanf("%c%c",&sv,&tv);scanf("%d",&w);int s=locateVex(g,sv);int t=locateVex(g,tv);arcNode* pi=(arcNode*)malloc(sizeof(arcNode));pi->adjvex=t;pi->weight=w;pi->nextarc=g->vertices[s].firstarc;//头插法g->vertices[s].firstarc=pi;if(g->kind==UDG ||g->kind==UDN){//若是无向图或无向网,在边的另一端也要加入边arcNode* pj=(arcNode*)malloc(sizeof(arcNode));pj->adjvex=s;pj->weight=w;pj->nextarc=g->vertices[t].firstarc;//头插法g->vertices[t].firstarc=pj;}}}void visit(vertexType v){//访问顶点数据printf("%c",v);}int find_element_in_array(char dest,vnode array[],int array_size){//在数组中寻找元素位置,找到返回,没找到返回-1for(int i=0;i<array_size;i++){if(dest==array[i].vexData){return i;}}// cout<<"fail to find element"<<endl;return-1;}void prim(alGraph* g,char start){alGraph p;//用邻接表存最小生成树p.vertices=(vnode*)malloc(g->vexnum*sizeof(vnode));p.vertices[0].vexData=start;p.vertices[0].firstarc=NULL;p.vexnum=1;p.arcnum=0;p.kind=UDN;while(true){if(p.vexnum==g->vexnum)break;//Vnew更新完则退出循环int min_weight=100;//假设所有边权重不超过100int min_index=0;int min_index_source=0;for(int i=0;i<p.vexnum;i++){//遍历Vnew所有边int index_find=find_element_in_array(p.vertices[i].vexData,g->vertices,g->vexnum); // cout<<index_find<<endl;if(index_find!=-1){//若在g中找到该点,遍历该点所有邻接边,查找权重最小的边arcNode* a=(arcNode*)malloc(sizeof(arcNode));a=g->vertices[index_find].firstarc;if(a==NULL)continue;while(true){if(a==NULL)break;if(a->weight<min_weight &&find_element_in_array(g->vertices[a->adjvex].ve xData,p.vertices,p.vexnum)==-1){//若找到更小权值的边(该边另一端点不在Vnew中)min_weight=a->weight;min_index=a->adjvex;min_index_source=i;}a=a->nextarc;}}}//找到权重最小的之后,更新Vnew和Enewp.vertices[p.vexnum].vexData=g->vertices[min_index].vexData;p.vertices[p.vexnum].firstarc=NULL;arcNode* pi=(arcNode*)malloc(sizeof(arcNode));pi->adjvex=p.vexnum;pi->weight=min_weight;pi->nextarc=p.vertices[min_index_source].firstarc;//头插法p.vertices[min_index_source].firstarc=pi;if (p .kind ==UDG || p .kind ==UDN ){//若是无向图或无向网,在边的另一端也要加入边arcNode * pj =(arcNode *)malloc (sizeof(arcNode ));pj ->adjvex =min_index_source ;pj ->weight =min_weight ;pj ->nextarc =p .vertices [p .vexnum ].firstarc ;//头插法p.vertices [p .vexnum ].firstarc =pj ;}p .vexnum ++;// printVertices(&p);}printVertices (&p );}int main (){//测试alGraph * g =(alGraph *)malloc (sizeof(alGraph ));if (g ==NULL){printf ("malloc fail in main for g \n ");return -1;}CreateGraph (g );printVertices (g );//查看邻接表printf ("输入起点:\n ");getchar ();//清掉回车char start =getchar ();cout <<"该图最小生成树为:"<<endl ;prim (g ,start );return 0;}DG,DN,UDG,UDN} GraphKind; // 定义图的类型 { 有向图, 有向网,无向图, 无向网}typedef struct arcNode{ //边int adjvex; //边上数据,指向其父节点下一个邻接点在顶点数组中的位置int weight; //边权重struct arcNode*nextarc; //指向下一条边}arcNode;typedef struct vnode{ //顶点vertexType vexData; //顶点数据string info; //顶点信息arcNode *firstarc; //指向第一个邻接点的边}vnode;typedef struct{ //图vnode *vertices; //顶点数组int vexnum, arcnum; //顶点数目,边的数目GraphKind kind; //图类型}alGraph;void printVertices(alGraph*g)//打印邻接表{for(int i =0; i < g->vexnum; i++)//遍历顶点数组{printf("%c ",g->vertices[i].vexData);//遍历每个顶点的所有边arcNode *a =(arcNode *)malloc(sizeof(arcNode));a =g->vertices[i].firstarc;while(a !=NULL){printf("%d&%d ",a->adjvex,a->weight);a =a->nextarc;}printf("\n");}}int locateVex(alGraph*g,char vex)//确定点vex在邻接表中的位置{for(int i =0; i < g->vexnum; i++){ //遍历比较if(g->vertices[i].vexData== vex){return i;}}printf("vex not exist in locateVex:%c\n", vex);return-1; //没找到返回-1}void CreateGraph(alGraph*g)//先序输入图{printf("输入顶点数,边数和图类\n");scanf("%d%d%d",&(g->vexnum),&(g->arcnum),&(g->kind)); g->vertices =(vnode *)malloc(g->vexnum *sizeof(vnode));printf("输入顶点\n");for(int i =0; i < g->vexnum; i++){printf("第%d个顶点:\n", i +1);getchar(); //清掉回车g->vertices[i].vexData=getchar();g->vertices[i].firstarc=NULL; //尾部置空}printf("输入边和权重\n");for(int i =0; i < g->arcnum; i++){char sv;char tv;int w;getchar(); //清掉回车printf("第%d条边和权重:\n", i +1);scanf("%c%c",&sv,&tv);scanf("%d",&w);int s =locateVex(g, sv);int t =locateVex(g, tv);arcNode *pi =(arcNode *)malloc(sizeof(arcNode));pi->adjvex= t;pi->weight= w;pi->nextarc=g->vertices[s].firstarc; //头插法g->vertices[s].firstarc= pi;if(g->kind== UDG ||g->kind== UDN)//若是无向图或无向网,在边的另一端也要加入边{arcNode *pj =(arcNode *)malloc(sizeof(arcNode));pj->adjvex= s;pj->weight= w;pj->nextarc=g->vertices[t].firstarc; //头插法g->vertices[t].firstarc= pj;}}}void visit(vertexType v)//访问顶点数据{printf("%c", v);}int find_char_in_vnode(char dest,vnode array[],int array_size)//在vnode数组中找dest(char),找到返回位置,没找到返回-1{for(int i =0; i < array_size; i++)//遍历寻找{if(dest ==array[i].vexData){return i;}}// cout<<"fail to find element"<<endl;return-1;}void prim(alGraph*g,char start)//prim算法,求最小生成树{alGraph p; //用邻接表存最小生成树p.vertices =(vnode *)malloc(g->vexnum *sizeof(vnode));p.vertices[0].vexData = start;p.vertices[0].firstarc =NULL;p.vexnum =1;p.arcnum =0;p.kind = UDN;while(true){if(p.vexnum==g->vexnum)//Vnew更新完则退出循环break;int min_weight =100; //假设所有边权重不超过100int min_index =0;int min_index_source =0;for(int i =0; i <p.vexnum; i++)//遍历Vnew所有边{int index_find =find_char_in_vnode(p.vertices[i].vexData,g->vertices,g->vexnum) ;// cout<<index_find<<endl;if(index_find !=-1)//若在g中找到该点,遍历该点所有邻接边,查找权重最小的边{arcNode *a =(arcNode *)malloc(sizeof(arcNode));a =g->vertices[index_find].firstarc;if(a ==NULL)continue;while(true){if(a ==NULL)break;if(a->weight< min_weight &&find_char_in_vnode(g->vertices[a->adjvex].ve xData,p.vertices,p.vexnum)==-1)//若找到更小权值的边(该边另一端点不在Vnew中){min_weight =a->weight;min_index =a->adjvex;min_index_source = i;}a =a->nextarc;}}}//找到权重最小的之后,更新Vnew和Enewp.vertices[p.vexnum].vexData=g->vertices[min_index].vexData;p.vertices[p.vexnum].firstarc=NULL;arcNode *pi =(arcNode *)malloc(sizeof(arcNode));pi->adjvex=p.vexnum;pi->weight= min_weight;pi->nextarc=p.vertices[min_index_source].firstarc; //头插法p.vertices[min_index_source].firstarc= pi;if(p.kind== UDG ||p.kind== UDN)//若是无向图或无向网,在边的另一端也要加入边{arcNode *pj =(arcNode *)malloc(sizeof(arcNode));pj->adjvex= min_index_source;pj->weight= min_weight;pj->nextarc=p.vertices[p.vexnum].firstarc; //头插法p.vertices[p.vexnum].firstarc= pj;}p.vexnum++;// printVertices(&p);}printVertices(&p);}template<typename t>void print_array(t array[],int array_size)//模板,打印数组{for(int i =0; i < array_size; i++){cout <<array[i]<<"";}}template<typename t>int find_element_in_array(t dest,t array[],int array_size)//模板,在数组中寻找元素,找到返回位置,没找到返回-1{for(int i =0; i < array_size; i++){if(array[i]== dest){return i;}}return-1;}void dijkstra(alGraph*g,char start)//dijkstra算法,求点start到其他所有点最短路径和最短距离{int dis[g->vexnum];int infinity =100; //假设所有边权重不超过100for(int i =0; i < g->vexnum; i++){if(i ==find_char_in_vnode(start,g->vertices,g->vexnum)){dis[i]=0; //start位赋值为0}else{dis[i]= infinity; //其他位先赋为无穷大}}arcNode *a =(arcNode *)malloc(sizeof(arcNode));a = g->vertices[find_char_in_vnode(start, g->vertices, g->vexnum)].firstarc;while(true) //初始化dis{if(a ==NULL)break;dis[a->adjvex]=a->weight;a =a->nextarc;}// print_array(dis,g->vexnum);char T[g->vexnum];//已经找到最短路径的点的集合int T_index =0;T[T_index++]= start;//T初始化char temp = start; //当前点string toTemp="";//当前路径toTemp=toTemp+temp;while(true)//寻找start到所有顶点路径和距离{if(T_index ==g->vexnum)break;int min_dis = infinity;int min_index =-1;for(int i =0; i <g->vexnum; i++)//从V-T中找出min(dis){if(find_element_in_array(g->vertices[i].vexData, T,g->vexnum)==-1&&dis[i]< min_dis){min_dis =dis[i];min_index = i;}}T[T_index++]=g->vertices[min_index].vexData;cout << toTemp <<"->"<<g->vertices[min_index].vexData<<"="<<dis[min_index]<< e ndl;//输出路径和距离arcNode *a2 =(arcNode *)malloc(sizeof(arcNode));a2 =g->vertices[min_index].firstarc;while(true)//查看与当前最小所连接的点,是否可发现到其他顶点的更短路径{if(a2 ==NULL)break;if(dis[min_index]+a2->weight<dis[a2->adjvex])//若找到更短的路径到达{dis[a2->adjvex]=dis[min_index]+a2->weight;//更新最短距离if(temp !=g->vertices[min_index].vexData)//若当前点变化,就更新{temp =g->vertices[min_index].vexData;toTemp = toTemp +"->"+ temp;//当前路径更新延伸到当前点}}a2 =a2->nextarc;}// print_array(dis,g->vexnum);}// print_array(dis, g->vexnum);}int main() //测试{alGraph *g =(alGraph *)malloc(sizeof(alGraph));if(g ==NULL){printf("malloc fail in main for g\n");return-1;}CreateGraph(g);printVertices(g); //查看邻接表printf("输入起点:\n");getchar(); //清掉回车char start =getchar();cout <<"该图最小生成树为:"<< endl;prim(g, start);cout <<"从"<< start <<"到各点最短路径及最短距离为:"<< endl;dijkstra(g, start);return0;}综合性实验4.调试分析1)采用IDE中自带的调试功能进行调试,手动添加断点和查看程序。

相关文档
最新文档