zoukankan      html  css  js  c++  java
  • 折半、二路插入排序

    折半插入排序:直接插入排序是将待插入元素与前面的元素一一比较,寻找合适的位置插入。而折半插入是通过折半来查找位置,所谓折半(可以参考二分查找)就是定义两个变量分别指向头start和尾end,取其中间值mid。如果待插入元素大于mid位置上的元素就这mid和end之间再查找,如果小于,则在start和mid之间查找。然后不断缩小范围,直到寻找到合适的位置(大于左边小于右边),然后就是元素的插入。

     1 #include<stdio.h> 
     2 #define n 6
     3 
     4 
     5 void binaryInsertSort(int num[]){
     6 
     7     int start,end,mid,i,j,t;
     8     for(i=1;i<n;i++){
     9         start = 0;                        //开始位置从0开始 
    10         end = i-1;                        //结束位置在待插入元素的前一个位置 
    11         while(start<=end){                //循环条件 
    12             mid = (start+end)/2;         
    13             if(num[i]>=num[mid])        //如果此条件成立 
    14                 start = mid + 1;        //就说明待插入元素的插入位置应该在mid和end之间 
    15             else
    16                 end = mid - 1;            //否则说明待插入元素的插入位置应该在start和mid之间 
    17         }
    18         
    19         if(start>mid)        //如果start>mid,说明待插入元素比mid位置的元素大,但比mid+1位置上的元素小 
    20             mid++;            //此时插入位置应该是mid+1
    21                             //还有一种情况就是end<mid,说明待插入元素比mid位置的元素小 
    22                             //此时插入位置应该是mid
    23                 
    24         t = num[i];                //此处就是元素的插入
    25         for(j=i-1;j>=mid;j--)    //使用直接插入排序代码思想在此处插入元素         
    26             num[j+1] = num[j];
    27         num[j+1] = t;
    28         
    29     }
    30     
    31 }

    二路插入排序:前面的插入排序每次插入元素的时候都会移动较多的元素,二路插入排序对其进行了改善。思路是:以第一个元素作为比较元素,后面所有大于该元素的数全部放在前面,所有小于元素的数放在后面,大于或小于部分的元素在插入的时候使用直接插入排序来保证有序,当所有元素分配好后,其实数组已经变成两个有序区,在组合好就完成排序了。

    定义first、final指向两个有序区,图解如下:

     1 #include<stdio.h>
     2 #define n 6
     3 
     4 
     5 void twoInsertSort(int num[]){
     6     
     7     int i,j,first,final,temp[n+1]={0};    //临时存放数组比原有数组多一个空间 
     8     first = 0;                            //first、final分别指向临时存放数组的开头和结尾 
     9     final = n;
    10     temp[0] = num[0];                    //数组第一个元素作为比较元素 
    11     
    12     for(i=1;i<n;i++){                    
    13         if(num[i]>=num[0]){                //大于第一个元素的数放在临时数组的前面 
    14             j = first;                    //first作为大于第一个元素的数的最后元素的下标 
    15             while(num[i]<=temp[j]){        //在这里使用直接插入,使其有序 
    16                 temp[j+1] = temp[j];     
    17                 j--;
    18             }
    19             temp[j+1] = num[i];
    20             first++;
    21         }
    22         else{
    23             j = final;                    //小于第一个元素的数放在临时数组的后面 
    24             while(num[i]>temp[j]){        //在这里使用直接插入,使其有序 
    25                 temp[j-1] = temp[j];    
    26                 if((++j)>=n+1)            //这里是为了防止数组向后越界 
    27                     break;
    28             }
    29             temp[j-1] = num[i];
    30             final--;                    //final作为小于第一个元素的数的最前元素的下标  
    31         }                                //但final指向了最前元素的前一个位置    
    32     }
    33     
    34     for(i=0;i<n-1-first;i++)            //将临时数组存放到原来的数组 
    35         num[i] = temp[++final];
    36         
    37     for(j=0;i<n;j++,i++)
    38         num[i] = temp[j];
    39     
    40 }
    41 
    42 void main(){
    43     
    44     int i,num[n] = {890,761,812,761,810,261};
    45     twoInsertSort(num);
    46     
    47     for(i=0;i<n;i++)
    48         printf("%d ",num[i]);
    49     
    50 }
  • 相关阅读:
    css中后代、元素、类、id选择器以及行间style优先级的比较
    JS小功能x系列6文字自动滚动
    JS小功能系列7自动打字
    JS小功能系列6折叠
    JS小功能系列5图片左右移动
    JS小功能系列4图片轮播综合数字轮播,顺时针逆时针,自动轮播
    JS小功能系列3时钟
    JS小功能系列2商品计算
    JS小功能系列1换一批
    JS隔行变色,鼠标悬停变色
  • 原文地址:https://www.cnblogs.com/lsy-lsy/p/12031835.html
Copyright © 2011-2022 走看看