最近整理了一些关于排序的算法,其中包括快排,简单插入排序,冒泡排序,选择排序,折半插入排序。
简单插入排序思想:
认为开始时数组第一个元素有序,随后依次向后扫描元素K,过程中有序的数组从后往前扫描,
若K比前一个元素小,则让元素向后移,直到K大于的元素处停止,此时K应放在此元素后面。
代码如下:
#include<stdio.h>
void insertsort(int *a,int n)//排序
{
int i,j,m;
for(i=1;i<n;i++)//默认第一个元素有序,从第二个开始依次向后扫描
{
for(m=a[i],j=i;j>0&&a[j-1]>m;j--)//如果有序元素从后向前扫描,直到找到小于m的元素位置
//并且此过程中每个元素后移,最后找到m的位置
{
a[j]=a[j-1];
}
a[j]=m;
}
}
main()
{
int a[10],i;
for(i=0;i<10;i++)
scanf("%d",a+i);
insertsort(a,10);
for(i=0;i<10;i++)
printf("%d",a[i]);
}
冒泡排序思想:
冒泡排序就是根据鱼吐泡泡的原理,大数往下沉,首先让最大的沉到最低端,然后就不再考虑它,
依次重复此操作,排序完成。
代码如下:
#include<stdio.h>
void popsort(int *a,int n)
{
int i,j,k;
for(i=0;i<n-1;i++)//从第一个元素开始直到倒数第二个,最后一个元素不用比较
{
for(j=0;j<n-1-i;j++)//从第一个元素开始依次与后面的元素作比较,大数向下沉,
//沉下去的就不再进行比较
{
if(a[j]>a[j+1])//大数向下沉进行交换
{
k=a[j];
a[j]=a[j+1];
a[j+1]=k;
}
}
}
}
main()
{
int a[10]={1,4,3,7,9,5,0,2,6,8},i;
popsort(a,10);
for(i=0;i<10;i++)
printf("%d",a[i]);
}
折半插入思想:
对简单插入的优化,减少了比较次数,即比较时首先比较中间元素,以此类推。
代码如下:
#include<stdio.h>
void binsearch(int *a,int n)
{
int i,j,k,m,low,high;
for(i=1;i<n;i++)//第一个元素默认有序,从第二个元素开始一次扫描比较
{
low=0;//有序元素的头
high=i-1;//有序元素的尾
while(low<=high)//直到low>high时即找到了此元素的位置
{
m=(low+high)/2;//m为元素的中间位置
if(a[m]>a[i])//m把有序元素分成了两半,看看a[i]处于哪一半
high=m-1;
else
low=m+1;
}
for(k=a[i],j=i;j>low;j--)//然后从a[i]前面的元素到low的位置处依次向后移
a[j]=a[j-1];
a[low]=k;//low的位置就是元素的位置
}
}
main()
{
int a[10],i;
for(i=0;i<10;i++)
scanf("%d",a+i);
binsearch(a,10);
for(i=0;i<10;i++)
printf("%d",a[i]);
}
选择排序思想:
依次扫描元素0<=K<=n,并且将元素与后面的所有元素进行比较,找到较大元素的坐标,
如果K!=I,即最大元素的位置不是I,而是K,进行交换。
代码如下:
#include<stdio.h>
void chosesort(int *a,int n)//传入数组和个数
{
int i,j,k,m;
for(i=0;i<n-1;i++)//从第一个依次向后扫描
{
k=i;//记录元素的位置
for(j=i+1;j<n;j++)//从此位置后面的元素开始依次扫描,找到较大的元素位置
//并将其付给 K
{
if(a[k]>a[j])
{
k=j;
}
}
if(k!=i)//如果K与I不同说明I在K位置的元素大于I位置的元素,因此交换
{
m=a[k];
a[k]=a[i];
a[i]=m;
}
}
}
main()
{
int a[10],i;
for(i=0;i<10;i++)
scanf("%d",a+i);
chosesort(a,10);
for(i=0;i<10;i++)
printf("%d ",a[i]);
}
快排思想:
快排主要是将以第一个元素为键值,即分界点,后面元素依次与制作比较,
大于它的在右边,小于它的在左边,而后左右两边再次运用此方法,递归。
代码如下:
#include<stdio.h>
int a[10]={1,3,2,6,8,9,7,4,5,0};
void sort(int *a,int x,int y)//传入数组的首位及末尾下标
{
int i=x,j=y,k;//I 为左端点,J为右端点
k=a[i];//第一个元素设为键值,即中间元素
if(i>=j)//如果数组不成立,返回
return;
while(i!=j)//当I!=J时
{
while(i<j&&k<=a[j])//保证I<J,从右端点开始扫描,直到找到小于键值的元素
//并且过程中J要减一
j--;
a[i]=a[j];//然后将其付给第一个元素
while(i<j&&k>a[i])//再从第二个元素开始扫描,直到找到大于键值的元素为止
//并将其付给末尾元素
i++;
a[j]=a[i];
}
a[i]=k;//键值付给中间元素
sort(a,x,i-1);//对左右部分分别递归调用
sort(a,i+1,y);
}
int main()
{
int i;
for(i=0;i<10;i++)
printf("%d",a[i]);
printf("\n");
sort(a,0,9);
for(i=0;i<10;i++)
printf("%d",a[i]);
return 0;
}