排序算法分为外部排序和内部排序,插入排序属于内部排序,内部排序即整个排序过程不需要访问外存,仅在内存中就能完成,这类问题成为内部排序。
插入排序又分为两种:直接插入排序,希尔排序。
直接插入排序:
将第一个和第二个元素排好序,然后将第3个元素插入到已经排好序的元素中,一次类推(插入排序最好的情况就是数组已经有序了)
直接插入排序的算法思想:
将数组中的所有元素依次从该元素所在位置往前和前面已经排好序的元素比较,如果选择的元素比已排序的元素小,就交换两个元素;如果大于等于前面的元素,则不变,直到全部的元素都比较过为止。因此,直接插入排序分为两个循环:
外部循环遍历所有未排序的元素;
内部循环将选中的元素与之前已经排好序的元素依次对比,如果小于则交换。
void InsertSort(int a[], int num)
{
for (int i = 1; i < num; i++) { //默认第0个元素已经排好序
if (a[i] < a[i - 1]) {
int j = i - 1; //如果小于前一个元素,记录前一个元素下表
int tmp = a[i]; //哨兵,记录当前元素,等待插入
while (tmp < a[j]) {
a[j + 1] = a[j]; //向后移动
j--;
if (j < 0)
break;
}
a[j + 1] = tmp; //插入
}
}
}
int main()
{
int a[10] = { 9,3,5,2,7,6,10,1,8,4 };
InsertSort(a, 10);
for (auto e : a) {
cout << e << ' ';
}
cout << endl;
return 0;
}
希尔排序:
插入排序每次只能操作一个元素,效率较低。所以有了希尔排序,希尔排序也称递减增量排序,是插入排序的一种更高效的方案,但是希尔排序是非稳定排序,所谓的稳定排序指,排序之后,两个相等的元素还在自己原来的位置,比如数组中有元素a,b。a=b,起初位置是a b 排完序之后还是a b而不是b a,非稳定排序指这两个元素位置可能发生变化成b a。
希尔排序的算法思想:
先将整个待排序序列分为若干个子序列,分别进行直接插入排序,待整个序列基本有序的时候,再对全体成员进行直接插入排序。
#include <iostream>
using namespace std;
void InsertSort(int a[], int num, int k)
{
for (int i = k; i < num; i++) {
if (a[i] < a[i - k]) {
int j = i - k;
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
void ShellSort(int a[], int num)
{
int k = num / 2;
while (k >= 1) {
InsertSort(a, num, k);
k = k / 2;
}
}
int main()
{
int a[10] = { 9,3,5,2,7,6,10,1,8,4 };
ShellSort(a, 10);
for (auto e : a) {
cout << e << ' ';
}
cout << endl;
return 0;
}