zoukankan      html  css  js  c++  java
  • 插入排序,希尔排序

    插入排序

        一、定义:将数组分成左右2个部分,左边的是有序的,右边的是无序的,按正序或反序,逐个把右边无序的插入到左边有序的,最终完成排序。

      实现:

        1.移动法

        先把数组第0个元素看作是有序的,第1个元素之后是无序的,把第1个元素取出来保存,并与第0个元素进行比较,如果第0个元素大(或小),移动第0个元素到第1个元素位置(把第0个元素的值赋值给第1个元素),然后把保存的原第1个元素的值,赋值给第0个元素,实现插入,第0、1元素有序;然后把第2个元素取出来保存,并与其之前的有序元素从右向左,逐个比较,移动、插入,移动的条件是大(或小),插入的条件是不再大(或小)或者第0个元素也已经移动;第3、4...以此类推。

      c语言代码:

     1 /*插入排序*/
     2 #include <stdio.h>
     3 void InsertSort(int *arr, int n)
     4 {
     5     int i;
     6     for(i=1; i<n; ++i){/*第0个元素有序,从第1个元素向右无序*/
     7         int j=i-1,key=arr[i];/*保存第i个元素,左边的元素i-1*/
     8         while(j>=0 && key<arr[j]){/*保存的元素key与之前的元素从右向左逐个比较*/
     9             arr[j+1]=arr[j];/*移动(向后赋值)*/
    10             j--;
    11         }
    12         arr[j+1]=key;/*j--退出,恢复正确值j+1*/
    13     }
    14 }
    15 int main()
    16 {
    17     int i, arr[5]={9,8,1,4,3};
    18     InsertSort(arr,5);
    19     for(i=0; i<5; ++i)
    20         printf("%d ",arr[i]);
    21     printf("\n");
    22     return 0;
    23 }

            2.交换法

        先把数组第0个元素看作是有序的,第1个元素之后是无序的,把第1个元素,与第0个元素进行比较,如果第0个元素大(或小),交换,实现插入,第0、1元素有序;然后,第2个元素,与其之前的有序元素从右向左,逐个比较,交换,实现原来第2个元素的插入、有序;第3、4...以此类推。

      c语言代码:

     1 /*插入排序*/
     2 #include <stdio.h>
     3 
     4 void Swap(int *a, int *b);
     5 void InsertSort(int *arr, int n);
     6 
     7 int main()
     8 {
     9     int i, arr[5]={9,8,1,4,3};
    10     InsertSort(arr,5);
    11     for(i=0; i<5; ++i)
    12         printf("%d ",arr[i]);
    13     printf("\n");
    14     return 0;
    15 }
    16 
    17 void Swap(int *a, int *b)
    18 {
    19     int t = *a;
    20     *a = *b;
    21     *b = t;
    22 }
    23 
    24 void InsertSort(int *arr, int n)
    25 {
    26     int i;
    27     for(i=1; i<n; ++i){/*第0个元素有序,从第1个元素向右无序*/
    28         int j=i;/*从第i个元素开始*/
    29         while(j>0 && arr[j-1]>arr[j]){/*与之前的元素从右向左逐个比较*/
    30             Swap(&arr[j-1],&arr[j]);/*交换,把原第i个元素的值向左推进*/
    31             j--;
    32         }
    33     }
    34 }

      

      二、插入排序的最好情况时间复杂度是O(N),最坏情况时间复杂度是O(N2),插入算法是稳定的;逆序对数即交换次数,如果序列基本有序,插入排序简单且高效,提高算法效率,每次不止消掉一个逆序对,即每次交换间隔较远的两个元素

    void InsertionSort( ElementType A[], int N )
    { /* 插入排序 */
         int P, i;
         ElementType Tmp;
          
         for ( P=1; P<N; P++ ) {
             Tmp = A[P]; /* 取出未排序序列中的第一个元素*/
             for ( i=P; i>0 && A[i-1]>Tmp; i-- )
                 A[i] = A[i-1]; /*依次与已排序序列中元素比较并右移*/
             A[i] = Tmp; /* 放进合适的位置 */
         }
    }

       

      三、希尔排序,是不稳定的,

    增量序列,Dk间隔有序的序列,在进行Dk-1间隔排序后,Dk间隔依然是有序的

    void ShellSort( ElementType A[], int N )
    { /* 希尔排序 - 用Sedgewick增量序列 */
         int Si, D, P, i;
         ElementType Tmp;
         /* 这里只列出一小部分增量 */
         int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0};
          
         for ( Si=0; Sedgewick[Si]>=N; Si++ ) 
             ; /* 初始的增量Sedgewick[Si]不能超过待排序列长度 */
     
         for ( D=Sedgewick[Si]; D>0; D=Sedgewick[++Si] )
             for ( P=D; P<N; P++ ) { /* 插入排序*/
                 Tmp = A[P];
                 for ( i=P; i>=D && A[i-D]>Tmp; i-=D )
                     A[i] = A[i-D];
                 A[i] = Tmp;
             }
    }
  • 相关阅读:
    我眼中的SCRUM
    文本转换程序
    免费接口
    看板,敏捷的另一种实现方式
    Android Asynchronous Http Client-Android异步网络请求客户端接口
    hdu4753 Fishhead’s Little Game 状态压缩,总和一定的博弈
    dbcp、c3p0、jdbc常用连接配置
    IE安全分析
    redis入侵小结
    heartbleed漏洞利用
  • 原文地址:https://www.cnblogs.com/GoldenEllipsis/p/10167475.html
Copyright © 2011-2022 走看看