开课实验室:计算机科学与工程实验(电子楼418B) 2022年11月8日
学院 |
计算机科学与网络工程学院 |
年级、专业、班 |
姓名 |
学号 |
||||
实验课程名称 |
数据结构实验 |
成绩 |
||||||
实验项目名称 |
指导老师 |
一、实验目的
掌握线性的定义及基本操作,用链表实现:遍历、查找、插入、删除、翻转。
二、使用仪器、器材
微机一台
操作系统:
编程软件:
三、实验内容
(1)用随机函数生成10个3位整数(100~999),把这些整数存于链表中;
(2)输出链表的内容;
(3)读入一个整数,查看该整数是否在表中,若在,输出其位置(首位置为1);
(4)读入一个整数,以及要插入的位置,把该整数插入到链表中,输出链表的内容(要求判断输入的位置是否合理);
(5)读入一个整数,若该整数在链表里,删除该整数,输出链表的内容;
(6)把链表的内容翻转,输出链表的内容。
四、实验原理
填入自己的内容(思路或算法流程图或伪代码说明等)
0、随机函数:
鉴于此实验多次需要使用随机函数生成10个3位整数(100~999)来进行链表、链栈、链队的相关操作,于是便可以创建一个rand_number.h文件,并在此文件中声明函数produce_rands,在rand_number.cpp文件中具体实现该函数的方法,该函数用来产生一个一维数组,一维数组中包含10个随机生成的3位整数。这样子在链表、链栈、链队存储结构的实现中直接调用函数,就会方便很多。
生成随机函数需要用上time.h和math.h,定义一个系统时间变量time_t t,srand()用来设置rand()产生随机数时的随机数种子,srand((unsigned)time(&t));由系统时间确定随机序列这样子生成的就不是伪随机数了。
最后通过一个大小为10的一维数组接收随机数就可以了。
1、线性表的链表实现+线性表(单链表)的应用实现:
创建一个LinkList.h文件,在此文件中对单链表的结点类型LinkNode进行声明,并在此文件中声明单链表的基本运算算法,包括:初始化单链表、建立的单链表(头插法)、建立单链表(尾插法)、销毁线性表、判断是否为空表、求单链表的长度、遍历单链表,输出链表的内容、按元素值查找并返回元素所在位置、将元素插入至线性表指定位置、删除线性表中第一个与指定值匹配的数据元素等,再声明翻转链表的内容算法ListReverse、判断输入是否为整数算法JudgeInteger、以某整数为基准把单链表分割为两部分的算法ListPartition。
创建一个LinkList.cpp文件,在此文件中对LinkList.h文件中声明的函数进行具体实现。
创建一个main.cpp文件,包含LinkList.h和LinkList.cpp,在此文件中进行单链表存储结构以及单链表的应用实现(以某整数为基准把单链表分割为两部分)。
翻转链表的内容算法ListReverse:
创建了两个指针p、q,分别指向链表的首结点,断裂头结点,当q不指向空时,循环遍历数据结点,并采用头插法插入到头结点之后,这样子就实现了链表内容的翻转。
判断输入是否为整数算法JudgeInteger:
应实验要求,很多内容都需要读入一个整数才能进行相关的链表操作,这时就需要判断读入的数据是否为整数,所以需要设计判断输入是否为整数的算法。
将输入数据设置为浮点数类型double num,若num-(int)==0,说明输入数据为整数。
以某整数为基准把单链表分割为两部分的算法ListPartition:
在函数ListPartition中创建两个链表LessHead、GreatHead,分别存放小于x的节点和大于等于x的节点,将链表中的元素分别进行尾插至两链表,用指针cur遍历完链表L后,将链表LessHead的尾连接GreatHead的头,将GreatHead的尾置为空,最后将L的next指向LessHead的next即可。特别需要注意的是,要在函数体内销毁生成的两个链表头!
2、栈的链式存储结构实现+栈的应用实现(判别给定表达式中所含括号是否正确配对):
创建一个LinkStack.h文件,在此文件中对链栈中的结点类型LinkStNode进行声明,并在此文件中声明链栈的基本运算算法,包括:初始化链栈、释放链栈、判链栈空、入栈、出栈、取栈顶等,再声明判别给定表达式中所含括号是否正确配对的算法Match。
创建一个LinkStack.cpp文件,在此文件中对LinkStack.h文件中声明的函数进行具体实现。
创建一个main.cpp文件,包含LinkStack.h和LinkStack.cpp,在此文件中进行栈的链式存储结构以及链栈的应用实现(判别给定表达式中所含括号是否正确配对)。
特别需要注意的是,由于要求产生的三位随机数是int类型的,而表达式是char类型,故链栈的结点类型LinkStNode、链栈的基本算法函数、判别给定表达式中所含括号是否正确配对的算法函数Match都应设置为模板,即声明结构体模板和函数模板,这样子才具有较强的适应性,以满足不同的数据类型。
在判别给定表达式中所含括号是否正确配对的算法Match中应用入栈与出栈的操作,当字符为左括号时,将其入栈;当字符为右括号时,将栈顶元素(当且仅当此元素为左括号时)出栈。这样子就可以很好地进行括号的匹配。
3、队列的链式存储结构的实现
创建一个LinkQueue.h文件,在此文件中对链队数据结点的类型DataNode进行声明,对链队头结点的类型LinkQuNode进行声明,并在此文件中声明链队的基本运算算法,包括:初始化带头结点的链队、销毁链队、判断链队是否为空、入队、出队、遍历队列、等,再声明翻转链队内容算法ReverseQueue。
创建一个LinkQueue.cpp文件,在此文件中对LinkQueue.h文件中声明的函数进行具体实现。
创建一个main.cpp文件,包含LinkQueue.h和LinkQueue.cpp,在此文件中进行队列的链式存储结构的实现。
翻转链队内容算法ReverseQueue:
判断链队是否为空,链队为空时输出无法翻转,链队不为空时执行翻转操作。
创建三个指针,分别指向前三个数据元素,将尾指针指向首个数据结点(翻转后的尾结点),循环遍历链队中的元素,在循环过程中将后一个数据结点指向前一个数据结点,再将三个指针同步后移,直至循环结束。此时除了倒数两个数据结点没有翻转,其他结点均完成了翻转。将最后一个数据结点指向倒数第二个数据节点,所有数据结点翻转完毕。最后将头结点指向尾结点(翻转后的首结点),将首结点(翻转后的尾结点)的next域置为空,即可完成链队内容的全部翻转。
4、用队列求解迷宫问题的最短路径
创建一个SequentialQueue.h文件,在此文件中对方块类型Box进行声明,对顺序队类型QuType进行声明,并在此文件中声明顺序队的基本运算算法,包括:初始化队列、销毁队列、判断队列是否为空、进队列、出队列,搜索迷宫的路径、输出迷宫的最短路径等,
创建一个SequentialQueue.cpp文件,在此文件中对SequentialQueue.h文件中声明的函数进行具体实现。
创建一个main.cpp文件,包含SequentialQueue.h和SequentialQueue.cpp,在此文件中进行求解迷宫问题的最短路径实现。
五、实验过程原始数据记录
1、实验源代码及注释
(0)随机函数:
rand_number.h
#pragma once
#include "time.h" //时间函数
#include "math.h" //随机函数
#include"iostream"
using namespace std;
void produce_rands(int array[]);
rand_number.cpp
#include"rand_number.h"
void produce_rands(int array[])
{
time_t t; //定义时间变量
srand((unsigned)time(&t)); //由时间确定随机序列,执行一次
for (int i = 0; i < 10; i++)
{
//int rand_n = (1 + rand() % 999);
//while (rand_n < 100)