数据结构第九章作业提示.docx
《数据结构第九章作业提示.docx》由会员分享,可在线阅读,更多相关《数据结构第九章作业提示.docx(64页珍藏版)》请在冰豆网上搜索。
数据结构第九章作业提示
第9章排序
静态数据表类定义
#include
constintDefaultSize=100;
templateclassdataList//数据表的前视声明
templateclassElement{//数据表元素类的定义
friendclassdataList;
private:
Typekey;//排序码
fieldotherdata;//其它数据成员
public:
TypegetKey(){returnkey;}//取当前结点的排序码
voidsetKey(constTypex){key=x;}//将当前结点的排序码修改为x
Element&operator=(Element&x)//结点x的值赋给this
{key=x->key;otherdata=x->otherdata;}
intoperator==(Type&x){returnkey==x->key;}//判this与x相等
intoperator<=(Type&x){returnkey<=x->key;}//判this小于或等于x
intoperator>(Type&x){returnkey>x->key;}//判this大于x
intoperator<(Type&x){returnkey>x->key;}//判this小于x
}
templateclassdataList{
//用顺序表来存储待排序的元素,这些元素的类型是Type
private:
Element*Vector;//存储待排序元素的向量
intMaxSize,CurrentSize;//最大元素个数与当前元素个数
intPartition(constintlow,constinthigh)//用于快速排序的一次划分算法
public:
datalist(intMaxSz=DefaultSize):
MaxSize(Maxsz),CurrentSize(0)
{Vector=newElement[MaxSize];}//构造函数
intlength(){returnCurrentSize;}
Element&operator[](inti){returnVector[i];}
voidswap(Element&x,Element&y)//交换x,y
{Elementtemp=x;x=y;y=temp;}
voidSort();//排序
}
静态链表类定义
templateclassstaticlinkList;//静态链表类的前视声明
templateclassElement{//静态链表元素类的定义
friendclassstaticlinkList;
private:
Typekey;//排序码,其它信息略
intlink;//结点的链接指针
public:
TypegetKey(){returnkey;}//取当前结点的排序码
voidsetKey(constTypex){key=x;}//将当前结点的排序码修改为x
intgetLink(){returnlink;}//取当前结点的链接指针
voidsetLink(constintptr){link=ptr;}//将当前结点的链接指针置为ptr
}
templateclassstaticlinkList{//静态链表的类定义
private:
Element*Vector;//存储待排序元素的向量
intMaxSize,CurrentSize;//向量中最大元素个数和当前元素个数
public:
dstaticlinkList(intMaxsz=DefaultSize):
MaxSize(Maxsz),CurrentSize(0)
{Vector=newElement[Maxsz];}
}
9-1什么是内排序?
什么是外排序?
什么排序方法是稳定的?
什么排序方法是不稳定的?
【解答】内排序是排序过程中参与排序的数据全部在内存中所做的排序,排序过程中无需进行内外存数据传送,决定排序方法时间性能的主要是数据排序码的比较次数和数据对象的移动次数。
外排序是在排序的过程中参与排序的数据太多,在内存中容纳不下,因此在排序过程中需要不断进行内外存的信息传送的排序。
决定外排序时间性能的主要是读写磁盘次数和在内存中总的记录对象的归并次数。
不稳定的排序方法主要有希尔排序、直接选择排序、堆排序、快速排序。
不稳定的排序方法往往是按一定的间隔移动或交换记录对象的位置,从而可能导致具有相等排序码的不同对象的前后相对位置在排序前后颠倒过来。
其他排序方法中如果有数据交换,只是在相邻的数据对象间比较排序码,如果发生逆序(与最终排序的顺序相反的次序)才交换,因此具有相等排序码的不同对象的前后相对位置在排序前后不会颠倒,是稳定的排序方法。
但如果把算法中判断逆序的比较“>(或<)”改写成“≥(或≤)”,也可能造成不稳定。
9-2设待排序的排序码序列为{12,2,16,30,28,10,16*,20,6,18},试分别写出使用以下排序方法每趟排序后的结果。
并说明做了多少次排序码比较。
(1)直接插入排序
(2)希尔排序(增量为5,2,1)(3)起泡排序
(4)快速排序(5)直接选择排序(6)锦标赛排序
(7)堆排序(8)二路归并排序(9)基数排序
【解答】
(1)直接插入排序
初始排列
0
1
2
3
4
5
6
7
8
9
排序码比较次数
i=1
[12]
2
16
30
28
10
16*
20
6
18
1
i=2
[2
12]
16
30
28
10
16*
20
6
18
1
i=3
[2
12
16]
30
28
10
16*
20
6
18
1
i=4
[2
12
16
30]
28
10
16*
20
6
18
2
i=5
[2
12
16
28
30]
10
16*
20
6
18
5
i=6
[2
10
12
16
28
30]
16*
20
6
18
3
i=7
[2
10
12
16
16*
28
30]
20
6
18
3
i=8
[2
10
12
16
16*
20
28
30]
6
18
3
i=9
[2
6
10
12
16
16*
20
28
30]
18
8
[2
6
10
12
16
16*
18
20
28
30]
(2)希尔排序(增量为5,2,1)
初始排列
0
1
2
3
4
5
6
7
8
9
排序码比较次数
12
2
16
30
28
10
16*
20
6
18
1+1+1+1+1=5
d=5
10
2
16
6
18
12
16*
20
30
28
(1+1+2+1)+(1+1
d=2
+1+1)=9
10
2
16
6
16*
12
18
20
30
28
1+1+3+1+3+1+1
d=1
+1+2=14
2
6
10
12
16
16*
18
20
28
30
希尔(shell)本人采取的增量序列为n/2,n/2/2,n/2/2/2,…,1。
一般地,增量序列可采用nα,nαα,nααα,…,1。
大量实验表明,取α=0.45454的增量序列比取其他的增量序列的优越性更显著。
计算0.45454n的一个简单方法是用整数算术计算(5*n-1)/11。
需要注意,当<1/2时,增量序列可能不以1结束,需要加以判断和调整。
(3)起泡排序
初始排列
0
1
2
3
4
5
6
7
8
9
排序码比较次数
i=0
[12
2
16
30
28
10
16*
20
6
18]
9
i=1
2
[12
6
16
30
28
10
16*
20
18]
8
i=2
2
6
[12
10
16
30
28
16*
18
20]
7
i=3
2
6
10
[12
16
16*
30
28
18
20]
6
i=4
2
6
10
12
[16
16*
18
30
28
20]
5
i=5
2
6
10
12
16
[16*
18
20
30
28]
4
i=6
2
6
10
12
16
16*
[18
20
28
30]
3
2
6
10
12
16
16*
18
20
28
30
(4)快速排序
Pivot
Pvtpos
0
1
2
3
4
5
6
7
8
9
排序码比较次数
pos
pos
pos
pos
12
0,1,2,3
[12
2
16
30
28
10
16*
20
6
18]
9
pos
pos
6
0,1
[6
2
10]
12
[28
16
16*
20
30
18]
2
pos
pos
pos
pos
pos
28
4,5,6,7,8
[2]
6
[10]
12
[28
16
16*
20
30
18]
5
pos
pos
pos
18
4,5,6
2
6
10
12
[18
16
16*
20]
28
[30]
3
pos
16*
4
2
6
10
12
[16*
16]
18
[20]
28
30
1
2
6
10
12
16*
[16]
18
20
28
30
左子序列递归深度为1,右子序列递归深度为3。
(5)直接选择排序
初始排列
0
1
2
3
4
5
6
7
8
9
排序码比较次数
i=0
[12
2
16
30
28
10
16*
20
6
18]
9
i=1
2
[12
16
30
28
10
16*
20
6
18]
8
i=2
2
6
[16
30
28
10
16*
20
12
18]
7
i=3
2
6
10
[30
28
16
16*
20
12
18]
6
i=4
2
6
10
12
[28
16
16*
20
30
18]
5
i=5
2
6
10
12
16
[28
16*
20
30
18]
4
i=6
2
6
10
12
16
16*
[28
20
30
18]
3
i=7
2
6
10
12
16
16*
18
[20
30
28]
2
i=8
2
6
10
12
16
16*
16
20
[30
28]
1
2
6
10
12
16
16*
16
20
28
[30]
(6)锦标赛排序
输出2,调整胜者树
2
6
2
10
6
2
16*
10
16
6
2
18
6
20
16*
10
28
16
30
2
12
当参加排序的数据对象个数n不足2的某次幂时,将其补足到2的某次幂。
本题的n=10,将叶结点个数补足到24=16个。
排序码比较次数=9。
输出6,调整胜者树
6
6
10
10
6
12
6
16*
10
16
12
18
6
20
16*
10
28
30
16
2
12
10
输出10,调整胜者树
排序码比较
次数=1。
10
10
18
18
12
10
18
16*
16
12
12
18
6
20
16*
10
28
30
16
2
当某结点的比较对手的参选标志为“不再参选”,该结点自动升入双亲结点,此动作不计入排序码比较次数。
12
输出12,调整胜者树
排序码比较
次数=3。
18
12
16*
18
12
16*
28
16
18
12
18
6
20
16*
10
28
30
16
2
12
排序码比较次数=3。
某对象输出后,对手自动升到双亲,不计入排序码比较次数。
输出16,调整胜者树
16
排序码比较
次数=2。
16
18
16
18
16*
28
16
18
12
16*
6
20
16*
10
28
30
16
2
12
18
16*
输出16*,调整胜者树
16*
18
排序码比较
次数=2。
16*
30
18
18
16*
12
30
28
6
20
16*
10
28
30
16
2
12
18
18
输出18,调整胜者树
排序码比较
次数=3。
20
18
20
30
18
20
30
18
12
28
18
20
16*
10
28
30
16
2
12
6
20
20
排序码比较
次数=0。
20
18
30
20
18
12
30
18
输出20,调整胜者树
28
6
20
16*
10
28
30
16
2
12
18
28
输出28,调整胜者树
28
排序码比较
次数=2。
18
28
18
30
20
28
30
18
12
20
6
16*
10
28
30
16
2
12
18
30
输出30,排序完成
30
排序码比较
次数=0。
18
28
18
30
20
18
28
30
12
18
20
16*
10
28
30
16
2
12
6
(7)堆排序
第一步,形成初始的最大堆(略),第二步,做堆排序。
6
30
12
16
28
16
28
16
2
16*
18
20
10
18
16*
10
20
16*
10
28
30
30
12
2
2
12
6
18
6
20
初始排列,不是最大堆形成初始最大堆交换0#与9#对象
20
28
28
18
16
20
16
16
20
6
10
12
16*
18
18
16*
12
10
10
12
16*
30
28
2
6
30
2
30
6
2
从0#到8#重新形成堆交换0#与8#对象从0#到7#重新形成堆
16*
28
28
2
12
16
16
12
16
18
18
2
2
16*
10
10
6
6
12
10
16*
6
18
30
20
30
20
28
20
30
交换0#与7#对象从0#到6#重新形成堆交换0#与6#对象
16
16*
10
10
12
16
12
12
16
6
18
16*
2
16*
18
18
6
2
6
2
10
30
28
20
28
20
30
28
20
30
从0#到5#重新形成堆交换0#与5#对象从0#到4#重新形成堆
2
12
6
6
10
6
10
10
12
12
18
16
16*
16
16*
18
2
16
18
2
16*
28
20
30
28
20
30
28
30
20
交换0#与4#对象从0#到3#重新形成堆交换0#与3#对象
6
2
10
10
2
6
10
2
6
18
16
12
16*
16*
12
16
18
12
18
16*
16
28
20
30
28
20
30
30
28
20
从0#到2#重新形成堆交换0#与2#对象从0#到1#重新形成堆
2
2
6
10
10
6
16*
16
12
18
18
16
12
16*
28
20
30
30
20
28
交换0#与1#对象从0#到1#重新形成堆,得到结果
(8)二路归并排序
采用迭代的方法进行归并排序。
设待排序的数据对象有n个。
首先把每一个待排序的数据对象看作是长度为的初始归并项,然后进行两两归并,形成长度为2的归并项,再对它们两两归并,形成长度为4的归并项,如此一趟一趟做下去,最后得到长度为n的归并结果。
排序码比较5次
18
20
16*
2
16
30
28
10
6
12
618
16*2012
1028
1630
212
排序码比较6次
618
1016*2028
2121630
排序码比较7次
排序码比较9次
210121616*202830
618
2610121616*18202830
(9)基数排序
6
2
16
30
10
28
16*
20
18
12
按最低位分配
r[0]r[1]r[2]r[3]r[4]r[5]r[6]r[7]r[8]r[9]
6
20
2
18
16*
10
28
16
30
12
f[0]f[1]f[2]f[3]f[4]f[5]f[6]f[7]f[8]f[9]
28
6
2
10
18
16*
16
12
20
30
收集
按最高位分配
18
r[0]r[1]r[2]r[3]r[4]r[5]r[6]r[7]r[8]r[9]
16*
16
28
6
f[0]f[1]f[2]f[3]f[4]f[5]f[6]f[7]f[8]f[9]
12
30
20
2
10
30
28
20
18
16
10
12
6
2
16*
收集
9-3在起泡排序过程中,什么情况下排序码会朝向与排序相反的方向移动,试举例说明。
在快速排序过程中有这种现象吗?
【解答】
如果在待排序序列的后面的若干排序码比前面的排序码小,则在起泡排序的过程中,排序码可能向与最终它应移向的位置相反的方向移动。
例如,
574038111334487561997如9向相反方向移动
657403811133448757199如19向相反方向移动
675740381113344875919如9向最终方向移动
679574038111334487519如13向相反方向移动
6791157403813193