数据结构张铭测验Word文档格式.docx

上传人:b****5 文档编号:21473133 上传时间:2023-01-30 格式:DOCX 页数:62 大小:243.13KB
下载 相关 举报
数据结构张铭测验Word文档格式.docx_第1页
第1页 / 共62页
数据结构张铭测验Word文档格式.docx_第2页
第2页 / 共62页
数据结构张铭测验Word文档格式.docx_第3页
第3页 / 共62页
数据结构张铭测验Word文档格式.docx_第4页
第4页 / 共62页
数据结构张铭测验Word文档格式.docx_第5页
第5页 / 共62页
点击查看更多>>
下载资源
资源描述

数据结构张铭测验Word文档格式.docx

《数据结构张铭测验Word文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构张铭测验Word文档格式.docx(62页珍藏版)》请在冰豆网上搜索。

数据结构张铭测验Word文档格式.docx

charstring[MAX_LENGTH];

strings*pNext;

}

如果有后续工作如反复增删结点,效率很高.并且可以使用不连续的空间。

操作过程相对复杂,容易出错.而且排序过程需要从表头开始沿链索一个结点一个结点的比较搜索,相当费时。

3.索引存储

是顺序存储的一种推广.使用一个字符串chardata[500],其中将大小长度不等的数据结点(单词)顺序存储其中.令使用一个字符指针数组char*index[n],存储一系列指针,每个指针指向存储区域的一个数据结点.

排序时,直接对index中的地址值进行调换修改即可,而不用修改data中的任何内容。

索引存储的优点是:

由于单词长度不同,在存储时充分考虑了这个因素,可以节省空间,此外由于交换的不是单词本身而是单词的地址,可以节省时间,从时空两方面得到了优化。

【排序结果】

B899,B9,CRSI,CXY,PAB,PABC,5C,7 

2、解答:

本题没有指明这100个实数是否存在相等的情况,在这里,我们考虑存在多个最大值的情形(即100个实数可能有相等的),为了保存其位置,利用intpos[100](因为有可能这100个实数都是相同的)来保存最大值的所有位置。

1.用int类型的数组来保存这100个元素,没有注意题目中说的是“每个元素的值都是实数”。

2.求最大值的时候代码如下:

temp=0;

for(inti=0;

i<

100;

i++)

if(Num[i]>

temp)

temp=Num[i];

评注:

这样是错误的,例如:

当Num[i]都是负数的时候。

3.未考虑可能存在多个最大值的情况,只保存了一个最大值的位置。

本题可以采用的存储结构有顺序(数组),链表和索引。

本题最好使用数组存储结构。

由于其他存储方法需要记录附加信息,使得空间有效利用不能够最大化。

因此在空间上顺序存储是最优的。

时间上,无论如何此题都要遍历所有的数,因此O(n)为可能的最优时间代价。

加之此题的规模较小,因此使用大家最熟悉的顺序存储是较为优先的选择。

【算法描述】

1.由于最大值可能不止一个,甚至可能都是最大值,所以创建一个长度为100的整型数组pos[100],用来记录最大值的位置。

2.初始情况,取这个数组的第一个位置为最大值所在的位置,存入变量position中。

3.假设有n(1≤n≤99)个最大值,那么pos[0,1,2,…,n-1]记录这些最大值的位置,且pos[n]=-1(-1是标记值,表明pos数组下标为n-1及以前的元素记录了最大值的位置);

假设有n(n=100)个最大值,那么pos[0,1,2,…,n-1]记录这些最大值的位置,pos数组不再设-1的标记值。

具体源码如下:

#include<

iostream.h>

