直接插入排序
/*总是将a[i]与a[i+1]作比较,temp记录两者中较小的数
然后对这个数左边遍历将比temp大的数右移,
然后在空出来的位置上插入temp进行排序*/
#include <stdio.h>
insert_sort(int a[],int n)
{
int i,j,temp;
for(i=1;i<n;i++)
{
if(a[i] <a[i-1])
{
temp=a[i];
for(j=i-1; a[j]>temp; j--)
{
a[j+1]=a[j];//从下标j处,所有的元素都右移
}
a[j+1]=temp;
}
}
}
int main(void)
{
int i,a[10]={0,1,3,2,9,6,5,8,7,4};
insert_sort(a, 10);
for(i=0;i<10;i++)
printf("%d ",a[i]);
}
选择排序
/*用index记录数组的未排序部分的第一个位置i=index,
从它的下一位置开始遍历所有元素与该位置处的数比较,找到最小的并用index记录该处下标
将a[i]与a[index]作值交换,如此往复。
与冒泡算法相比,比较次数无变化,但值交换的次数减少*/
#include <stdio.h>
void select_sort(int a[],int n)
{
int i,j,index,temp;
int count1=0,count2=0;
for(i=0;i<n-1;i++)
{
index=i;
for(j=i+1;j<n;j++){
count1++;
if(a[j] <a[index]) {index=j;count2++;}
}
temp=a[index];
a[index]=a[i];
a[i]=temp;
}
printf("共进行%d次比较%d次值交换\n",count1,count2);
}
int main(void)
{
int i,a[10]={0,1,3,2,4,6,5,7,8,9};
select_sort(a, 10);
for(i=0;i<10;i++)
printf("%d ",a[i]);
}
希尔排序
/*希尔排序基本思想:先将整个记录序列分割成若干个子序列分别进行直接插入排序,
待整个序列中的记录基本有序时,再对全体记录进行一次直接插入排序
其实就是对插入排序的改进a[i-gap]与a[i]比较,时间复杂度与gap的值有关系。应使gap值为
没有除1之外的公因子,并且最后gap值必须为1*/
#include <stdio.h>
void shell_sort(int a[],int n)
{
int i,j,temp;
int gap=n;
do
{
gap=gap/3+1;
for(i=gap;i<n;i++)
{
if(a[i] <a[i-gap])
{
temp=a[i];
for(j=i-gap; a[j]>temp; j-=gap)
{
a[j+gap]=a[j];//从下标j处,所有的元素都右移
}
a[j+gap]=temp;
}
}
}while(gap>1);
}
int main(void)
{
int i,a[10]={0,9,2,3,4,6,7,1,5,8};
shell_sort(a, 10);
for(i=0;i<10;i++)
printf("%d ",a[i]);
}
冒泡排序
/*数组中左右相邻的元素a[i-1]与a[i]相互之间进行比较,若a[i-1]<a[i]则交换数值
最终可以使得大的数不断往后移动实现排序功能*/
#include <stdio.h>
void bubble_sort(int k[],int n)
{
int i,j,temp,flag=1;
int count1=0,count2=0;
for(i=0; i<n-1 && flag; i++)
{
for(j=n-1; j>i; j--)//加入flag标志,减少比较次数
{
count1++;
flag=0;
if(k[j-1] > k[j])
{
temp=k[j-1];
k[j-1]=k[j];
k[j]=temp;
flag=1;
count2++;
}
}
}
printf("共进行了%d次比较%d次值交换",count1,count2);
}
int main(void)
{
int i,a[10]={0,1,3,2,4,6,5,7,8,9};
for(i=0;i<10;i++)
printf("%d ",a[i]);
bubble_sort(a, 10);
for(i=0;i<10;i++)
printf("%d ",a[i]);
}
快速排序
/*快速排序是对冒泡排序的一种改进,它的基本思想就是通过一趟排序将
待排序记录分割成独立的两个部分,其中一部分记录的关键字比另一部分
记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序
快速排序是目前被认为是最好的一种内部排序算法*/
#include <stdio.h>
void QuickSort(int a[], int n)//n为数组的长度
{
int low=0,high=n-1;
int temp,temq;
int pivot=a[low];//枢轴值
if(n >1 )
{
while(low <high)
{
while(low<high && a[high] >= pivot )
--high;
a[low]= a[high];//比pivot小的都放在左边
while(low<high && a[low] <=pivot)
++low;
a[high]=a[low];//比pivot大的都放到右边
}
a[low]=pivot;//此时low=high
QuickSort(a,low);//对low的左边部分进行排序
QuickSort(a+low+1, n-low-1);/*对i+2到numsize这numsize-1-i个数排序*/
}
}
int main(void)
{
int a[8];
int i;
for(i=0;i<8;i++)
scanf("%d", a+i);
QuickSort(a,8);
for(i=0;i<8;i++)
printf("%d",a[i]);
}
归并排序
/*将含有n个记录的序列看作n个有序的子序列,每个子序列的长度为1,然后两两归并,
得到n/2个长度为2的子序列,如此往复最终求解
将长度n的序列向下递归分解为左右两部分,知道L/R长度为1,
然后向上倒退合并,并将排序后的值保存在Llist数组中,因为它的首地址就是数组A的地址*/
#include <stdio.h>
#define MAXSIZE 10
//实现归并,并把最后的结果存放到Llist中
void merge(int *Llist, int Lsize,int *Rlist,int Rsize)
{
int i=0,j=0,k=0;
int temp[MAXSIZE];
while(i <Lsize && j<Rsize)
{
if(Llist[i] < Rlist[j])
{
temp[k++] =Llist[i++];
}
else
{
temp[k++] = Rlist[j++];
}
}
while(i < Lsize)
{
temp[k++] =Llist[i++];
}
while(j < Rsize)
{
temp[k++] =Rlist[j++];
}
int m;
for(m=0;m<(Lsize+Rsize);m++){
Llist[m]=temp[m];
printf("%d ",Llist[m]);
}
printf("||\n");
}
void merge_sort(int a[],int n)
{
//拆分
int *Llist=a;
int Lsize=n/2;
int *Rlist=a+n/2;
int Rsize=n-Lsize;
if(n>1)
{
merge_sort(Llist, Lsize);
merge_sort(Rlist, Rsize);
merge(Llist, Lsize,Rlist, Rsize);
}
}
int main(void)
{
int i,a[10]={0,9,2,3,4,6,7,1,5,8};
merge_sort(a, 10);
for(i=0;i<10;i++)
printf("%d ",a[i]);
}