初级排序方法是最基本的排序方法,主要包括选择排序、插入排序以及希尔排序。
选择排序的原理是通过比较整个数组,找到最小值,然后将最小值与数组中第一个位置的数字进行交换,依靠循环来完成对整个数组的排序。对于一个由N个元素组成的数组,这种方法进行(N^2)/2次比较和N次交换,并且无论输入是什么情况,其比较和交换次数不变。
插入排序的原理则是比较该元素与其之前元素的大小,若偏小则交换位置,继续与新位置之前的元素进行比较,直到偏大为止,同样依靠循环来对整个数组进行排序。这种方法十分依赖输入,若输入的就是一组排好序的数组,则其进行N-1次比较和0次交换;若输入是最坏情况,则进行(N^2)/2次比较和(N^2)/2次交换。但平均而言,进行(N^2)/4次比较和(N^2)/4次交换,,一般而言是快于选择排序的。
希尔排序则在插入排序的基础上更进一步。它是通过将一个大数组分割成几个小数组,每个小数组的各个元素相隔h个元素,然后对每个小数组进行插入排序,完成后缩小h重复上述步骤,直到h<1。
三种排序方法c++代码如下:
template<typename T>
void _swap(T *t, int i, int j) //交换两个元素
{
T k;
k = t[i];
t[i] = t[j];
t[j] = k;
}
template<typename T>
void selection_sort(T *t) //选择排序
{
int N = sizeof(t) / sizeof(t[0]); //确定数组大小
for(int i = 0; i < N; i++)
{
int _min = i;
for(int j = i + 1; j < N; j++) //寻找位置i及i右侧数组的最小值
{
if(t[_min] > t[j])
{
_min = j;
}
}
_swap(t, i, _min); //交换i元素和最小元素
}
}
template<typename T>
void insertation_sort(T *t) //插入排序
{
int N = sizeof(t) / sizeof(t[0]);
for(int i = 1; i < N; i++) //哨兵:先找到最小值并放在t[0]处,用来避免边界判定
{
int _min = 0;
if(t[i] < t[_min]) _min = i;
_swap(t, 0, _min);
}
for(int i = 1; i < N; i++) //如果t[j]<t[j-1],则交换,直到t[j]>=t[j-1]
{
for(int j = i; t[j] < t[j-1]; j--)
_swap(t, j, j-1);
}
}
template<typename T>
void shell_sort(T *t) //希尔排序
{
int N = sizeof(t) / sizeof(t[0]);
int h = 1;
while(h < N/3)
h = h * 3 + 1; //h=1,4,13,40......
while(h > 0)
{
for(int i = h; i < N; i++)
for(int j = i; j > h && t[j] < t[j-h]; j -= h)
_swap(t, j, j-h);
h /= 3;
}
}