C语言排序法大集合.docx
《C语言排序法大集合.docx》由会员分享,可在线阅读,更多相关《C语言排序法大集合.docx(12页珍藏版)》请在冰豆网上搜索。
C语言排序法大集合
河南工业大学
班级:
软件2班
姓名:
晁永兵
学号:
201116040220
(快排效率最好)
#include
#include
#include /*用到了time函数*/
typedefint Keytype;
typedefintDatatype;
structrecord_node
{
Keytype key; //排序码的字段
Datatypeinfo; //记录的其他字段
};
structSort_object
{
intn; //n为文件中记录的个数
record_node*record; //采用顺序存储结构
};
voidfrand(Sort_object*pvector) /*产生随机数的函数*/
{
inti;
srand((int)time(0)); /*准备生成随机数,以当前时间为种子*/
for(i=0;in;i++)
pvector->record[i].key=rand()%1000; /*产生随机数*/
}
voiddirect_insert_sort(Sort_object*pvector) //直接插入排序,按照增序
{
inti,j,compare_num=0,move_num=0;
record_nodetemp; //一个辅助空间
for(i=1;in;i++)
{
temp=pvector->record[i];
j=i-1;
while(j>=0&&temp.keyrecord[j].key)
{
compare_num++;
move_num++;
pvector->record[j+1]=pvector->record[j];
j--;
}
if(j!
=i-1) //判断是否需要插入
{
move_num++;
pvector->record[j+1]=temp;
}
}
printf("***************************************************************************\n");
printf("经过 直接插入法排序 之后得到的顺序序列是:
\n\n");
for(i=0;in;i++)
printf("%d\t",pvector->record[i].key);
printf("\n\n");
printf("比较的次数是:
%d\t移动的次数是:
%d\n",compare_num,move_num);
printf("***************************************************************************\n\n\n\n");
}
voiddichotomy_insert_sort(Sort_object*pvector) //二分法插入排序,按照增序
{
inti,j,compare_num=0,move_num=0,left,right,mid;
record_nodetemp; //一个辅助空间
for(i=1;in;i++)
{
temp=pvector->record[i];
left=0;
right=i-1;
while(left<=right)
{
compare_num++;
mid=(left+right)/2;
if(temp.keyrecord[mid].key)
right=mid-1;
else
left=mid+1;
}
for(j=i-1;j>=left;j--)
{
move_num++;
pvector->record[j+1]=pvector->record[j];
}
if(left!
=i)
{
move_num++;
pvector->record[left]=temp;
}
}
printf("***************************************************************************\n");
printf("经过 二分法排序 之后得到的顺序序列是:
\n\n");
for(i=0;in;i++)
printf("%d\t",pvector->record[i].key);
printf("\n\n");
printf("比较的次数是:
%d\t移动的次数是:
%d\n",compare_num,move_num);
printf("***************************************************************************\n\n\n\n");
}
voidtwo_way_insert_sort(Sort_object*pvector) //二路插入排序,按照增序
{
inti,j,compare_num=0,move_num=0,left,right,mid,first,last;
record_node*d; //一个与记录类型相同的数组
d=(structrecord_node*)malloc(sizeof(structrecord_node)*(pvector->n)); //申请的n个辅助空间
if(d==NULL)
{
printf("Outofspace!
\n");
return;
}
d[0]=pvector->record[0]; //将第一个记录赋给第一个辅助空间
last=first=0; //初始化指针,记录的是数组的下标
for(i=1;in;i++)
{
compare_num++;
if(pvector->record[i].key {
if(first==0) //如果后面的顺序表为空时
{
first=pvector->n-1;
d[first]=pvector->record[i];
}
else
{
left=pvector->n-1;
right=first;
while(right<=left) //注意判断条件,折半检索,查找要插入的位置
{
compare_num++;
mid=(left+right)/2;
if(pvector->record[i].key left=mid-1;
else
right=mid+1;
}
first--; //first的位置向前移动一位,腾出位置,插入新的记录
for(j=first;j {
move_num++;
d[j]=d[j+1]; //依次后移一位
}
d[j]=pvector->record[i]; //直接赋值
}
}
else //否则插入后面的有序表
{
left=0;
right=last;
while(left<=right) //注意判断条件,折半检索,查找要插入的位置
{
compare_num++;
mid=(left+right)/2;
if(pvector->record[i].key right=mid-1;
else
left=mid+1;
}
last++; //first的位置向前移动一位,腾出位置,插入新的记录
for(j=last;j>left;j--)
{
move_num++;
d[j]=d[j-1]; //数组元素向前移动一位
}
d[j]=pvector->record[i]; //完成插入操作
}
}
printf("***************************************************************************\n");
printf("经过 二路插入法排序 之后得到的顺序序列是:
\n\n");
for(i=first,j=0;(j++)n;i=(i+1+pvector->n)%pvector->n)
printf("%d\t",d[i].key);
printf("\n\n");
printf("比较的次数是:
%d\t移动的次数是:
%d\n",compare_num,move_num);
printf("***************************************************************************\n\n\n\n");
}
voidshell_insert_sort(Sort_object*pvector) //希尔排序法,按照增序
{
inti,j,increment,compare_num=0,move_num=0;
record_nodetemp; //一个辅助空间
for(increment=pvector->n/2;increment>0;increment/=2)
{
for(i=increment;in;i++)
{
temp=pvector->record[i];
j=i-increment;
while(j>=0&&temp.keyrecord[j].key)
{
compare_num++;
pvector->record[j+increment]=pvector->record[j];
j-=increment;
}
move_num=++compare_num;
pvector->record[j+increment]=temp;
}
}
printf("***************************************************************************\n");
printf("经过 希尔排序 之后得到的顺序序列是:
\n\n");
for(i=0;in;i++)
printf("%d\t",pvector->record[i].key);
printf("\n\n");
printf("比较的次数是:
%d\t移动的次数是:
%d\n",compare_num,move_num);
printf("***************************************************************************\n\n\n\n");
}
voiddirect_select_sort(Sort_object*pvector) //直接选择排序法,按照增序
{
inti,j,k,compare_num=0,move_num=0;
record_nodetemp;
for(i=0;in-1;i++) //做n-1趟选择排序
{
k=i;
for(j=i+1;jn-1;j++)
{
compare_num++;
if(pvector->record[j].keyrecord[k].key)
k=j;
}
if(k!
=i) //存在不需要交换的情况
{
move_num+=3;
temp=pvector->record[i];
pvector->record[i]=pvector->record[k];
pvector->record[k]=temp;
}
}
printf("***************************************************************************\n");
printf("经过 直接选择法排序 之后得到的顺序序列是:
\n\n");
for(i=0;in;i++)
printf("%d\t",pvector->record[i].key);
printf("\n\n");
printf("比较的次数是:
%d\t移动的次数是:
%d\n",compare_num,move_num);
printf("***************************************************************************\n\n\n\n");
}
voidlarge_sift(Sort_object*pvector,intsize,intp,int*compare_num,int*move_num) //大根堆排序中利用到的算法,建堆,其中size为整个堆的结点总数,而p为需要建堆的结点下标
{
record_nodetemp=pvector->record[p];
intchild=2*p+1; //chile为P结点的左孩子
while(child {
if((childrecord[child].keyrecord[child+1].key))
{
(*compare_num)++;
child++; //选择较大的子结点
}
if(temp.keyrecord[child].key)
{
(*compare_num)++;
(*move_num)++;
pvector->record[p]=pvector->record[child]; //将大的子结点上移
p=child; //继续往上寻找
child=2*p+1;
}
else
break; //调整结束
}
(*move_num)++;
pvector->record[p]=temp; //将temp放入正确位置
}
voidheap_select_sort(Sort_object*pvector) //堆排序,按照增序
{
inti,n,*compare_num,*move_num;
compare_num=(int*)malloc(sizeof(int)); //这里将比较次数,移动次数设定为指针型数据,是为了防止直接整型在调用过程中被释放的情况
move_num =(int*)malloc(sizeof(int));
*compare_num=0;
*move_num =0;
record_nodetemp;
n=pvector->n;
for(i=n/2-1;i>=0;i--)
large_sift(pvector,n,i,compare_num,move_num); //从完全二叉树的倒数第一个分支结点开始建堆,直到根结点,首先构造出第一个初始堆
for(i=n-1;i>0;i--) //需要循环n-1次
{
*move_num+=3;
temp =pvector->record[0];
pvector->record[0]=pvector->record[i];
pvector->record[i]=temp; //将首元素即最大的元素,与最后一个元素交换
large_sift(pvector,i,0,compare_num,move_num); //交换之后,重新建堆
}
printf("***************************************************************************\n");
printf("经过 大根堆排序 之后得到的顺序序列是:
\n\n");
for(i=0;i printf("%d\t",pvector->record[i].key);
printf("\n\n");
printf("比较的次数是:
%d\t移动的次数是:
%d\n",*compare_num,*move_num);
printf("***************************************************************************\n\n\n\n");
free(compare_num);
free(move_num);
}
voidbubble_swap_sort(Sort_object*pvector) //起泡法排序,按照增序
{
inti,j,swap,compare_num=0,move_num=0;
record_nodetemp;
for(i=0;in-1;i++)
{
swap=0;
for(j=0;jn-i-1;j++)
{
compare_num++;
if(pvector->record[j+1].keyrecord[j].key)
{
move_num=move_num+3;
temp=pvector->record[j];
pvector->record[j]=pvector->record[j+1];
pvector->record[j+1]=temp;
swap=1;
}
}
if(swap==0) //在一趟起泡之中未发生交换,算法结束
break;
}
printf("***************************************************************************\n");
printf("经过 起泡法排序 之后得到的顺序序列是:
\n\n");
for(i=0;in;i++)
printf("%d\t",pvector->record[i].key);
printf("\n\n");
printf("比较的次数是:
%d\t移动的次数是:
%d\n",compare_num,move_num);
printf("***************************************************************************\n\n\n\n");
}
voidquick_swap_sort(Sort_object*pvector,intl,intr,int*compare_num,int*move_num) //快速分区交换排序
{
inti,j;
record_nodetemp;
if(l>=r)
return;
i=l;
j=r;
temp=pvector->record[i];
(*move_num)++;
while(i!
=j)
{
while(j>i&&temp.key<=pvector->record[j].key)
{
(*compare_num)++;
j--;
}
(*compare_num)++;
if(i {
(*move_num)++;
pvector->record[i++]=pvector->record[j];
}
while(j>i&&temp.key>=pvector->record[i].key)
{
(*compare_num)++;
i++;
}
(*compare_num)++;
if(i {
(*move_num)++;
pvector->record[j--]=pvector->record[i];
}
}
pvector->record[i]=temp;
(*move_num)++;
quick_swap_sort(pvector,l,i-1,compare_num,move_num);
quick_swap_sort(pvector,i+1,r,compare_num,move_num);
}
intmain()
{
inti,n,*compare_num,*move_num;
compare_num=(int*)malloc(sizeof(int)); //这里将比较次数,移动次数设定为指针型数据,是为了防止直接整型在调用过程中被释放的情况
move_num =(int*)malloc(sizeof(int));
*compare_num=0;
*mov