排序冒泡选择堆归并.docx

上传人:b****8 文档编号:9816930 上传时间:2023-02-06 格式:DOCX 页数:15 大小:265.85KB
下载 相关 举报
排序冒泡选择堆归并.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

排序冒泡选择堆归并

课程名称:

数据结构开课实验室:

计算中心204室2011年12月日

年级、专业、班

学号

姓名

成绩

实验项目名称

实现排序、冒泡、选择、堆、归并的算法

指导教师

教师

评语

 

教师签名:

年月日

1、实验内容和目的

目的:

实现排序、冒泡、选择、堆、归并的算法。

内容:

撑握排序、冒泡、选择、堆、归并的算法和使用,熟悉并学会运用排序、冒泡、选择、堆、归并的算法内容和相互间的转变等。

二、上机实验环境

计算中心204;操作系统:

MicrosoftVisualC++;软件平台:

MicrosoftVisualC++

三、上机操作方法、步骤

打开计算机进入WindowsXP→在桌面建立自己的工作目录→进入MicrosoftVisualC++6.0→文件/新建/文件/C++SourceFile/位置/命名→输入源程序→编译/组建→运行。

#include

#include

#defineMax100//假设文件长度

typedefstruct{//定义记录类型

intkey;

}RecType;

typedefRecTypeSeqList[Max+1];//SeqList为顺序表,表中第0个元素作为哨兵

intn;//顺序表实际的长度

intmenu();

//-----------------------------------------------------------------------------------------

voidInsertSort(SeqListR)//直接插入排序法

