排序技术综合应用.docx

上传人:b****5 文档编号:7417610 上传时间:2023-01-23 格式:DOCX 页数:15 大小:103.15KB
下载 相关 举报
排序技术综合应用.docx_第1页
第1页 / 共15页
排序技术综合应用.docx_第2页
第2页 / 共15页
排序技术综合应用.docx_第3页
第3页 / 共15页
排序技术综合应用.docx_第4页
第4页 / 共15页
排序技术综合应用.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

排序技术综合应用.docx

《排序技术综合应用.docx》由会员分享,可在线阅读,更多相关《排序技术综合应用.docx(15页珍藏版)》请在冰豆网上搜索。

排序技术综合应用.docx

排序技术综合应用

《算法与数据结构》实验报告

(一)实验题目:

排序技术综合应用

1、实验目的:

(1)熟练掌握常用的排序方法,并掌握用高级语言实现排序算法的方法;

(2)深刻理解排序的定义和各种排序方法的特点,并能加以灵活应用;

(3)了解各种方法的排序过程及其依据的原则,并掌握各种排序方法的时间复杂度的分析方法。

2、实验内容:

对希尔排序、快速排序、归并排序任意选择两种排序方法进行比较。

任意选择希尔排序、快速排序、归并排序中两种排序方法,对任意给定一组数据:

单增、单减、乱码等,对它们进行比较分析。

3、实验说明:

希尔排序算法如下:

voidShellSort(intr[],intn)

