排序算法——直接插入法排序

来源:互联网 发布:php ios aes加密解密 编辑:程序博客网 时间:2024/04/30 09:56

直接插入法排序,对于这样一个问题我们该如何很好的去理解它呢?相信很多人对扑克牌应该很熟悉,当你拿到带有数字5 4 6 9 7 8这样几张牌的时候肯定会自然而然的将4向5的左侧1移动(4 5 6 9 7 8),将7往9的左侧移(4 5 6 7 9 8),再将8向9移动(4 5 6 7 8 9),这个移动的过程就是直接插入法排序。如果还不是太明白的话可以通过下图进一步的理解:


下来我们再将直接插入法的算法思路整合一下:

(1)将待排序序列的第一个元素看作是一个有序序列,把第二个元素到最后一个元素当成是无序序列;

(2)将无需序列的元素插入到有序序列中的适当位置处,这里存在元素大小的比较,还有如果待插入元素与有序区中的某个元素相等时,则将待插入的这个元素直接插入到有序区中与之相等的元素的后面。

下面给出代码实现:

#include<stdio.h>#include<stdlib.h>#include<assert.h>void InsertSort(int *str,int len){int i=0;int j=0;int tmp=0;for(i=1;i<len;i++)            //控制插入的次数{tmp=str[i];for(j=i;(j>0)&&(str[j-1]>tmp);j--){str[j]=str[j-1];}str[j]=tmp;}}int main(){int arr[]={1,2,3,7,6,5,4,8,9,0};int i=0;InsertSort(arr,10);for(i=0;i<10;i++){printf("%2d",arr[i]);}system("pause");return 0;}



像上面最后一步在找3的合适位置时,我们还可以通过折半查找的方式做出优化,因为有序去已经有序了啊,刚好符合我们折半查找的要求。对于大型数组这样的优化是相当有必要的,通过优化可以减少有序区元素比较的次数。


void InsertSort(int *str,int len){int i=0;int j=0;int mid=0;int left=0;int right=0;int tmp=0;int k=0;                    //用来记录要插入的位置for(i=1;i<len;i++)          //控制插入的次数{left=0;right=i-1;//还可用left&right+(left^right)>>1来求解mid,防止溢出mid=(right-left)/2+left;    tmp=str[i];while(left<=right){if(str[mid]>tmp)      //要插入的位置要小于等于mid{right=mid-1;k=mid;}else if(str[mid]<tmp) //要插入的位置必大于mid{left=mid+1;k=mid+1;}mid=(right-left)/2+left;}for(j=i;j>k;j--)           {str[j]=str[j-1];}str[k]=tmp;}}




0 0
原创粉丝点击