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-1Merge(R,i,i+length-1,n);//归并最后两个子序列
//注意:
若i≤n且i+length-1≥n时,则剩余一个子序列轮空,无须归并
}
//-----------------------------------------------------------------------------------
voidMergeSort(SeqListR)//自底向上对R[1..n]做二路归并排序
{
intlength;
for(length=1;lengthMergePass(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>图为程序成功退出
五、上机实践收获和体会:
这几次的上机实践课,让我知道计算机专业需要相当多的实践,而在实践中不但掌握计算机技术(包括程序设计),还要掌握许多其他专业并不“深究”的东西,例如,算法,体系结构,信息管理等等。
对于我这个初学者的知识基础较薄弱,对一些应用操作理解起来较为困难,要能从整体概念上较好地理解和把握应用软件,不是仅仅靠几本培训的书籍还买了几本有关专业的书籍,细致地看几遍,然后上机练习几次就可以成功。
本专的同学也都在说,学习编程的秘诀是:
编程,编程,再编程。
我今后会更努力的去学习这门课。