简介
本篇主要介绍两种排序方法:直接插入排序和希尔排序。
直接插入排序:将记录直接插入到已经排好序的有序表中,从而得到一个新的记录数加1的有序表。
希尔排序:缩小增量排序,一般与直接插入排序配合使用(当然用其他排序方法与希尔排序配合也是可以的),是直接插入排序的高效版本。
提示:下附代码,亲测可用
1. 直接插入排序
#include <iostream>
using namespace std;
void InsertSort(int k[], int n)
{
int count_1 = 0, count_2 = 0;
for (int i = 0; i < n-1; i++)
{
if (k[i] > k[i+1])
{
count_1++;
int tmp = k[i+1];
int j = i+1;
while (tmp < k[j-1] and j > 0)
{
count_2++;
k[j] = k[j-1];
j--;
}
k[j] = tmp;
}
}
for (int i = 0; i < n; i++)
{
cout << k[i] << " ";
}
cout << "count_1: " << count_1 << " count_2: " << count_2 << endl;
}
int main()
{
int k[] = {2, 1, 3, 4, 5, 6};
InsertSort(k, 6);
return 0;
}
运行结果如下:
1 2 3 4 5 6 count_1: 1 count_2: 1
若将输入改掉,则运行结果如下:
int k[] = {2, 1, 5, 7, 5, 6};
1 2 5 5 6 7 count_1: 3 count_2: 3
如排序算法(一)中所说,冒泡排序和选择排序的复杂度都为O(n2)。
直接插入排序的复杂度也为O(n2)。
直接插入排序适用于数据基本有序或者记录数少的情况。
2. 希尔排序
代码如下:
#include <iostream>
using namespace std;
void ShellSort(int k[], int n)
{
int count_1 = 0, count_2 = 0;
int gap = n;
cout << "before\n";
for (int i = 0; i < n; i++)
{
cout << k[i] << " ";
}
cout << endl;
do
{
gap = gap/3+1;
for (int i = 0; i < n-gap; i = i+1)
{
if (k[i] > k[i+gap])
{
count_1++;
int tmp = k[i+gap];
int j = i+gap;
while (tmp < k[j-gap] and j > 0)
{
count_2++;
k[j] = k[j-gap];
j-=gap;
}
k[j] = tmp;
}
}
cout << "gap: " << gap << endl;
for (int i = 0; i < n; i++)
{
cout << k[i] << " ";
}
cout << endl;
} while (gap > 1);
for (int i = 0; i < n; i++)
{
cout << k[i] << " ";
}
cout << "count_1: " << count_1 << " count_2: " << count_2 << endl;
}
int main()
{
int k[] = {2, 1, 5, 7, 5, 6, 10, 20, 15, 17, 16, 14, 13};
ShellSort(k, 13);
return 0;
}
运行结果如下:
before
2 1 5 7 5 6 10 20 15 17 16 14 13
gap: 5
2 1 5 7 5 6 10 13 15 17 16 14 20
gap: 2
2 1 5 6 5 7 10 13 15 14 16 17 20
gap: 1
1 2 5 5 6 7 10 13 14 15 16 17 20
1 2 5 5 6 7 10 13 14 15 16 17 20 count_1: 6 count_2: 6
希尔排序的算法复杂度更低一些,其复杂度为O(n(log(n))。
总结
总的来说,
冒泡排序、选择排序、直接插入排序的算法复杂度都为O(n2)。
希尔排序的实现,提高了排序算法的效率,复杂度从O(n2)提升为O(n(log(n))。