目录
1. 直接插入排序
1.1 概念
插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动 。
1.2. 动图效果
1.3. 思路(配合动图理解)
用两个指针end,tmp。end指针是指向每趟排序末尾的元素,end从第二元素开始往后走(第一个元素无需插入),tmp指针从end指针开始往前,判断tmp指向的元素是否小于(升序)end指向的元素,如果小于end,tmp++,直到走到小于等于end(注意:别走到过头了),tmp指向的元素和end指向的元素交换位置,end++,然后不循环,直之end走到末尾,插入排序就完成了。
1.4. 代码
//交换
void Swap(int* left, int * right)
{
int tmp = *left;
*left = *right;
*right = tmp;
}
//直接插入排序
void InsertSort(int* a, int n)
{
//一开始指向第二个元素
int end = 1;
while (end < n)
{
int tmp = end;
while (tmp > 0)
{
if (a[tmp] < a[tmp - 1])
{
//交换两个元素
Swap(&a[tmp], &a[tmp - 1]);
--tmp;
}
else
{
break;
}
}
++end;
}
}
2. 希尔排序
2.1 概念
希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。
2.2 动图效果
2.3 思路 (配合动图理解)
希尔排序不同于直接插入排序就是多了个分组,如下图所见,我把数据分成了3组。
对分组了的数据,内部进行排序(每组单独进行直接排序)。
gap--,分组。
组内排序
gap--,到gap == 1了, 分组变为了1,相当于是直接插入排序。
这样就完成排序了。
2.4 代码
我这里gap优化了一下,每次是数据总量的一半。
void ShellSort(int* a, int n)
{
int gap = n;
while (gap >1)
{
gap /= 2;
for (int j = 0;j<gap;j++)
{
for (int i = j+gap;i<n;i+=gap)
{
int end = i-gap;
int tmp = a[gap + end];
//end向前走
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
//出来就覆盖值,到该到的位置
}
a[end+gap] = tmp;
}
}
}
}
3. 时间复杂度
3.1 直接插入排序
时间复杂度为O(n^2)。
首先,它要遍历每个数据拿取元素(n),然后将拿取的数据往前对比(n), 合起来就是
O(n^2)。
3.2 希尔排序
时间复杂度为O(n^1.3)。
它的时间复杂度比较复杂,这里不做过多说明。