插入排序

1、排序的基本术语

在排序问题中,通常将数据元素称为记录(record)。

(1)数据表

它是指排序记录的有限集合。

(2)关键字

记录中的某一个可以用来标识一个记录的数据项,被称为关键字项,该数据项的值称为关键字(key)。

(3)排序的稳定性

如果待排序的文件中,存在多个关键字相同的记录,排序前和排序后,这些记录的相对次序保持不变,则称这种排序方法是稳定的。

2、排序算法性能评价

(1)算法的执行时间

(2)所需的辅助空间

辅助空间是指在排序记录个数一定的条件下,除了存放待排序记录占用的存储空间外,执行算法所需要的其他存储空间。若排序算法所需的辅助空间并不依赖于问题的规模n,则辅助空间是O(1),则称之为就地排序(in-place sort)。非就地排序一般要求的辅助空间为O(n)。

(3)算法本身的复杂程度

3、插入排序

插入排序就是按关键字大小将一个待排序记录插入到一个有序表的适当位置,并且插入后使表仍然是有序的。因为源表是有序的,在插入一个记录时,要寻找适当的插入位置,可以采用顺序查找法,也可以采用折半查找法。相应地,插入排序有直接插入排序法和折半插入排序法。另外,还可以对插入排序稍加改进,产生一种排序方法——希尔排序。

当排序表中记录个数比较少或者接近有序时,直接插入排序算法的效率比较高。

  1 #include "stdafx.h"
  2 #include <iostream>
  3 using namespace std;
  4 void InsertSort(int a[], int n); //直接插入排序
  5 void BInsertSort(int a[], int n);//折半插入排序
  6 void ShellSort(int a[], int n);//希尔排序
  7 /*********************************************
  8 *    直接插入排序
  9 *    最好情况下,数组正序,O(n)
 10 *    最差情况,数组逆序,时间复杂度O(n^2)
 11 *    平均复杂度O(n^2),算法是稳定的
 12 ***********************************************/
 13 void InsertSort(int a[], int n)
 14 {
 15     int i,j,k,target;
 16     for(i=1;i<n;i++)
 17     {
 18         j = i;
 19         target = a[i];    //保存a[i],并设置哨兵target
 20         while(j>0 && target<a[j-1]) //在有序区中查找a[i]的合适位置
 21         {
 22             a[j] = a[j-1]; //记录后移
 23             j--;
 24         }
 25         a[j] = target; //将r[i]插入到j位置
 26     }
 27     for(k=0;k<n;k++)
 28     {
 29         cout<<a[k]<<" ";
 30     }
 31     cout<<endl;
 32 }
 33 /*********************************************
 34 *    折半插入排序,仅减少了关键字之间的比较次数
 35 *    平均复杂度O(n^2),算法是稳定的
 36 ***********************************************/
 37 void BInsertSort(int a[], int n)
 38 {
 39     int i,j,k,left,mid,right,target;
 40     for(i=1;i<n;i++)
 41     {
 42         target = a[i];    //保存a[i],并设置哨兵target
 43         left = 0;
 44         right = i - 1;
 45         while(left<=right)
 46         {
 47             mid = (left + right)/2;    //取中间位置
 48             if(target<a[mid])
 49             {
 50                 right = mid - 1;    //插入点在前半部分
 51             }
 52             else
 53             {
 54                 left = mid + 1;        //插入点在后半部分
 55             }
 56         }
 57         for(j=i;j>=right+1;j--)
 58         {
 59             a[j] = a[j-1];        //记录后移
 60         }
 61         a[right+1] = target;    //将a[i]插入到right+1位置
 62     }
 63     for(k=0;k<n;k++)
 64     {
 65         cout<<a[k]<<" ";
 66     }
 67     cout<<endl;
 68 }
 69 /*****************************************
 70 *    希尔排序
 71 *    平均时间复杂度O(n^1.3)
 72 *    不稳定的排序
 73 *****************************************/
 74 void ShellSort(int a[], int n)
 75 {
 76     int i,j,k,gap,temp;
 77     for(gap=n/2;gap>0;gap/=2)
 78     {
 79         for(i=gap;i<n;i++)
 80         {
 81             for(j=i-gap;j>=0;j=j-gap)
 82             {
 83                 if(a[j]>a[j+gap])
 84                 {
 85                     temp = a[j];
 86                     a[j] = a[j+gap];
 87                     a[j+gap] = temp;
 88                 }
 89             }
 90         }
 91     }
 92 
 93     for(k=0;k<n;k++)
 94     {
 95         cout<<a[k]<<" ";
 96     }
 97     cout<<endl;
 98 }
 99 
100 int _tmain(int argc, _TCHAR* argv[])
101 {
102     const int NUM = 10;
103     int i = NUM;
104     int a[NUM]={14,4,4,1,9,8,4,75,6,4};
105     InsertSort(a,NUM);
106     BInsertSort(a,NUM);
107     ShellSort(a,NUM);
108     getchar();
109     return 0;
110 }
View Code
原文地址:https://www.cnblogs.com/iambitiousman/p/3372496.html