对排序的一点研究(选择排序,交换排序,插入排序)。望补充。
最近看了些排序的东西,感觉收获挺多,不过就是不全,希望大家看了之后说说自己的想法。
以下代码中,EleType是自定义的数据类型,这不是什么关键。
1、简单选择排序
思路:选择最小的数放在数组的前端。
代码如下:
程序代码:void SelectSort(EleType a[],int n) //a[n]是要排序的最后一个数
{
int i,j,min;
EleType temp;
for(i=0;i<n-1;i++)
{
min=i;
for(j=i+1;j<n;j++) //找出最小的数字
if(a[j]<a[min])
min=j;
if(min!=i) //如果min和i不等,就交换
{
temp=a[min];
a[min]=a[i];
a[i]=temp;
}
}
}代码很简单,理解起来也没什么难度。2、直接插入排序
思路:把前面的序列作为已经排序好的序列,将未排序的数逐个插入到适当位置。
代码如下:
程序代码:void InsertSort(EleType a[],int n)
{
int i,j;
EleType Flag; //作为监视哨
for(i=1;i<=n;i++)
{
Flag=a[i]; //要插入的数赋值给Flag,作为监视哨
j=i-1;
while(Flag<a[j])//寻找插入位置
{
a[j+1]=a[j];
j--;
}
a[j+1]=Flag; //将原a[i]中的值存入第j+1个位置
}
}3、折半插入排序
思路:与直接插入排序的不同仅仅在于查找插入位置的方法不同,用折半查找的方法,
代码就不贴了。
4、希尔排序
思路:将要排序的数据分组,相隔为d的数据做一组,组内做直接插入排序,缩小d的值,
循环排序,直至结束。
代码如下:
程序代码:void ShellSort(EleType a[],int n)
{
int i,j,d;
EleType Flag;
for(d=n/2;d>=1;d=d/2)
{
for(i=d;i<=n;i++)
{
Flag=a[i]; //监视哨
j=i-d; //j为同一组的i的前一个元素下标
while(j>=0 && Flag<a[j])
{
a[j+d]=a[j]; //同一组内做简单插入
j=j-d;
}
a[j+d]=Flag;
}
}
}希尔算法十分巧妙,效率也比较高。5、冒泡排序
思路:比较相邻两数的大小,如果位置不对就交换,就像气泡像上冒一样。
代码如下:
程序代码:void BubbleSort(EleType a[],int n)
{
int i,j,Last,flag,m,temp;
Last=n-1;
for(i=n;i>=2;i--)
{
flag=0; //标记设置为0
m=Last; //记录最后交换的位置
for(j=0;j<=m;j++)
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
flag=1; //如果发生过交换,置1
Last=j; //最后交换位置赋值给Last
}
if(flag == 0) break;//如果未发生交换,说明已排序完成,退出函数
}
}这是我最早会的排序方法,最简单,但是效率比较低。6、快速排序
思路:将temp数放置在正确位置,左边的数都比它小,右边的数都比它大,然后递归
调用进行再次排序,直至结束。
代码如下:
程序代码:void QuickSort(EleType a[],int Left,int Right)
{
EleType temp;
int i,j;
i=Left;j=Right;temp=a[i]; //设置初始排序区
while(i<j)
{
while(temp <= a[j]) //从右侧开始扫描
j--; //找到第一个小于基准记录的数据
a[i]=a[j]; //覆盖
while(a[i]<=temp) //从左侧开始扫描
i++; //找到第一个大于基准记录的数据
a[j]=a[i]; //覆盖
}
a[i]=temp; //找到正确位置
if(Left<i-1) QuickSort(a,Left,i-1); //判断是否需要再排序
if(i+1<Right) QuickSort(a,i+1,Right);
}快速排序应该算是这些排序算法中效率最高的了。用100个随机数据进行排序,比较移动次数和比较次数
直接插入 折半插入 希尔排序 冒泡排序 快速排序 简单选择
比较次数 2666 257 401 4950 622 4950
移动次数 2864 2864 1407 7581 398 270
上面的数据很直观的看出了各个排序方法的差距。
还有其他排序方法希望补充补充,或者有什么深入想法也说说。










.