算法之排序——插入排序

来源:互联网 发布:bad sql grammar 编辑:程序博客网 时间:2024/05/19 09:04

插入排序的基本思想是,对数组元素a[l]~a[r],经过前i-l遍处理后,a[l],a[l+1],.....a[i-1]已排好序。下一轮处理就是要将a[i]插入到a[l],a[l+1],.......a[i-1]的合适位置,即插入到前面的有序数列中,使得a[l],a[l+1],........a[i]是排好序的序列。  要达到这个目的,可以用顺序比较的方法,首先比较a[i]和a[i-1];如果a[i-1]<=a[i],则 a[l]......a[i]已排好序,第i遍处理就结束了;否则交换 a[i]和a[i-1]的位置,继续比较a[i-1]和a[i-2],直到找到某个位置j(1<=j<=i-1),使得a[j]<=a[j+1]时为止。直接看代码会比较直观


c语言代码:

#include<stdio.h>#include<malloc.h>//为了使用malloc函数void insert(int *a,int l,int i){int v=a[i];  //v为临时变量,存储要插入的数while(i>l&&v<a[i-1])  //从后往前查找,在不越界的情况下,找到一个比V小的数,即前面的数比V大,后面的数比V小,则插入{a[i]=a[i-1];//后面的数依次往后挪一个位置,为空出一个位置,以便插入Vi--;}a[i]=v;   //将V插入到相应位置}void insertion(int *a,int l,int r)  //默认a[0]是有序的,然后从a[1]开始,每个元素都插入到前面已经排序好的元素中{int i;for(i=1;i<=r;i++)   //此循环就是将除a[0]外的每个元素依次插入到前面的有序数列中insert(a,l,i);  //调用插入函数}  int main(){int *a;  //声明一个int 型指针int n=10,t,i;//n可以自由输入,此处定义n=10;a=(int *)malloc(sizeof(int)*n); //动态分配一片n个int 的空间 , 即数组a[n];for(i=0;i<n;i++)  //输入n个数,并存储在数组中scanf("%d",&a[i]);insertion(a,0,n-1);//调用排序函数for(i=0;i<n;i++) //打印排序之后的数组printf("%d ",a[i]);free(a);return 0;}



哨兵方法:

上述程序在每次比较时,都要判断i是否越界,即i>0是否成立,这样显然有点麻烦,如果在a[0]设置一个哨兵的话,即可解决问题,但是数据的话就要从a[1]开始存。


#include<stdio.h>#include<malloc.h>//为了使用malloc函数void insert(int *a,int l,int i){a[0]=a[i];  //设置哨兵,即a[0]存储的是要插入的元素,以下循环在遇到a[0]<a[0]的时候就会退出while(a[0]<a[i-1])  //从后往前查找,在不越界的情况下,找到一个比V小的数,即前面的数比V大,后面的数比V小,则插入{a[i]=a[i-1];//后面的数依次往后挪一个位置,为空出一个位置,以便插入Vi--;}a[i]=a[0];   //将V插入到相应位置}void insertion(int *a,int l,int r)  //默认a[0]是有序的,然后从a[1]开始,每个元素都插入到前面已经排序好的元素中{int i;for(i=2;i<=r;i++)   //默认a[1]为有序,此循环就是将除a[1]外的每个元素依次插入到前面的有序数列中,a[0]为哨兵,insert(a,l,i);  //调用插入函数}  int main(){int *a;  //声明一个int 型指针int n=10,t,i;//n可以自由输入,此处定义n=10;a=(int *)malloc(sizeof(int)*(n+1)); //动态分配一片n个int 的空间 , 即数组a[n];for(i=1;i<=n;i++)  //注意:由于要设置一个哨兵,所以只能从a[1]开始存数据scanf("%d",&a[i]);insertion(a,0,n);//调用排序函数,实参为数组下标0和nfor(i=1;i<=n;i++) //打印排序之后的数组printf("%d ",a[i]);free(a);return 0;}

在插入的过程需要比较以找到合适的位置插入,这时就可以才用二分查找的策略以减少查找次数;

代码如下:只是修改了查找部分

#include<stdio.h>void insertion(int a[],int l,int i){int v=a[i];int r=i,m,j;while(l<=r)  //折半查找{ m=(l+r)/2;if(v==a[m])break;if(v<a[m])r=m-1;if(v>a[m])l=m+1;}for(j=i;j>m;j--)  //m即要插入的位置,所以将m之后的元素一次往后挪,然后将a[i]插入m的位置a[j]=a[j-1];a[m]=v;}void sort(int a[],int l,int r){for(int i=1;i<=r;i++)insertion(a,0,i);}int main(){int a[10]={5,7,9,6,8,4,2,1,3,10};printf("排序前:\n");for(int i=0;i<10;i++)printf("%d ",a[i]);sort(a,0,9);printf("\n排序后:\n");for(i=0;i<10;i++)printf("%d ",a[i]);return 0;}


原创粉丝点击