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