当前位置:文档之家› 数据结构实验指导手册(2015版)

数据结构实验指导手册(2015版)

五邑大学计算机学院数据结构实验指导手册2015年3月目录实验一线性表 (1)1.实验目的 (1)2.实验内容 (1)3.解题思路 (1)实验二栈 (4)1.实验目的 (4)2.实验内容 (4)3.解题思路 (4)实验三队列 (8)1.实验目的 (8)2.实验内容 (8)3.解题思路 (8)实验四二叉树 (12)1.实验目的 (12)2.实验内容 (12)3.解题思路 (12)实验五哈夫曼树 (18)1.实验目的 (18)2.实验内容 (18)3.解题思路 (18)实验六图的基本存储 (21)1.实验目的 (21)2.实验内容 (21)3.解题思路 (21)实验七图的应用 (26)1.实验目的 (26)2.实验内容 (26)3.解题思路 (26)实验八查找 (30)1.实验目的 (30)2.实验内容 (30)3.解题思路 (30)实验九排序 (32)1.实验目的 (32)2.实验内容 (32)3.解题思路 (32)说明 (36)附录实验报告模板 (37)实验一线性表1.实验目的(1)了解线性表的逻辑结构特性是数据元素之间存在着线性关系,在计算机中表示这种关系有顺序存储结构和链式存储结构;(2)掌握这两种存储结构的描述方法;(3)掌握线性表的基本操作(查找、插入、删除);(4)考虑时间和空间复杂度设计算法。

2.实验内容(1)创建一个顺序表,存放在数组A[N]中,元素的类型为整型,设计算法调整A,使其左边的所有元素小于0,右边的所有元素大于0(要求算法的时间复杂度和空间复杂度均为O(n))。

(2)建立一个循环单链表,其节点有prior,data和next三个域,其中data为数据域,存放元素的有效信息,next域为指针域,指向后继节点,prior为指针域,它的值为NULL。

编写一个算法将此表改为循环双链表。

3.解题思路(1)如图1-1所示,设立两个工作指针i和j,i由数组的左端向右移动,查找大于等于0的数,j由数组的右端向左端移动,查找小于0的数,然后交换,如图1-2所示,直到i>=j,调整结束。

