《数据结构》内部排序12种算法上机实验报告.docx

上传人:b****5 文档编号:11639410 上传时间:2023-03-29 格式:DOCX 页数:19 大小:207.99KB
下载 相关 举报
《数据结构》内部排序12种算法上机实验报告.docx_第1页
第1页 / 共19页
《数据结构》内部排序12种算法上机实验报告.docx_第2页
第2页 / 共19页
《数据结构》内部排序12种算法上机实验报告.docx_第3页
第3页 / 共19页
《数据结构》内部排序12种算法上机实验报告.docx_第4页
第4页 / 共19页
《数据结构》内部排序12种算法上机实验报告.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

《数据结构》内部排序12种算法上机实验报告.docx

《《数据结构》内部排序12种算法上机实验报告.docx》由会员分享,可在线阅读,更多相关《《数据结构》内部排序12种算法上机实验报告.docx(19页珍藏版)》请在冰豆网上搜索。

《数据结构》内部排序12种算法上机实验报告.docx

《数据结构》内部排序12种算法上机实验报告

成都信息工程学院计算机系

 

实验课程:

数据结构

实验项目:

实现算法的全排序

指导教师:

学生姓名:

学生学号:

班级:

计算机工程1班

实验地点:

6305

实验时间:

2012年12月2日—12月19日

实验成绩:

评阅老师:

(说明:

实验报告必须包含下面的每项内容,根据实验情况认真填写,封面必须打印或复印(A4纸),书写上机实验报告内容的纸张也用A4纸,最后从侧面装订)

一【上机实验目的】

目的:

从键盘输入一组数,通过内部排序的12种算法对这组数字进行排序。

熟练掌握刚刚学过的内部排序的算法,并对这12种排序算法的时间复杂度进行比较,根据不同的情况,选择合适的算法

二【实验环境】

PC机每人1台

三【上机实验内容】

实现内部排序的12种排序算法的全排序。

四【上机调试程序流程图】(注:

可打印)

(用传统流程图的形式表示)

五【上机调试中出现的错误信息、错误原因及解决办法】

(记录下你调试程序中出现的错误信息的英文提示,分析出错原因及可能的解决办法)

六【上机调试后的源程序及还存在的问题】(注:

源程序可打印)

(同时记录下你对你编写此程序的其它具体想法,)

主要的程序:

/********************************直接插入排序***************************/

voidInsertSort(SqList&L)

