【转载】八大排序法之直接插入排序

基本思想

        在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

 

直接插入排序(straight insertion sort)的做法

        每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。

        第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。

        直接插入排序属于稳定的排序,最坏时间复杂性为O(n^2),空间复杂度为O(1)。

        直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。

        值得注意的是,我们必需用一个存储空间来保存当前待比较的数值,因为当一趟比较完成时,我们要将待比较数值置入比它小的数值的后一位 插入排序类似玩牌时整理手中纸牌的过程。插入排序的基本方法是:每步将一个待排序的记录按其关键字的大小插到前面已经排序的序列中的适当位置,直到全部记录插入完毕为止。

哨兵的作用

算法中引进的附加记录R[0]称监视哨或哨兵(Sentinel)

哨兵有两个作用:

1进人查找(插入位置)循环之前,它保存了R[i]的副本,使不致于因记录后移而丢失R[i]的内容;

2它的主要作用是:在查找循环中监视下标变量j是否越界。一旦越界(j=0),因为R[0].key和自己比较,循环判定条件不成立使得查找循环结束,从而避免了在该循环内的每一次均要检测j是否越界(即省略了循环判定条件“j>=1”)

源代码(不带哨兵)

  1. #include “stdio.h”  
  2. #define SIZE 10  
  3.   
  4. void InsertSortArray(int arr[] , int n)   
  5. {  
  6.     for(int i=1; i<n; i++)   
  7.     {  
  8.         int temp=arr[i];  
  9.         int j=i-1;  
  10.         while (j>=0 && arr[j]>temp)  
  11.         {   
  12.             arr[j+1]=arr[j];    
  13.             j–;   
  14.         }   
  15.         arr[j+1]=temp;   
  16.     }  
  17. }  
  18. int main()  
  19. {  
  20.     int number[SIZE] = {34, 89, 9, 12, 3, 78, 100, 2, 39, 1};       
  21.     InsertSortArray(number,SIZE);       
  22.     for (int i = 0; i < SIZE; i++)  
  23.     {          
  24.         printf(”%d ”, number[i]);      
  25.     }      
  26.     printf(”\n”);  
  27.     return 0;  
  28. }  
#include "stdio.h"




#define SIZE 10 void InsertSortArray(int arr[] , int n) { for(int i=1; i<n; i++) { int temp=arr[i]; int j=i-1; while (j>=0 && arr[j]>temp) { arr[j+1]=arr[j]; j--; } arr[j+1]=temp; } } int main() { int number[SIZE] = {34, 89, 9, 12, 3, 78, 100, 2, 39, 1}; InsertSortArray(number,SIZE); for (int i = 0; i < SIZE; i++) { printf("%d ", number[i]); } printf("\n"); return 0; }

运行截图

 

基本思想

        在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

 

直接插入排序(straight insertion sort)的做法

        每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。

        第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。

        直接插入排序属于稳定的排序,最坏时间复杂性为O(n^2),空间复杂度为O(1)。

        直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。

        值得注意的是,我们必需用一个存储空间来保存当前待比较的数值,因为当一趟比较完成时,我们要将待比较数值置入比它小的数值的后一位 插入排序类似玩牌时整理手中纸牌的过程。插入排序的基本方法是:每步将一个待排序的记录按其关键字的大小插到前面已经排序的序列中的适当位置,直到全部记录插入完毕为止。

哨兵的作用

算法中引进的附加记录R[0]称监视哨或哨兵(Sentinel)

哨兵有两个作用:

1进人查找(插入位置)循环之前,它保存了R[i]的副本,使不致于因记录后移而丢失R[i]的内容;

2它的主要作用是:在查找循环中监视下标变量j是否越界。一旦越界(j=0),因为R[0].key和自己比较,循环判定条件不成立使得查找循环结束,从而避免了在该循环内的每一次均要检测j是否越界(即省略了循环判定条件“j>=1”)

源代码(不带哨兵)

  1. #include “stdio.h”  
  2. #define SIZE 10  
  3.   
  4. void InsertSortArray(int arr[] , int n)   
  5. {  
  6.     for(int i=1; i<n; i++)   
  7.     {  
  8.         int temp=arr[i];  
  9.         int j=i-1;  
  10.         while (j>=0 && arr[j]>temp)  
  11.         {   
  12.             arr[j+1]=arr[j];    
  13.             j–;   
  14.         }   
  15.         arr[j+1]=temp;   
  16.     }  
  17. }  
  18. int main()  
  19. {  
  20.     int number[SIZE] = {34, 89, 9, 12, 3, 78, 100, 2, 39, 1};       
  21.     InsertSortArray(number,SIZE);       
  22.     for (int i = 0; i < SIZE; i++)  
  23.     {          
  24.         printf(”%d ”, number[i]);      
  25.     }      
  26.     printf(”\n”);  
  27.     return 0;  
  28. }  
#include "stdio.h"




猜你喜欢

转载自blog.csdn.net/qq_34621771/article/details/75316699