数据结构之——插入排序

1.排序中一些概念

(1)算法稳定性:如果待排序的序列中两个元素A和B,对应的关键字key_A和key_B相等,且在原序列中A在B前面。如果使用某一排序算法后,A仍在B前面,则称这个算法是稳定的,否则称该算法不稳定。值得注意的是,排序算法稳定与否并不能衡量一个算法的优劣,主要是用其来描述算法的性质。

(2)在排序过程中,根据数据元素是否完全在内存中,可以及将算法分为内部排序和外部排序。如果排序期间元素全部在内存中,则称之为内部排序;若排序期间元素无法全部同时放入内存中,则将其称之为外部排序。

2.三种插入排序算法的实现

  1 #include<iostream>
  2 using namespace std;
  3 //声明打印辅助函数
  4 void printArray(int array[], int length);
  5 //声明直接插入排序函数
  6 void InsertionSort(int array[], int length);
  7 //定义折半插入排序函数
  8 void SplitHalfInsertionSort(int array[], int length);
  9 //定义希尔排序
 10 void ShellSort(int array[], int length);
 11 
 12 int main()
 13 {
 14     int array[] = { 12, 3, 6, 4, 27, 9 };
 15     int length = sizeof(array) / sizeof(*array);
 16     cout << "排序前序列为:" << endl;
 17     printArray(array, length);
 18     InsertionSort(array, length);
 19     cout << endl << "直接插入排序排序后序列为:" << endl;
 20     printArray(array, length);
 21     cout << endl;
 22     SplitHalfInsertionSort(array, length);
 23     cout << endl << "折半插入排序排序后序列为:" << endl;
 24     printArray(array, length);
 25     cout << endl;
 26     ShellSort(array, length);
 27     cout << endl << "Shell插入排序排序后序列为:" << endl;
 28     printArray(array, length);
 29     cout << endl;
 30     system("pause");
 31     return 0;
 32 }
 33 
 34 void printArray(int array[], int length)
 35 {
 36     for (int i = 0; i < length;i++)
 37     {
 38         if (i == length - 1)
 39             cout << array[i];
 40         else
 41             cout << array[i] << ",";
 42     }
 43 }
 44 
 45 void InsertionSort(int array[], int length)
 46 {
 47     //直接从1号元素开始,加快速度
 48     for (int i = 1; i < length;i++)
 49     {
 50         int p = i;
 51         //记录要插入元素
 52         int tmp = array[i];
 53         for (int j = i - 1; j >=0 ; j--)
 54         {
 55             if (array[j]>tmp)
 56             {
 57                 array[j + 1] = array[j];
 58                 //记录待插入的位置
 59                 p = j;
 60             }
 61         }
 62         //在正确位置插入元素
 63         array[p] = tmp;
 64     }
 65 }
 66 
 67 void SplitHalfInsertionSort(int array[], int length)
 68 {
 69     //直接从1号元素开始,加快速度
 70     for (int i = 1; i < length; i++)
 71     {
 72         int mid, low = 0, high = i;
 73         //记录要插入元素
 74         int tmp = array[i];
 75         while (low<=high)
 76         {
 77             mid = (low + high) / 2;
 78             if (array[mid]>tmp)
 79             {
 80                 high = mid - 1;
 81             }
 82             else
 83             {
 84                 low = mid + 1;
 85             }
 86         }
 87         for (int j = i - 1; j >= high ;j--)
 88         {
 89             array[j + 1] = array[j];
 90         }
 91         //在正确位置插入元素
 92         array[high] = tmp;
 93     }
 94 }
 95 
 96 void ShellSort(int array[], int length)
 97 {
 98     int gap = length;
 99     do
100     {
101         gap = gap / 3 + 1;//经验取值
102         for (int i = gap; i<length; i += gap)
103         {
104             int k = i;
105             int tmp = array[k];
106             for (int j = i - gap; (j >= 0) && (array[j]>tmp); j -= gap)
107             {
108                 array[j + gap] = array[j];
109                 k = j;
110             }
111             array[k] = tmp;
112         }
113     } while (gap > 1);
114 }

 

3.插入排序讨论

(1)在待排序的元素基本有序的前提下,直接插入排序是效率最高的排序算法。

(2)对于同一待排序序列,折半插入排序和直接插入排序的差别在于元素的比较次数。

(3)在最后一趟开始之前,所有的元素可能都不在最终位置上的直接插入排序。

(4)希尔排序是不稳定算法,另外两个插入算法是稳定算法。

 

posted @ 2015-09-12 20:20  Linear_Luo  阅读(230)  评论(0编辑  收藏  举报