{//直接插入排序

inti,j;

for(i=2;i<=L.length;++i)

{

if(L.r[i].key<=L.r[i-1].key)

{

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

L.r[i]=L.r[i-1];

for(j=i-2;(L.r[0].key

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

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

}

}

}

/*********************************折半插入排序************************/

voidBinsertSort(SqList&L)

{//折半插入排序

inti,j,low,high,m;

for(i=2;i<=L.length;i++)

{

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

low=1;

high=i-1;

while(low<=high)

{

m=(low+high)/2;

if(L.r[0].key

high=m-1;

else

low=m+1;

}

for(j=i-1;j>=high+1;--j)

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

L.r[high+1]=L.r[0];

}

}

/**********************************2-路插入排序***********************/

voidP2_InsertSort(SqList&L)

{//2—路插入排序

inti,j,first,final;

RedType*d;

d=(RedType*)malloc(L.length*sizeof(RedType));//生成L.length个记录的临时空间

d[0]=L.r[1];

first=final=0;//first、final分别指示d中排好序的记录的第1个和最后1个记录的位置

for(i=2;i<=L.length;++i)

{//依次将L的第2个~最后1个记录插入d中

if(L.r[i].key

{//待插记录小于d中最小值,插到d[first]之前(不需移动d数组的元素)

first=(first-1+L.length)%L.length;//设d为循环向量

d[first]=L.r[i];

}

elseif(L.r[i].key>d[final].key)

{//待插记录大于d中最大值,插到d[final]之后(不需移动d数组的元素)

final=final+1;

d[final]=L.r[i];

}

else

{//待插记录大于d中最小值,小于d中最大值,插到d的中间(需要移动d数组的元素)

j=final++;//移动d的尾部元素以便按序插入记录

while(L.r[i].key

{

d[(j+1)%L.length]=d[j];

j=(j-1+L.length)%L.length;

}

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

}

}

for(i=1;i<=L.length;i++)//把d赋给L.r

L.r[i]=d[(i+first-1)%L.length];//线性关系

}

/***************************************希尔排序***************************/

voidShellInsert(SqList&L,intdk)

{

//printf("OK");

inti,j;

for(i=dk+1;i<=L.length;i++)

if(L.r[i].key

{

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

for(j=i-dk;j>0&&(L.r[0].key

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

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

}

}

voidShellSort(SqList&L,intdlta[],intt)

{

//printf("OK");

intk;

for(k=0;k

ShellInsert(L,dlta[k]);

//display(L);

}

/***********************************表插入排序***********************/

voidTableInsert(SLinkListType&SL,RedTypeD[]){

//由数组D建立的n个元素的表插入排序的静态链表SL

inti,p,q;

SL.r[0].rc.key=INT_MAX;//表头结点记录的关键字取得最大整数(非降序表的表尾)

SL.r[0].next=0;//next域为0表示表尾(现为空表,初始化)

for(i=0;i

SL.r[i+1].rc=D[i];//将数组D的值赋给静态链表SL

q=0;

p=SL.r[0].next;

while(SL.r[p].rc.key<=SL.r[i+1].rc.key){//静态链表后移

q=p;

p=SL.r[p].next;

}

SL.r[i+1].next=p;

SL.r[q].next=i+1;//将当前记录插入到静态链表

}

SL.length=MAXSIZE;

}

voidArrange(SLinkListType&SL)

{

//根据静态链表SL中各结点的指针值调整记录位置,使得SL中记录按关键字非递减有序排列

inti,p,q;

SLNodet;

p=SL.r[0].next;//p指示第一个记录的当前位置

printf("%d",SL.length);

for(i=1;i

{

//SL.r[i...i-1]中记录已按关键字有序排列,第i个记录在SL中的当前记录不应小于i

while(p

p=SL.r[p].next;//找到第i个记录,并用p指示其在SL中当前位置

q=SL.r[p].next;//q指示当前未调整的表尾

if(p!

=i){

t=SL.r[p];//交换记录,使第i个记录到位

SL.r[p]=SL.r[i];

SL.r[i]=t;

SL.r[i].next=p;//指向被移走的记录,使得以后可由while循环找回

}

p=q;//p指示未调整的表尾,为找到第i+1个记录作准备

//print(SL);

//printf("\n");

}

}

/*************************************冒泡排序***********************/

voidbubble_sort(SqList&L)

{//冒泡排序

inti;

intk;

RedTypetem;

for(i=L.length-1,k=1;i>=1&&k;--i)

{

k=0;

for(intj=1;j<=i;++j)

{

if(L.r[j].key>L.r[j+1].key)

{

tem=L.r[j];

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

L.r[j+1]=tem;

k=1;

}

}

}

}

/************************************快速排序**************************/

intPartition(SqList&L,intlow,inthigh)

{//快速排序递归函数的实现

intpivotkey;

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

pivotkey=L.r[low].key;

while(low

{

while(low=pivotkey)

--high;

L.r[low]=L.r[high];

while(low

++low;

L.r[high]=L.r[low];

}

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

returnlow;

}

/********************************简单选择排序***********************/

intSelectMinKey(SqList&L,inti)

{

intj,k=i;

for(j=i+1;j

{

if(L.r[k].key>L.r[j].key)

k=j;

}

returnk;

}

voidSelect_Sort(SqList&L)

{

inti,j;

RedTypetem;

for(i=1;i

{

j=SelectMinKey(L,i);

if(i!

=j)

{

tem=L.r[i];

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

L.r[j]=tem;

}

}

}

/**************************************堆排序*************************/

voidHeapAdjust(HeadType&L,ints,intm)

{//对生成的堆进行排序,生成大顶堆

RedTyperc;

rc=L.r[s];

intj;

for(j=2*s;j<=m;j*=2)

{

if(j

j++;

if(rc.key>=L.r[j].key)

break;

L.r[s]=L.r[j];

s=j;

}

L.r[s]=rc;

}

voidHeadSort(HeadType&L)

{//对一组无序的数字进行排序生成堆

inti;

RedTypetemp;

for(i=L.length/2;i>0;--i)

HeapAdjust(L,i,L.length);

for(i=L.length;i>1;--i)

{

temp=L.r[1];

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

L.r[i]=temp;

HeapAdjust(L,1,i-1);

}

}

/**************************************归并排序***************************/

voidMerge(RedTypeSR[],RedTypeTR[],ints,intm,intt)

{//printf("+_+_+_+_+_+_");

inti,j,k;

//RcdType*tem;

for(j=m+1,k=s,i=s;i<=m&&j<=t;k++)

{

if(SR[i].key

TR[k]=SR[i++];

else

TR[k]=SR[j++];

}

while(i<=m)

{

//for(l=0;l

TR[k++]=SR[i++];

}

while(j<=t)

{

//for(l=0;l

TR[k++]=SR[j++];

}

}

voidMSort(RedTypeSR[],RedTypeTR1[],ints,intt)

{

intm;

RedTypeTR2[MAXSIZE+1];

if(s==t)

TR1[s]=SR[s];

else

{

m=(s+t)/2;

MSort(SR,TR2,s,m);

MSort(SR,TR2,m+1,t);

Merge(TR2,TR1,s,m,t);

}

}

voidMergeSort(SqList&L)

{

MSort(L.r,L.r,1,L.length);

}

/************************************基数排序*************************/

oidInitList(SLList&L,RedTypeD[],intn)//初始化静态链表L(把数组D中的数据存于L中)

{

charc[MAX_NUM_OF_KEY],c1[MAX_NUM_OF_KEY];

inti,j,max=D[0].key;//max为关键字的最大值

for(i=1;i

if(max

max=D[i].key;

L.keynum=int(ceil(log10(max)));

L.recnum=n;

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

{

L.r[i].otheritems=D[i-1].otherinfo;

itoa(D[i-1].key,c,10);//将10进制整型转化为字符型,存入c

for(j=strlen(c);j

{

strcpy(c1,"0");

strcat(c1,c);

strcpy(c,c1);

}

for(j=0;j

}

}

voidDistribute(SLCellr[],inti,ArrTypef,ArrTypee)//算法10.15

{//静态键表L的r域中记录已按(keys[0],…,keys[i-1])有序。

本算法按

//第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。

//f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录

intj,p;

for(j=0;j

for(p=r[0].next;p;p=r[p].next)

{

j=r[p].keys[i]-'0';//将记录中第i个关键字映射到[0..RADIX-1]

if(!

f[j])

f[j]=p;

else

r[e[j]].next=p;

e[j]=p;//将p所指的结点插入第j个子表中

}

}

voidCollect(SLCellr[],ArrTypef,ArrTypee)//算法10.16

//本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成

//一个链表,e[0..RADIX-1]为各子表的尾指针。

{intj,t;

for(j=0;!

f[j];j=++j);//找第一个非空子表

r[0].next=f[j];

t=e[j];//r[0].next指向第一个非空子表中第一个结点

while(j

{for(j=++j;j

f[j];j=++j);//找下一个非空子表

if(f[j])//链接两个非空子表

{r[t].next=f[j];

t=e[j];

}

}

r[t].next=0;//t指向最后一个非空子表中的最后一个结点

}

voidprintl(SLListL)//按链表输出静态链表

{inti=L.r[0].next,j;

while(i)

{for(j=L.keynum-1;j>=0;j--)printf("%c",L.r[i].keys[j]);

printf("");

i=L.r[i].next;

}

}

voidRadixSort(SLList&L)//算法10.17

//L是采用静态链表表示的顺序表。

对L作基数排序,使得L成为按关键字

//自小到大的有序静态链表,L.r[0]为头结点。

{inti;

ArrTypef,e;

for(i=0;i

L.r[L.recnum].next=0;//将L改造为静态链表

for(i=0;i

{Distribute(L.r,i,f,e);//第i趟分配

Collect(L.r,f,e);//第i趟收集

printf("第%d趟收集后:

\n",i+1);

printl(L);

printf("\n");

}

}

voidprint(SLListL)//按数组序号输出静态链表

{inti,j;

printf("keynum=%drecnum=%d\n",L.keynum,L.recnum);

for(i=1;i<=L.recnum;i++)

{printf("keys=");

for(j=L.keynum-1;j>=0;j--)printf("%c",L.r[i].keys[j]);

printf("otheritems=%dnext=%d\n",L.r[i].otheritems,L.r[i].next);

}

}

voidSort(SLListL,intadr[])//改此句(类型)

//求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号

{inti=1,p=L.r[0].next;

while(p)

{adr[i++]=p;

p=L.r[p].next;

}

}

voidRearrange(SLList&L,intadr[])//改此句(类型)

//adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。

//本算法按adr重排L.r,使其有序。

算法10.18(L的类型有变)

{inti,j,k;

for(i=1;i

if(adr[i]!

=i)

{j=i;

L.r[0]=L.r[i];//暂存记录L.r[i]

while(adr[j]!

=i)//调整L.r[adr[j]]的记录到位直到adr[j]=i为止

{k=adr[j];

L.r[j]=L.r[k];

adr[j]=j;

j=k;//记录按序到位

}

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

adr[j]=j;

}

}

运行效果图:

七【上机实验中的其他它问题及心得】

(在上机实验中遇到的你不能解决的其它问题,简单描述一下你此次上机的收获及感想)

心得:

排序时计算机程序设计中的一种重要的操作,因为我们无论做什么样的程序都会涉及到排序算法,在第十章的内部排序算法中,基本上都是一些经典的排序算法,这是我选择这个题目的主要原因,因为通过这个综合设计,我可以了解不同的排序算法,根据不同的情况,选择更好的算法。

在本章中共有12种算法:

插入排序5种,选择排序3种,快速排序2种,归并排序和基数排序。

在没有接触本章之前,我们只是接触了简单的冒泡排序和选择排序,这些只是对数n不是很大的情况,当n值很大时,我们果继续使用这些简单的算法,时间复杂度会很大的。

因此,在本章中介绍的这些算法,适合我们遇到的任何情况,不能够说那种算法是好的,不同的算法都有好坏,我们可以根据不同的情况,从这些算法中选择合适的算法。

每一种排序都有最好的情况和最坏的情况。

1.从平均时间性能而言,快速排序是最好的,因为其所用的时间是最少的。

但是,如果想到最坏的情况,当然就要考虑到堆排序和归并排序。

堆排序对n值较大时是比较有效的,因为堆排序主要的耗时是在建初始堆和调整建新堆时进行的反复的“筛选”。

当n值很大时,归并排序所需时间较堆排序省,但是归并排序所需要的辅助空间较多。

入过在输入一行数字是,这些数字是基本有序的,为了节省时间和空间,可以选择冒泡排序和简单选择排序。

从方法的稳定性来说:

基数排序时稳定的内部排序算法,所有时间复杂度为O(n^2)的简单排序法也是稳定的,但是,快速排序、堆排序和希尔排序等时间较好的排序方法都是不稳定的。

一般来说,排序过程中的“比较“是在“相邻两个关键字”间进行的排序方法是稳定的。

因此,在所有的算法当中,没有哪一种算法是绝对最优的。

有的适用于n较大时,有的适合n的有序情况,有

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

当前位置:首页 > 求职职场 > 简历

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

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