1.直接插入排序
将待排的n个元素看成一个有序序列和一个无序序列,每次从无序序列中取出第一个元素插入前面的有序序列中。
时间复杂度o(n^2)
#include<stdio.h>
void insert_sort(int a[],int n)
{
int i,j,k,temp;
for(i=1;i<n;i++)
{
//为a[i]在前面已经排号的有序序列中找一个合适的位置
for(j=i-1;j>=0;j--)
if(a[j]<a[i])
break;
//找到合适的位置,
if(j!=i-1)
{
int temp=a[i];
//将比a[i]大的数向后移
for (k=i-1;k>j;k--)
a[k+1]=a[k];
//a[i]放到找到的位置
a[k+1]=temp;
}
}
}
int main()
{
int a[]={3,1,6,23,5,8,22};
int n=7;
int i;
insert_sort(a,n);
printf("the sort:");
for (i=0;i<n;i++)
printf("%d ",a[i]);
}
交换排序:冒泡排序和快速排序
2.冒泡排序
/*思想:每次比较相邻的数,交换位置;
针对第一个数开始往后比较直到就位,就像一个气泡一步一步往后翻滚;
每一趟只能确定一个数就位;
时间复杂度o(N^2);
*/
从数组头部开始,不断比较相邻的两个元素的大小,让较大的元素逐渐往后移动(交换两个元素的值),直到数组的末尾。经过第一轮的比较,就可以找到最大的元素,并将它移动到最后一个位置。
第一轮结束后,继续第二轮。仍然从数组头部开始比较,让较大的元素逐渐往后移动,直到数组的倒数第二个元素为止。
经过第二轮的比较,就可以找到次大的元素,并将它放到倒数第二个位置。
以此类推,进行 n-1(n 为数组长度)轮“冒泡”后,就可以将所有的元素都排列好。
#include<stdio.h>
int main()
{
int a[10]={5,8,67,23,43,12,3,2,6,10},i,j,t;
//冒泡排序
for (i=0;i<9;i++) //n个数排序,只用进行n-1趟
{
for(j=0;j<=9-i;j++) //一趟:从第一个数开始比较到最后一个尚未归位的数
{
if(a[j]>a[j+1]) //比较换位 :大的往后移
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
for (i=0;i<10;i++) //输出
printf("%3d",a[i]);
}
3.快速排序
在待排序的n个记录中任取一个记录,以该记录的排序码为准,将所有的记录分为两组,第一组各记录的排序码都小于等于该排序码,第二组各记录的排序码都大于该排序码,并把该记录排在这两组中间。
在快速排序中,选定了以第一个元素为基准,接着就拿第一个元素和第一个元素比较,如果大于第一个元素,则保持不变,再拿倒数第二个元素和基准比较,如果小于基准,就进行交换。交换之后,再从前面的元素开始与基准比较,如果小于基准,则保持不变,如果大于基准,则交换。交换之后,再从后面比较,依次类推,前后交叉进行,当前后的指针交叉过,则第一轮结束,此时,基准数前面的数都小于基准数,基准数后面的数都大于基准数。
第二轮,对第一轮基准数两边的数组分别进行上面的步骤,直到数组不能再分组(只有一个数据),最后得到结果。
#include<stdio.h>
int a[10]={5,8,45,69,21,47,6,3,24,18},n;
void quicksort(int left,int right)
{
int i,j,t,temp;
//如果左指针在右指针的右边,说明这趟快排结束
if(left>right)
{
return;
}
//最左边的元素作为基准数
temp=a[left];
//
i=left;
j=right;
while(i<j)
{
//移动右指针,直至a[j]<temp
while(i<j&&a[j]>=temp)
{
j--;
}
//移动左指针,直至a[i]>=temp
while(i<j&&a[i]<=temp)
{
i++;
}
//交换找到的两个元素,
if(i<j)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
//把a[i]作为最左边的指针
a[left]=a[i];
//把a[i]作为枢纽元素
a[i]=temp;
//快排左边的序列
quicksort(left,i-1);
//快排右边的序列
quicksort(i+1,right);
}
int main()
{
int i;
quicksort(0,9);
for (i=0;i<10;i++)
printf("%3d",a[i]);
return 0;
}