{

for(d=n/2;d>=1;d=d/2)//以增量为d进行直接插入排序

{

for(i=d+1;i<=n;i++)

{

r[0]=r[i];//暂存被插入记录

for(j=i-d;j>0&&r[0]

r[j+d]=r[j];//记录后移d个位置

r[j+d]=r[0];

}

}

}

 

voidQuickSort(intr[],intfirst,intend)

{

if(first

pivot=Partition(r,first,end);//一次划分

QuickSort(r,first,pivot-1);//递归地对左侧子序列进行快速排序

QuickSort(r,pivot+1,end);//递归地对右侧子序列进行快速排序

}

}

intPartition(intr[],intfirst,intend)

{

i=first;j=end;//初始化

while(i

{

while(i

if(i

r[i]←→r[j];//将较小记录交换到前面

i++;

}

while(i

if(i

r[j]←→r[i];//将较大记录交换到后面

j--;

}

}

retutni;//i为轴值记录的最终位置

}

 

快速排序算法如下:

 

voidQuickSort(intr[],intfirst,intend)

{

if(first

pivot=Partition(r,first,end);//一次划分

QuickSort(r,first,pivot-1);//递归地对左侧子序列进行快速排序

QuickSort(r,pivot+1,end);//递归地对右侧子序列进行快速排序

}

}

intPartition(intr[],intfirst,intend)

{

i=first;j=end;//初始化

while(i

{

while(i

if(i

r[i]←→r[j];//将较小记录交换到前面

i++;

}

while(i

if(i

r[j]←→r[i];//将较大记录交换到后面

j--;

}

}

retutni;//i为轴值记录的最终位置

}

 

设计分析:

希尔排序

输入:

数组名称(也就是数组首地址)、数组中元素个数

算法思想简单描述:

在直接插入排序算法中,每次插入一个数,使有序序列只增加1个节点,并对插入下一个数没有提供任何帮助。

如果比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。

D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。

算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。

当增量减到1时,整个要排序的数被分成一组,排序完成。

 

下面的函数是一个希尔排序算法的一个实现,初次取序列的一半为增量,以后每次减半,直到增量为1。

希尔排序是不稳定的。

快速排序

输入:

数组名称(也就是数组首地址)、数组中起止元素的下标

算法思想简单描述:

快速排序是对冒泡排序的一种本质改进。

它的基本思想是通过一趟

扫描后,使得排序序列的长度能大幅度地减少。

在冒泡排序中,一次

扫描只能确保最大数值的数移到正确位置,而待排序序列的长度可能只

减少1。

快速排序通过一趟扫描,就能确保某个数(以它为基准点吧)

的左边各数都比它小,右边各数都比它大。

然后又用同样的方法处理

它左右两边的数,直到基准点的左右只有一个元素为止。

它是由

C.A.R.Hoare于1962年提出的。

显然快速排序可以用递归实现,当然也可以用栈化解递归实现。

下面的函数是用递归实现的,有兴趣的朋友可以改成非递归的。

快速排序是不稳定的。

最理想情况算法时间复杂度O(nlog2n),最坏O(n^2)--[n的平方]

 

源程序代码:

希尔排序

#include

usingnamespacestd;

#defineMax20

typedefintkeytype;

structretype{

keytypekey;

charch;

};

structsqlist{

retyper[Max+1];

intlen;

};

 

//初始化数据

voidcreatsqlist(sqlist&L,intn)

{

inti=1;

L.len=0;

if(n>Max||n<0)

exit(0);

cout<<"请输入数据:

"<

for(i;i<=n;i++)

{

cout<<"请输入第个"<

cout<<"请输入字符:

"<

cin>>L.r[i].ch;

cout<<"输入的数据如下:

"<

cin>>L.r[i].key;

L.len++;

}

}

//输出数据

voidoutputsqlist(sqlistL)

{

inti=1;

for(i;i<=L.len;i++)

{

cout<<"数据:

"<

cout<<"字符="<

}

}

//希尔排序

voidshellinsert(sqlist&L,intd);//对顺序表L进行一次希尔插入排序

voidshellsort(sqlist&L)

{

intd=L.len/2;

while(d!

=0)

{

shellinsert(L,d);

d=d/2;

}

}

voidshellinsert(sqlist&L,intd)

{

inti=d+1;

for(i;i<=L.len;++i)

{

if(L.r[i].key

{

L.r[0]=L.r[i];

//L.r[0].ch=L.r[i].ch;

//L.r[0].key=L.r[i].key;

intj=i-d;

for(j;(j>0)&&(L.r[0].key

{

L.r[j+d]=L.r[j];

//L.r[j+d].ch=L.r[j].ch;

//L.r[j+d].key=L.r[j].key;

}

L.r[j+d]=L.r[0];

//L.r[j+d].ch=L.r[0].ch;

//L.r[j+d].key=L.r[0].key;

}

}

}

 

intpartition(sqlist&L,intlow,inthigh)

{

L.r[0]=L.r[low];//用区间第low个记录作枢轴记录

keytypepivokey=L.r[low].key;//取枢轴记录关键字

while(low

{

while((low=pivokey))

--high;//从左向右扫描

L.r[low]=L.r[high];//比枢轴小的记录移到左端

while((low

++low;//从右向左扫描

L.r[high]=L.r[low];//比枢轴记录大的移到右端

}

L.r[low]=L.r[0];//枢轴记录到位

returnlow;//返回枢轴位置

}

voidmain()

{

sqlistL;

intn;

cout<<"请输入顺序表的长度(大于0):

"<

cin>>n;

creatsqlist(L,n);

cout<<"排序前输出数据:

"<

outputsqlist(L);

shellsort(L);

cout<<"排序后输出数据:

"<

outputsqlist(L);

}

快速排序

#include

usingnamespacestd;

#defineMax20

typedefintkeytype;

structretype{

keytypekey;

charch;

};

structsqlist{

retyper[Max+1];

intlen;

};

 

//初始化数据

voidcreatsqlist(sqlist&L,intn)

{

inti=1;

L.len=0;

if(n>Max||n<0)

exit(0);

cout<<"请输入数据:

"<

for(i;i<=n;i++)

{

cout<<"请输入第个"<

cout<<"请输入字符:

"<

cin>>L.r[i].ch;

cout<<"输入的数据如下:

"<

cin>>L.r[i].key;

L.len++;

}

}

//输出数据

voidoutputsqlist(sqlistL)

{

inti=1;

for(i;i<=L.len;i++)

{

cout<<"数据:

"<

cout<<"字符="<

}

}

voidqsort(sqlist&L,intlow,inthigh);//顺序表L的子序列L.r[low..high]进行快速排序

intpartition(sqlist&L,intlow,inthigh);//交换顺序表L的子序列L.r[low..high]的记录

voidquiksort(sqlist&L)

{

qsort(L,1,L.len);//排序整个文件记录

}

voidqsort(sqlist&L,intlow,inthigh)

{

if(low

{

intpivotpos=partition(L,low,high);//pivotpos曲轴位置

qsort(L,low,pivotpos-1);//对左区间递归排序

qsort(L,pivotpos+1,high);//对右区间递归排序

}

}

 

intpartition(sqlist&L,intlow,inthigh)

{

L.r[0]=L.r[low];//用区间第low个记录作枢轴记录

keytypepivokey=L.r[low].key;//取枢轴记录关键字

while(low

{

while((low=pivokey))

--high;//从左向右扫描

L.r[low]=L.r[high];//比枢轴小的记录移到左端

while((low

++low;//从右向左扫描

L.r[high]=L.r[low];//比枢轴记录大的移到右端

}

L.r[low]=L.r[0];//枢轴记录到位

returnlow;//返回枢轴位置

}

voidmain()

{

sqlistL;

intn;

cout<<"请输入顺序表的长度(大于0):

"<

cin>>n;

creatsqlist(L,n);

cout<<"排序前输出数据:

"<

outputsqlist(L);

cout<<"排序后输出数据:

"<

outputsqlist(L);

}

 

测试用例

希尔排序

 

快速排序

实验总结

通过这次的实验,我掌握了几种常用的排序方法,并掌握用高级语言实现排序算法的方法;深刻理解排序的定义和各种排序方法的特点,并能加以灵活应用;了解各种方法的排序过程及其依据的原则,并掌握各种排序方法的时间复杂度的分析方法。

通过这次的实验,我认识到仅仅掌握课本上的知识是不够的,在实际操作时,常常遇到一些问题,自己看不懂,更无法解决。

要经过不断的思考,尝试着去更改代码中出现的问题。

虽然开始很困难,但在同学的帮助下,我逐渐的熟悉了许多操作,为后继工作的顺利进行做了准备。

个人的力量是薄弱的,在过程中和同学相互讨论,不断进步。

也许,我们可以说,编一个程仅仅是开始,调试和运行相比之下更难。

实践中收获的远比想象的多。

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

当前位置:首页 > 高等教育 > 理学

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

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