• 数据结构之——插入排序


    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)希尔排序是不稳定算法,另外两个插入算法是稳定算法。

  • 相关阅读:
    POJ 2502 Subway(最短路径)
    HDU 1430 魔板
    HDU 1043 POJ 1077 八数码问题
    POJ 2576 Tug of War 随机算法(非正规解法)
    什么是COM
    6.0的版本的 tc,不支持大漠对象做数组吗?
    Q键连发。按住Q键则连发。松开则停止1。
    Q键连发。按住Q键 则连发。松开则停止2。
    特殊符号。
    僵尸_另类的生命体。
  • 原文地址:https://www.cnblogs.com/zhiyinglky/p/4803534.html
Copyright © 2020-2023  润新知