{//对顺序表R中的记录R[1‥n]按递增序进行插入排序

inti,j;

for(i=2;i<=n;i++)//依次插入R[2],……,R[n]

if(R[i].key

R[0]=R[i];j=i-1;//R[0]是R[i]的副本

do

{//从右向左在有序区R[1‥i-1]中查找R[i]的位置

R[j+1]=R[j];//将关键字大于R[i].key的记录后移

j--;

}

while(R[0].key

R[j+1]=R[0];//R[i]插入到正确的位置上

}//endif

}

//------------------------------------------------------------------------------------------

intPartition(SeqListR,inti,intj)//一次划分函数

{//对R[i‥j]做一次划分,并返回基准记录的位置

RecTypepivot=R[i];//用第一个记录作为基准

while(i

while(i=pivot.key)//基准记录pivot相当与在位置i上

j--;//从右向左扫描,查找第一个关键字小于pivot.key的记录R[j]

if(i

R[i++]=R[j];//交换R[i]和R[j],交换后i指针加1

while(i

i++;//从左向右扫描,查找第一个关键字小于pivot.key的记录R[i]

if(ipivot.key,则

R[j--]=R[i];//交换R[i]和R[j],交换后j指针减1

}

R[i]=pivot;//此时,i=j,基准记录已被最后定位

returni;//返回基准记录的位置

}

//--------------------------------------------------------------------------------------------

voidQuickSort(SeqListR,intlow,inthigh)//快速排序

{//R[low..high]快速排序

intpivotpos;//划分后基准记录的位置

if(low

pivotpos=Partition(R,low,high);//对R[low..high]做一次划分,得到基准记录的位置

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

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

}

}

//--------------------------------------------------------------------------------------------

voidSelectSort(SeqListR)//直接选择排序

{

inti,j,k;

for(i=1;i

k=i;

for(j=i+1;j<=n;j++)//在当前无序区R[i‥n]中选key最小的记录R[k]

if(R[j].key

k=j;//k记下目前找到的最小关键字所在的位置

if(k!

=i){////交换R[i]和R[k]

R[0]=R[i];

R[i]=R[k];

R[k]=R[0];

}

}

}

//------------冒泡排序------------------------------------------------------------------------

typedefenum{FALSE,TRUE}Boolean;//FALSE为0,TRUE为1

voidBubbleSort(SeqListR){//自下向上扫描对R做冒泡排序

inti,j;Booleanexchange;//交换标志

for(i=1;i

exchange=FALSE;//本趟排序开始前,交换标志应为假

for(j=n-1;j>=i;j--)//对当前无序区R[i‥n]自下向上扫描

if(R[j+1].key

R[0]=R[j+1];//R[0]不是哨兵,仅做暂存单元

R[j+1]=R[j];

R[j]=R[0];

exchange=TRUE;//发生了交换,故将交换标志置为真

}

if(!

exchange)//本趟排序未发生交换,提前终止算法

return;

}//endfor(为循环)

}

//----------------------------------------------------------------------------------------------------

voidHeapify(SeqListR,intlow,inthigh)//大根堆调整函数

{//将R[low..high]调整为大根堆,除R[low]外,其余结点均满足堆性质

intlarge;//large指向调整结点的左、右孩子结点中关键字较大者

RecTypetemp=R[low];//暂存调整结点

for(large=2*low;large<=high;large*=2){//R[low]是当前调整结点

//若large>high,则表示R[low]是叶子,调整结束;否则先令large指向R[low]的左孩子

if(large

large++;//若R[low]的右孩子存在且关键字大于左兄弟,则令large指向它

//现在R[large]是调整结点R[low]的左右孩子结点中关键字较大者

if(temp.key>=R[large].key)//temp始终对应R[low]

break;//当前调整结点不小于其孩子结点的关键字,结束调整

R[low]=R[large];//相当于交换了R[low]和R[large]

low=large;//令low指向新的调整结点,相当于temp已筛下到large的位置

}

R[low]=temp;//将被调整结点放入最终位置上

}

//构造大根堆

voidBuildHeap(SeqListR)

{//将初始文件R[1..n]构造为堆

inti;

for(i=n/2;i>0;i--)

Heapify(R,i,n);//将R[i..n]调整为大根堆

}

//堆排序

voidHeapSort(SeqListR)

{//对R[1..n]进行堆排序,不妨用R[0]做暂存单元

inti;

BuildHeap(R);//将R[1..n]构造为初始大根堆

for(i=n;i>1;i--){//对当前无序区R[1..i]进行堆排序,共做n-1趟。

R[0]=R[1];R[1]=R[i];R[i]=R[0];//将堆顶和堆中最后一个记录交换

Heapify(R,1,i-1);//将R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质。

}

}

//--------------------------------------------------------------------------------------

//将两个有序的子序列R[low..m]和R[m+1..high]归并成有序的序列R[low..high]

voidMerge(SeqListR,intlow,intm,inthigh)

{

inti=low,j=m+1,p=0;//置初始值

RecType*R1;//R1为局部量

R1=(RecType*)malloc((high-low+1)*sizeof(RecType));//申请空间

while(i<=m&&j<=high)//两个子序列非空时取其小者输出到R1[p]上

R1[p++]=(R[i].key<=R[j].key)?

R[i++]:

R[j++];

while(i<=m)//若第一个子序列非空,则复制剩余记录到R1

R1[p++]=R[i++];

while(j<=high)//若第二个子序列非空,则复制剩余记录到R1中

R1[p++]=R[j++];

for(p=0,i=low;i<=high;p++,i++)

R[i]=R1[p];//归并完成后将结果复制回R[low..high]

}

//-----------------------------------------------------------------------------------

voidMergePass(SeqListR,intlength)//对R[1..n]做一趟归并排序

{

inti;

for(i=1;i+2*length-1<=n;i=i+2*length)

Merge(R,i,i+length-1,i+2*length-1);//归并长度为length的两个相邻的子序列

if(i+length-1

Merge(R,i,i+length-1,n);//归并最后两个子序列

//注意:

若i≤n且i+length-1≥n时,则剩余一个子序列轮空,无须归并

}

//-----------------------------------------------------------------------------------

voidMergeSort(SeqListR)//自底向上对R[1..n]做二路归并排序

{

intlength;

for(length=1;length

MergePass(R,length);//有序长度≥n时终止

}

//-----------------------------------------------------------------------------------

voidinput_int(SeqListR)//输入顺序表

{

inti;

printf("请输入个数(int):

");

scanf("%d",&n);

printf("请输入一组数据:

",n);

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

scanf("%d",&R[i].key);

}

//----------------------------------------------------------------------------------

voidoutput_int(SeqListR)//输出顺序表

{

inti;

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

printf("%4d",R[i].key);

printf("\n\n");

}

//---------------------------------------------------------------------------------

voidmain()//主函数

{

//inti;

SeqListR;

input_int(R);

while

(1){

system("cls");

inti=menu();

switch(i)

{

case1:

InsertSort(R);break;//值为1,直接插入排序

case2:

BubbleSort(R);break;//值为2,冒泡法排序

case3:

QuickSort(R,1,n);break;//值为3,快速排序

case4:

SelectSort(R);break;//值为4,直接选择排序

case5:

HeapSort(R);break;//值为5,堆排序

case6:

MergeSort(R);break;//值为6,归并排序

case7:

exit(0);break;//值为7,结束程序

}

printf("所选排序的结果:

");

printf("\n");

output_int(R);

if(i!

=7)

{

puts("\n\n操作成功!

");

system("pause");

}

}

}

//----------------------------------------------------

intmenu()

{

intn;

printf("\t----------选择操作----------\n");

printf("\t1:

直接插入排序\n");

printf("\t2:

冒泡法排序\n");

printf("\t3:

快速排序\n");

printf("\t4:

直接选择排序\n");

printf("\t5:

堆排序\n");

printf("\t6:

归并排序\n");

printf("\t7:

退出\n");

printf("\t-----------------------------\n");

fflush(stdin);

scanf("%d",&n);//输入整数1-7,选择排序方式

returnn;

}

四、源程序与运行结果:

<1>图为输入要排序的一组数据

<2>数据输完后,回车出现选择所要的排序法

<3>图为选择“直接插入排序法”

<4>图为选择“冒泡法排序法”

<5>图为选择“快速排序法”

<6>图为选择“直接选择排序法”

<7>图为选择“堆排序法”

<8>图为选择“归并排序法”

<9>图为程序成功退出

五、上机实践收获和体会:

这几次的上机实践课,让我知道计算机专业需要相当多的实践,而在实践中不但掌握计算机技术(包括程序设计),还要掌握许多其他专业并不“深究”的东西,例如,算法,体系结构,信息管理等等。

对于我这个初学者的知识基础较薄弱,对一些应用操作理解起来较为困难,要能从整体概念上较好地理解和把握应用软件,不是仅仅靠几本培训的书籍还买了几本有关专业的书籍,细致地看几遍,然后上机练习几次就可以成功。

本专的同学也都在说,学习编程的秘诀是:

编程,编程,再编程。

我今后会更努力的去学习这门课。

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

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

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

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