图1-1图1-2算法描述(C语言)如下:void quickSwapList(int a[],int n){int i = 0, j = n - 1 ; // n为顺序表的长度,即数的个数while( i < j ){while( a[i] < 0 && i < j ) i ++ ; // 找到左边大于等于0的数while( a[j] >= 0 && i < j ) j -- ; // 找到右边小于0 的数if(i < j ) // 交换{int t = a[i] ; a[i] = a[j] ; a[j] = t ;}i++;j--;}}(2)如图1-3所示,已建有一个单循环链表(带头结点),first指向头结点。

设立两个工作指针p和q,分别指向头结点和第1个结点;执行q->prior=p;,建立第1个结点的前驱指针,如图1-4所示;同步移动工作指针p和q分别指向下一个结点,如图1-5所示,建立q指向结点的前驱,直到q==first为止,再将头结点的前驱设为最后一个结点,如图1-6所示。

图1-3图1-4图1-5图1-6算法描述(C语言)如下:void singleCircleToDoubleCircleLinkList(struct Node *first) {struct Node *p,*q;p=first; //工作指针p指向头结点q=first->next; //工作指针q指向第1个结点while(q!=first){q->prior=p; //置结点q的前驱为指针p指向的结点p=p->next; //移动工作指针pq=q->next; //移动工作指针q}q->prior=p; //置头结点的前驱为最后一个结点}实验二栈1.实验目的(1)理解栈的定义、特点及与线性表的异同;(2)熟悉顺序栈的组织方法,栈满、栈空的判断条件及其描述;(3)掌握栈的基本操作(进栈、退栈等)。

2.实验内容(1)设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达式的值。

(2)设计两个栈S1、S2都采用顺序栈方式,并且共享一个存储区[0,MaxLen-1],为了尽量利用空间,减少溢出的可能,可采用栈顶相向、迎面增长的存储方式,如图2-1所示。

设计一个有关栈的入栈和出栈算法。

图2-13.解题思路(1)一般算术表达(中缀表达),如#3*(4+2)/2-5#,#为表达式界定符,逆波兰表达式(后缀表达式),如前述表达的后缀表达式为:3 4 2 + * 2 / 5 -。

设中缀表达式的运算符有+、-、*、/、#五种,运算符的优先级别从高到低为()、*、/、+、-、#;有括号先算括号内,再算括号外的,多层括号由内向外进行。

中缀表达式转换为后缀表达式需要用到一个临时栈optr暂存运算符。

转换算法描述(伪代码)如下:1.将栈optr初始化为#;2.从左至右依次扫描表达式的每个字符,执行下述操作2.1 若当前字符是运算对象,则输出该字符,处理下一个字符;2.2 若当前字符是运算符且优先级别比栈optr的栈顶运算符的优先级高,则将该字符入栈optr,处理下一个字符;2.3 若当前字符是运算符且优先级别比栈optr的栈顶运算符优先级别低,则将栈optr的栈顶元素弹出并输出;2.4 若当前字符是运算符且优先级别与栈optr的栈顶运算符的优先级相等,则将栈optr的栈顶元素弹出,处理下一个字符。

后缀表达式求值,由于后缀表达中所有的计算按运算符出现的顺序从左向右进行,不用再考虑运算符的优先级。

设定一个临时堆栈opnd暂存计算过程的中间结果。

后缀表达式计算算法描述(伪代码)如下:1.初始化栈opnd为空;2.从左到右依次扫描表达式的每一个字符,执行下述操作;2.1 若当前是运算对象,则入栈opnd,处理下一个字符;2.2 若当前字符是运算符,则从栈opnd出栈两个运算对象,执行运算并将结果入栈opnd,处理下一个字符;3.输出栈opnd的栈顶元素,即表达式的运算结果。

(2)两栈共享存储空间,需要解决的关键问题在于如何判断栈满和栈空,由于两栈共享存储空间,入栈和出栈的时候还需要区分是哪个栈。

设lsTop是左栈(数组下标为0的一端为栈底)栈顶指针,rsTop为右栈(数组下标为MaxLen-1的一端为栈底)栈顶指针,显然,当两个栈都为空时,lsTop==-1,rsTop==MaxLen,如图2-2所示;当栈满时,rsTop和lsTop存在以下关系:rsTop==lsTop+1,如图2-3所示。

图2-2图2-3入栈算法描述(C语言)如下://入栈,s=1,入左栈,s=2,入右栈,x为入栈元素void push(int s,int x){if(rsTop==lsTop+1)//栈满{printf("栈已满!\n");return;}if(s==1)//入左栈{lsTop++;dsStack[lsTop]=x;}else if(s==2)//入右栈{rsTop--;dsStack[rsTop]=x;}elseprintf("该栈不存在!\n");return;}出栈算法描述(C语言)如下://出栈,s=1,出左栈,s=2,出右栈,x返回出栈元素,成功函数返回1,否则返回0 int pop(int s,int *x){if(s==1)//出左栈{if(lsTop==-1){printf("栈已空!\n");return 0;}*x=dsStack[lsTop];lsTop--;}else if(s==2)//出右栈{if(rsTop==MaxLen){printf("栈已空!\n");return 0;}*x=dsStack[rsTop];rsTop++;}else{printf("该栈不存在!\n");return 0;}return 1;}实验三队列1.实验目的(1)理解队列的定义、特点及与线性表的异同;(2)熟悉队列的组织方法,队列满、队列空的判断条件及其描述;(3)掌握队列的基本操作(入队、出队等)。

2.实验内容(1)假设以数组sequ[MaxSize]存放环形队列的元素,同时Rear和Len分别指示环形队列中队尾元素的位置和内含元素的个数。

设计相应的入队和出队算法。

(2)某汽车轮渡口,过江渡船每次能载10辆车过江。

过江车辆分别为客车类和货车类,上船有如下规定:同类车先到先上船,客车先于货车上渡船,且每上4辆客车,才允许上一辆货车;若等待客车不足4辆则以货车代替;若无货车等待则允许客车都上船。

设计一个算法模拟渡口管理。

3.解题思路(1)解决问题的关键在于以下两点:如何使用软件的方法构造环形队列和如何通过Rear和Len来确定队头元素所在的位置。

对于第1点,通过模运算来实现,即Rear=(Rear+1)%MaxSize;第2个问题,当队尾元素的下标大于队头元素的下标时,如图3-1所示,显然,Rear-Len+1即为队头元素的下标;当队尾元素的下标小于队头元素的下标时,如图3-2所示,此时队头元素的下标为:(Rear+MaxSize)-Len+1;为使这两种情况统一处理,采用以下表达式来计算队头元素的下标:((Rear+MaxSize)-Len+1)%MaxSize。

队空和队满的问题通过Len的值即可判断出,Len=0显然是队空,Len=MaxSize则为队满。

图3-1图3-2环形队列入队算法描述(C语言)如下://入队void entryQueue(int x){if(Len==MaxSize)//队满{printf("队列已满,不能入队\n");return;}Rear=(Rear+1)%MaxSize;//移动队尾指针sequ[Rear]=x;//入队Len++;//长度加1return;}环形队列出队算法描述(C语言)如下://出队,返回出队元素int exitQueue(void){int x,First;//队头元素的下标if(Len==0)//队空{printf("队列已空,不能出队\n");return -1;}First=((Rear+MaxSize)-Len+1)%MaxSize;//计算队头元素的下标x=sequ[First];//获得队头元素Len--;//长度减1return x;//返回队头元素}(2)建立3个队列,分别为客车队列bus,货车队列truck和渡船队列ferry,设置3个变量标识已上渡船的客车数量busNum、货车数量truckNum和总数量totalNum。

相关主题