数据结构课程设计排序算法演示系统Word格式.docx
《数据结构课程设计排序算法演示系统Word格式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计排序算法演示系统Word格式.docx(41页珍藏版)》请在冰豆网上搜索。
![数据结构课程设计排序算法演示系统Word格式.docx](https://file1.bdocx.com/fileroot1/2022-12/31/559261c8-24b3-4134-8c74-ff1d149df973/559261c8-24b3-4134-8c74-ff1d149df9731.gif)
intkey;
}RecType;
四.
功能模块详细设计
4.1详细设计思想
主函数:
#include<
stdio.h>
stdlib.h>
#include<
math.h>
#defineL8//排序元素个数
#defineFALSE0
#defineTRUE1
RecTypeR[L];
intnum;
intsum;
intsun;
//定义排序趟数的全局变量
//系统主界面
//主函数
intmain()
RecTypeS[100];
inti,k;
charch1,ch2,q;
printf("
\n\t\t***********排序算法演示系统************\n\n\t\t请输入%d个待排序的数据:
\n"
L);
for(i=1;
i<
=L;
i++)
{
printf("
\t\t请输入第%dth数据:
"
i);
scanf("
%d"
&
S[i].key);
getchar();
}
ch1='
y'
;
while(ch1=='
)
{
\n\t\t菜单\n"
);
\n\t\t***********************************************\n"
\n\t\t*1--------更新排序数据*2--------直接插入排序\n"
\n\t\t*3--------希尔排序*4--------冒泡排序\n"
\n\t\t*5--------快速排序*6--------直接选择排序\n"
\n\t\t*7--------堆排序*8--------归并排序\n"
\n\t\t**********0--------退出************\n"
\n\t\t********************************************\n"
\n\t\t请选择:
%c"
ch2);
for(i=1;
{
R[i].key=S[i].key;
}
switch(ch2)
case'
1'
:
printf("
\n\t\t请输入%d个待排序数据\n\t\t"
for(i=1;
{
scanf("
getchar();
printf("
\t\t"
}
\n\t\t数据输入完毕!
break;
2'
Insertsort();
3'
Shellsort();
4'
Bubblesort();
5'
\n\t\t原始数据为(按回车键开始排序):
\n\t\t"
for(k=1;
k<
k++)
%5d"
R[k].key);
getchar();
num=0;
sun=0;
sum=0;
Quicksort(1,L);
\n\t\t排序最终结果是:
\n\t\t比较次数是:
%d\n\t\t"
sum);
\n\t\t交换次数是:
sun);
6'
Selectsort();
7'
Heap();
8'
Mergesort();
0'
ch1='
n'
default:
system("
cls"
//清屏
\n\t\t对不起,您输入有误,请重新输入!
if(ch2!
='
if(ch2=='
||ch2=='
\n\n\t\t排序完毕!
\n\t\t按回车键继续!
q=getchar();
if(q!
\n'
{
getchar();
ch1='
}
return1;
}
图一主界面
4.1.1冒泡排序
核心思想
依次比较相邻的两个数,将小数放在前面,大数放在后面,第一轮比较后,最大的数便被放到了最后;
第二轮操作前n-1个数据(假设有n个数据),依然是依次比较相邻的两个数,将小数放在前面,大数放在后面,倒数第二个数便是第二大的数;
同理第i轮操作前n-i+1的数据(假设i取值是从1开始的),则n-i+i位置上的数据为第i大的数据。
一共有n-1轮,第i轮比较中共比较n-i次比较。
核心代码
voidBubblesort()
inti,j,k,x=0,y=0,m=0;
intexchange=TRUE;
//标志位exchange初始化为TRUE1
for(k=1;
getchar();
L&
&
exchange==TRUE;
i++)//外层对总的循环次数执行次数
exchange=FALSE;
for(j=1;
j<
=L+1-i;
j++)//内层相邻记录的交换与比较
{m++;
//比较次数++
if(R[j].key<
R[j-1].key)
R[0].key=R[j].key;
R[j].key=R[j-1].key;
R[j-1].key=R[0].key;
exchange=TRUE;
y++;
//移动次数++
m--;
//比较次数
if(exchange)//输出语句
\t\t第%d趟冒泡排序的结果为:
{printf("
m);
\n\t\t移动次数是:
y);
{printf("
R[i].key);
图二直接插入排序
4.1.2快速排序
首先检查数据列表中的数据数,如果小于两个,则直接退出程序。
如果有超过两个以上的数据,就选择一个分割点将数据分成两个部分,小于分割点的数据放在一组,其余的放在另一组,然后分别对两组数据排序。
通常分割点的数据是随机选取的。
这样无论你的数据是否已被排列过,你所分割成的两个字列表的大小是差不多的。
而只要两个子列表的大小差不多
//递归算法实现
voidQuicksort(intlow,inthigh)
{
inti=low,j=high,k;
R[0].key=R[low].key;
while(i<
j)
while(i<
j&
R[0].key<
=R[j].key)//右侧扫描
{j--;
sum++;
if(i<
{R[i].key=R[j].key;
//交换
i++;
sun++;
R[i].key<
R[0].key)//左侧扫描
{i++;
R[j].key=R[i].key;
j--;
sun++;
R[i].key=R[0].key;
num++;
//输出语句包括排序的结果及次数
\t\t第%d趟快速排序的结果为:
num);
if(low<
i-1)Quicksort(low,i-1);
//递归部分(左侧)
if(j+1<
high)Quicksort(j+1,high);
//递归部分(右侧)
}
图三快速排序
4.1.3直接插入排序
经过i-1遍处理后,L[1..i-1]己排好序。
第i遍处理仅将L[i]插入L[1..i-1]的适当位置,使得L[1..i]又是排好序的序列。
要达到这个目的,我们可以用顺序比较的方法。
首先比较L[i]和L[i-1],如果L[i-1]≤L[i],则L[1..i]已排好序,第i遍处理就结束了;
否则交换L[i]与L[i-1]的位置,继续比较L[i-1]和L[i-2],直到找到某一个位置j(1≤j≤i-1),使得L[j]≤L[j+1]时为止
voidInsertsort()
inti,j,k,m=0,x=0;
//初始化比较次数变量m,移动次数变量x
\n\t\t原始数据为:
(按回车键开始排序)\n\t\t"
//主要运行部分
for(i=2;
if(R[i].key<
R[i-1].key)
R[0]=R[i];
j=i-1;
while(R[0].key<
R[j].key)
R[j+1]=R[j];
j--;
R[j+1]=R[0];
x++;
m++;
//输出语句包括排序的结果及次数
\t\t第%d趟直接插入排序的结果为:
for(k=1;
{printf("
x);
图四直接插入排序
4.1.4希尔排序
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。
所有距离为dl的倍数的记录放在同一个组中。
先在各组内进行直接插入排序;
然后,取第二个增量d2<
d1重复上述的分组和排序,直至所取的增量dt=1(dt<
dt-l<
…<
d2<
d1),即所有记录放在同一组中进行直接插入排序为止。
voidShellsort()
inti,j,gap,x,k,y=0,m=0;
//初始化比较次数变量m,移动次数变量y
//函数主要部分
gap=L/2;
while(gap>
0)
for(i=gap+1;
j=i-gap;
while(j>
if(R[j].key>
R[j+gap].key)
x=R[j].key;
//交换语句
R[j].key=R[j+gap].key;
R[j+gap].key=x;
j=j-gap;
y++;
else
j=0;
gap=gap/2;
\t\t第%d趟希尔排序的结果为:
图五希尔排序
4.1.5直接选择排序
第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R{1}~R[n-1]中选取最小值,与R[2]交换,....,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,.....,第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列.
voidSelectsort()
inti,j,k,h,x=0,y=0;
L;
h=i;
for(j=i+1;
j++)
{x++;
//比较次数
R[h].key)
h=j;
//确定最小值
if(h!
=i)
R[0].key=R[i].key;
R[i].key=R[h].key;
R[h].key=R[0].key;
//移动次数
\t\t第%d趟选择排序的结果为:
\n\t\t比较次数:
\n\t\t移动次数:
图六选择排序
4.1.6堆排序
堆排序是一树形选择排序,在排序过程中,将R[1..N]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。
将原始记录序列建成一个堆,成为初始堆,并输出堆顶元素;
调整剩余的记录序列,使之成为一个新堆,再输出堆顶元素;
如此反复进行,当堆中只有一个元素时,整个序列的排序结束,输出的序列便是原始序列的非递减有序序列。
在堆排序的过程中,主要负责两方面的工作:
一是如何将原始记录序列构造成一个堆,即建立初始堆;
二是输出堆顶元素后,如何将剩余记录整理成一个新堆。
voidCreateHeap(introot,intindex,int*x,int*y)
intj,temp,finish;
j=2*root;
//j指向左孩子
temp=R[root].key;
finish=0;
while(j<
=index&
finish==0)
if(j<
index)
if(R[j].key<
R[j+1].key)
j++;
}//指向较大的孩子
if(temp>
=R[j].key)
finish=1;
else
R[j/2].key=R[j].key;
(*y)++;
j=j*2;
*x=*x+2;
R[j/2].key=temp;
(*y)++;
//堆排序
voidHeapsort()
inti,j,temp,k,x=0,y=0;
for(i=(L/2);
i>
=1;
i--)//建立初始堆
CreateHeap(i,L,&
x,&
y);
x=0;
y=0;
for(i=L-1,k=1;
i--,k++)//将堆中根节点和最后一个节点交换
temp=R[i+1].key;
R[i+1].key=R[1].key;
R[1].key=temp;
CreateHeap(1,i,&
\t\t第%d趟堆排序的结果为:
k);
R[j].key);
%d\t\t"
voidHeap()
inti;
Heapsort();
voidMerge(intlow,intmm,inthigh,int*x,int*y)//两个有序序列的合并
inti=low,j=mm+1,p=0;
RecType*R1;
//i对第一个开始到结尾,j从第二个开始到结尾
R1=newRecType[high-low+1];
if(!
R1)
内存不足!
=mm&
=high)//两序列从起始位置开始将小的元素放入到R1中
R1[p++]=(R[i].key<
=R[j].key)?
R[i++]:
R[j++];
(*x)++;
(*y)++;
=mm)//第二段结束,剩余放入R1中
R1[p++]=R[i++];
=high)//第二段剩余,剩余放入R1中
R1[p++]=R[j++];
for(p=0,i=low;
=high;
p++,i++)//剩余元素放入R1中,赋予R
R[i]=R1[p];
图七堆排序
4.1.7归并排序
将有n个记录的原始序列看作n个有序子序列,每个子序列的长度为1,然后从第一个子序列开始,把相邻的子序列两两合