voidmain(){

//存放100个实数的数组

doubleNum[100]={4543.9,4543.9,3,45,654.7,7,66,35,45,4,6,4543.9,5,46,54,6,43,5.980,34};

//记录最大值所在位置的数组

intpos[100];

//初始设定数组的第1个元素为最大值

intposition=0;

//j指示位置数组pos的下标

intj=1;

for(inti=1;

++i)

Num[position]){

position=i;

//记下新的最大值的位置

j=1;

//位置数组pos的下标恢复为1,下标为0的位置为position预留

elseif(Num[i]==Num[position])

pos[j++]=i;

//记下重复最大值的位置

//位置数组pos的下标为0的位置为position预留

pos[0]=position;

//-1为标识值,表示位置数组pos下标为0,1,2…(j-1)的位置存

//放的是最大值所在的位置

if(j<

100)

pos[j]=-1;

cout<

<

"

最大值为:

Num[position]<

endl;

最大值所在的位置为:

for(i=0;

i<

++i){

if(pos[i]==-1) 

//-1是标识值

break;

第"

(pos[i]+1)<

个元素"

3、解答:

【逻辑结构】

逻辑结构由结点集合K和关系集合R来表示,以学生每周的课程表为例:

将每天的课程安排数据作为结点,一共引入7个结点,它们的名称依次为“星期一”,“

星期二”,“星期三”,……,“星期日”。

全部结点组成结点集K。

这些结点是复合类型,是一个结构体,包括当日课程的名称,时间和地点等。

这些结点两两之间有一个时间关系r,r={(“星期一“,“星期二”),(“星期二”,“星期三”),(“星期三”,“星期四”),(“星期四”,“星期五”),(“星期五”,“星期六”),(“星期六”,“星期日”)。

此集合中的6个元素描述了“时间先后”关系r。

此外,还引入一个关系r*={“星期日”,“星期一”},r*只含有一个元素,以表示星期日和下一周工作日的时间顺序。

r和r*共同构成关系集R。

其中r属于线性结构。

R是一种环行的关系。

【存储结构】

几种可行的存储方案比较

1.顺序表:

见图一

优点:

逻辑清晰,查阅修改方便;

缺点:

需要占用整块的存储空间,对空间要求较大 

星期

课次

1~2

课程名

上课地点

授课老师…

3~4

5~6

7~8

9~10

图一顺序表存储课程表

2.索引

图二索引结构的课程表

构造索引表,其中的指针分别指向每一天的课程

逻辑较清晰,不占用整块的存储空间,缺点:

算法较复杂,附加的空间代价较高(有索引表)

3.链表:

链接的方法是可以采纳的一个方法,每个指针都指向逻辑关系中的紧邻后继,最后一个结点的指针指向首结点,构成一个循环链表.链表结构检索较繁琐.

【相关运算】

常见的运算包括增、删、查、改运算,课程表的抽象数据类型可以定义如下:

template<

classELEM>

classtable

//当程序使用此table模板时,应该在前面附加#include<

table>

{

public:

//创建一张空课程表

table<

ELEM>

t;

//创建一张天数为k的课程表,可默认k为7

t(intk);

//设置某天的课程(时间地点等),该结点的地址可由索引表找出

virtualvoidSetcourse(ELEM&

pday)=0;

//把一个新的结点插入课程表,使该结点在表中位置是nPos如果nPos=-1

//则插入到表尾部(同时地址加入索引表) 

virtualvoidAddday(constELEM*pday,intnPos=-1)=0;

//删除课程表中某天(结点),释放该结点的空间,该结点的地址可由索引表找出

virtualvoidRemoveday(ELEM&

//清空整个课程表,成功返回true

virtualboolClearall()=0;

//清空某天(结点)的所有内容,该结点的地址可由索引表找出,成功返回true

virtualboolClearday(ELEM&

pday)=0;

//修改某天(结点)的课程(时间地点等),该结点的地址可由索引表找出

virtualvoidChangecourse(ELEM&

//输出某天(结点)的课程内容,该结点的地址可由索引表找出

virtualvoidPrintday(ELEM&

pday)=0;

//输出所有课程内容(结点)

virtualvoidPrintList()=0;

//根据系统时间查询当天课程

virtualvoidCurrent()=0;

//统计课程总数

virtualintNumber()=0;

//析构函数,清空课程表

~table();

private:

ELEM*m_index;

//索引表头指针

}

第二章线性表、栈和队列练习

 本章练习

1、(教材习题2.1)给出一个算法,求单链表X中,内容为a的结点地址。

2、(教材习题2.5)给出一个算法,求出循环表中结点的个数。

3、(教材习题2.8)编号为1,2,3,4的四辆列车,顺序开进一个栈式结构的站台;

问开出车站的顺序有多少种可能,请具体写出来。

4、(教材习题2.10)环状的队列,写出计算队列元素个数的程序。

5、(教材习题2.19)现有4个元素作为双端队列的输入,问可以得到多少种不同的排列?

参考答案

第二章线性表、栈和队列练习答案

本题没有指明是否存在多个内容为a的地址,在这里,我们考虑存在多个结点内容为a的情形。

没有考虑内容为a的地址可能有多个。

由于链表中内容为a的结点数目不确定,可以选择用一个新链表来存放找到的结点地址。

这样的存储结构

优于定长数组。

本题中涉及到两个链表:

原链表ListNode和用于存储结点地址的新链表ListAddress。

1. 

设pfirst和qfirst分别是这两个链表的头指针,p,q为指针变量。

2. 

p从链表X的表头开始向后移动,每当遇到原链表中内容为a的结点,就在新链表中增

加一个结点记录下其地址(用指针指向该结点来进行记录),如此循环直到链表X的表尾。

structListNode 

//链表结点定义

ELEMdata;

//数据类型为ELEM

ListNode*plink;

//指向后继结点的指针

};

ListNode*pfirst;

//pfirst指向原链表第一个结点

ListNode*p;

//原链表的指针变量,程序运行时可对其所指结点进行各种运算

p=pfirst;

//指向头指针

StructListAddress 

//用于存放地址的新链表

ListNode*address;

//存放地址,类型为指向链表X的结点的指针

ListAddress*qlink;

//新链表的指针变量

ListAddress*qfirst;

//qfirst指向新链表第一个结点

qfirst->

qlink=NULL;

//空表

ListAddress*q=qfirst;

voidfind(ELEMa) 

//用于查找内容为a的结点,并记录其地址,参数为待查数据a

while(p!

=NULL) 

//未到达链表尾结点

if(p->

data==a) 

//找到符合条件的结点,插入新链表

q->

qlink=newListAddress;

//创建内存空间

qlink->

address=p;

//存储指向该结点的指针

q=q->

qlink;

//指针向后移

p=p->

plink;

//指针后移继续查找

判断已经遍历整个循环表的方法:

使用一个指针变量link从链表首元素向后遍历整个链表,直到link==first时,说明该结点即尾结点。

设空表时结点数count为0(此时first->

link=first),每经过一个结点count加1,直到到达尾结点。

structListNode

ListNode*link;

intLength(ListNode*first) 

//first为循环表的头指针

p=first;

intcount=0;

//用于记录结点数,空链表时结点数为0

while(p->

link!

=first) 

//未到达尾结点

link;

count++;

//结点数加1

returncount;

3、解答:

有14种可能:

【思路】

先进站的车可以先开,也可以后开。

只有一种情况不可能:

编号大的车开出后,比其编号小的车反序开出。

也即编号大的车开出后,编号比其小的车只能由大到小依次开出(中间可以插入编号更大的车,但此车后面的编号小的车也要遵守此规则)。

例如312的开出顺序是不可能的。

对所有车进行全排列共有24种出法。

但4开头的只能有一种:

4321。

所以少了3的全排列-1=5种。

三开头的时候,必须先2后1开出,先1后2时4的位置有三种:

3124、3142、3412,所以少了三种。

1或2开头的时候,后面的车如果是4,则最后两辆必须是3、2或3、1。

所以又少了1423、2413两种。

总共少了5+3+2=10种,有24-10=14种开出法。

下面用+表示进站,-表示出站:

1234:

1+ 

1- 

2+ 

2- 

3+ 

3- 

4+ 

4-

1243:

4- 

3-

1324:

1342:

2-

1432:

2134:

2143:

2314:

2341:

1-

2431:

3214:

3– 

2– 

1– 

4-

3241:

3421:

4321:

1-

4、解答:

对于顺序队列

intQueue:

:

length_of_queue()

if(IsEmpty())return0;

if(front<

=rear)returnrear-front;

elsereturnmaxsize+rear-front;

对于链式队列

inttotal=0;

for(ListPtrtemp=front;

temp!

=rear;

temp=temp->

link)total++;

returntotal;

5、解答:

双端队列可以在队列的两端进行插入和删除操作,既可在队尾进行插入/删除,又可在队头进行插入/删除。

但第一个元素从左或右入队没有区别,以后每个元素都有两种入队方式。

即有2^3=8种方法。

不妨设元素为a,b,c,d,各种排列如下:

第一次放入a:

a

第二次放入b:

abba 

第三次放入c:

cababccbabac

第四次放入d:

dcabcabddabcabcddcbacbaddbacbacd 

故共有8种。

第三章字符串练习

1、(教材习题3.1)设有字符串变量StringA='

'

,B='

MULE'

,C='

OLD'

,D='

MY'

;

请计算下列表达式

(a)A+B

(b)B+A

(c)D+C+B

(d)B.substr(3,2)

(e)C.substr(1,1)

(f)A.str1ength()

(g)D.str1ength()

(h)B.Find('

L'

(i)C.FindLast('

D'

(j)D.insert(B,2)

(k)B.insert(B,1)

(1)B.remove(2,2)

(m)B.remove(0,5)

2、(教材习题3.2)计算下列字符串P的特征向量N[i]

(a)'

ABCDEFGH'

(b)'

IIIIIIII'

(c)'

BABBABAB'

注意串内字符间有空格隔开

3、设计算法用顺序结构存储的串s和串t的一个最长公共子串。

4、编写程序,统计在输入字符串中各个不同字符出现的频度并将结果存入文件(字符串中的合法字符为A-Z这26个字母和

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1