zoukankan      html  css  js  c++  java
  • 排序算法(五)插入排序

      

      从一个乱序的数组中依次取值,插入到一个已经排好序的数组中。 这看起来好像要两个数组才能完成,但如果只想在同一个数组内排序,也是可以的。此时需要想象出两个区域:前方有序区和后方乱序区。

      设数组为a[0...n-1]。

    1. 初始时,a[0]自成1个有序区,无序区为a[1...n-1]。令i=1
    2. 将a[i]并入当前的有序区a[0...i-1]中形成a[0...i]的有序区间。
    3. i++并重复第二步直到i==n-1,排序完成。

     

      下面给出严格按照定义书写的代码(由小到大排序):

     1 void insertSort1(int data[], int len)
     2 {
     3     int i, j, k;
     4     for (i = 1; i < len; i++)
     5     {
     6         //为data[i]在前面的data[0...i-1]有序区间中找一个合适的位置
     7         for (j = i - 1; j >= 0;j--)
     8         if (data[j] < data[i])//找到一个位置时,即停止
     9             break;
    10 
    11         //如找到一个合适的位置
    12         if (j != i - 1)
    13         {
    14             //将比data[i]大的数据向后移
    15             int temp = data[i];
    16             for (k = i - 1; k>j; k--)
    17                 data[k + 1] = data[k];
    18 
    19             //执行完上面的for循环后,k=j,而因为temp>data[j],所以将temp放在序号j的后面一个位置中
    20             data[k + 1] = temp;
    21         }
    22     }
    23 }

      这样的代码太长了,不够清晰。现在进行一下改写,将搜索和数据后移这两个步骤合并。即每次data[i]先和前面一个数据data[i-1](因为无序区间中,i从1开始)比较,如果data[i]>data[i-1],说明data[0...i]也是有序的,无须调整。否则,就令j=i-1,temp=data[i].然后一边将数据data[j]向后移动一边向前搜索,当有数据data[j]<data[i]时停止,并将temp放到data[j+1]处。

     1 /*
     2 @将搜索和数据后移这两个步骤合并
     3 */
     4 void insertSort2(int data[], int len)
     5 {
     6     int i, j;
     7     for (i = 1; i < len;i++)
     8         if (data[i] < data[i - 1])//当无序区间中的元素比有序区间的小时,说明需要调整
     9         {
    10             int temp = data[i];//临时存放要调整的元素
    11             for (j = i - 1; j >= 0 && data[j]>temp; j--)//当有数据data[j]<data[i]时(即data[j]<temp)停止并将temp放到data[j+1]
    12                 data[j + 1] = data[j];
    13             data[j + 1] = temp;
    14         }
    15 }

      也可对将data[j]插入到前面data[0...j-1]的有序区间所用的方法进行改写,用数据交换代替数据后移。如果data[j]前一个数据data[j-1]>data[j],就交换data[j]和data[j-1],再j--知道data[j-1]<=data[j]。这样就可以实现将一个新数据新并入到有序区间。

     1 /*
     2 @用数据交换代替数据后移
     3 */
     4 void insertSort3(int data[], int len)
     5 {
     6     int i, j;
     7     for (i = 1; i < len;i++)
     8         for (j = i - 1; j >= 0 && data[j]>data[j + 1]; j--)
     9             swap(data[j], data[j + 1]);
    10 }

      

    完整代码


     1 /*
     2 @theme:简单插入排序
     3 @author:CodingMengmeng
     4 @date:2016-11-10 12:16:32
     5 @email:sprint_meng0116@163.com
     6 */
     7 #include <iostream>
     8 using namespace std;
     9 /*
    10 @严格按照定义书写的代码
    11 */
    12 void insertSort1(int data[], int len)
    13 {
    14     int i, j, k;
    15     for (i = 1; i < len; i++)
    16     {
    17         //为data[i]在前面的data[0...i-1]有序区间中找一个合适的位置
    18         for (j = i - 1; j >= 0;j--)
    19         if (data[j] < data[i])//找到一个位置时,即停止
    20             break;
    21 
    22         //如找到一个合适的位置
    23         if (j != i - 1)
    24         {
    25             //将比data[i]大的数据向后移
    26             int temp = data[i];
    27             for (k = i - 1; k>j; k--)
    28                 data[k + 1] = data[k];
    29 
    30             //执行完上面的for循环后,k=j,而因为temp>data[j],所以将temp放在序号j的后面一个位置中
    31             data[k + 1] = temp;
    32         }
    33     }
    34 }
    35 
    36 /*
    37 @将搜索和数据后移这两个步骤合并
    38 */
    39 void insertSort2(int data[], int len)
    40 {
    41     int i, j;
    42     for (i = 1; i < len;i++)
    43         if (data[i] < data[i - 1])//当无序区间中的元素比有序区间的小时,说明需要调整
    44         {
    45             int temp = data[i];//临时存放要调整的元素
    46             for (j = i - 1; j >= 0 && data[j]>temp; j--)//当有数据data[j]<data[i]时(即data[j]<temp)停止并将temp放到data[j+1]
    47                 data[j + 1] = data[j];
    48             data[j + 1] = temp;
    49         }
    50 }
    51 
    52 /*
    53 @用数据交换代替数据后移
    54 */
    55 void insertSort3(int data[], int len)
    56 {
    57     int i, j;
    58     for (i = 1; i < len;i++)
    59         for (j = i - 1; j >= 0 && data[j]>data[j + 1]; j--)
    60             swap(data[j], data[j + 1]);
    61 }
    62 int main(void)
    63 {
    64     int len;//要排序数组的长度
    65     cout << "要排序数组的长度为:" << endl;
    66     cin >> len;
    67     int* data = (int*)malloc((len)*(sizeof(int)));//动态分配大小为len的int型数组
    68     memset(data, 0, (len)*sizeof(int));//初始化数组的值为0,否则会出错
    69 
    70     //读入数据
    71     cout << "请输入" << len << "个数据:" << endl;
    72     for (int i = 0; i < len; i++)
    73         cin >> data[i];
    74     insertSort3(data, len);
    75     //输出排序后的结果
    76     cout << "插入排序后的结果:" << endl;
    77     for (int i = 0; i < len; i++)
    78         cout << data[i] << " ";
    79 
    80     return 0;
    81 }

    运行结果:

  • 相关阅读:
    355. Design Twitter
    54. Spiral Matrix
    143. Reorder List
    324. Wiggle Sort II
    365. Water and Jug Problem
    洛谷 P3527 [POI2011]MET-Meteors 解题报告
    洛谷 P4592 [TJOI2018]异或 解题报告
    单调序列 解题报告
    洛谷 P4735 最大异或和 解题报告
    洛谷 P1527 [国家集训队]矩阵乘法 解题报告
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/6050332.html
Copyright © 2011-2022 走看看