本篇博客介绍的是排序算法(一) 插入排序:直接插入排序和希尔排序
插入排序的思想:在一个已排好序的记录子集的基础上,每一步将下一个待排序的记录语序插入到已排好序的记录子集中,直到将所有待排记录全部插入为止。
一、直接插入排序
直接插入排序是一种最基本的插入排序方法,其基本操作是将第i个记录插入到前面i-1个已排好的记录中。
直接插入排序的思想:将第i个元素的关键字Ki,顺次与前面记录的关键字进行比较,将大于关键字Ki的元素依次向后移动一个位置,直到遇到一个小于或等于的Ki的元素Kj,此时Kj后面必定是一个空位置,将i元素插入即可。
直接插入排序的思路:完整的直接插入排序是从i=1开始,也就是将第一个记录视为已排好序的单元素子集和,然后将第二个元素记录插入到单元素子集和中。i从2循环到n,即可实现完整的直接插入排序。
(1)使用监视哨temp = r[i] ,保存待插入的记录,
(2)比较元素,找到插入的位置并搬移元素(第一次从i=1开始,)
(3) 将元素插入位置
代码: 升序排序
void InsertSort(int array[], size_t size) //升序
{
for (size_t i = 1; i < size; ++i)
{
int temp = array[i];
int pos = i - 1;
while (pos >= 0 && array[pos] > temp) //小心数组越界
{
array[pos + 1] = array[pos];//搬移元素
--pos;
}
array[pos + 1] = temp;
}
}
算法分析:
空间复杂度:它只需要一个辅助空间,所以空间复杂度为O(1)
时间复杂度:主要时间耗费在比较和搬移元素上。
对于一趟插入排序,算法的while循环的次数取决于待插入记录与前i-1个记录的关系上
最好的情况(顺序):while循环只执行一次,且不移动
最坏的情况(逆序):while循环中关键字比较和移动记录的次数为i-1.
时间复杂度为T(n) = O(n^2)
稳定性:直接插入排序是稳定的,由于while循环判断条件array[pos] >temp保证了后面出现的关键字不可能插入到前面与之相同的关键字之前。
二、折半插入排序
基本思想:在上面插入排序的基础上,在while循环中比较时采用折半查找插入位置,性能优于顺序查找
代码:
//在查找元素时 用二分查找来优化[]
void InsertSort_P(int arr[],size_t size)
{
for (size_t idx = 1; idx < size; ++idx)
{
int temp = arr[idx];
int left = 0;
int right = idx -1;
int mid = 0;
//查找插入的位置
while (left <= right)
{
mid = left + ((right - left) >> 1);
if (temp < arr[mid]) //相等的话,插入其后面
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
//跳出循环,left为插入的位置
int pos = left;
for (int index = idx -1; index >= pos ; --index)
{
arr[index + 1] = arr[index];
}
arr[pos] = temp;
}
}时间复杂度:O(n^2)
三、希尔排序(缩小增量排序算法)
基本思想:将待排序记录序列分割为若干个“较稀疏的”子序列,分别进行插入排序。
把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。
随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。
void ShellSort(int arr[],size_t size)
{
int gsp = size;
while (gsp > 1)
{
gsp = gsp / 3 + 1;
for (size_t idx = gsp; idx < size; idx+=gsp)
{
int temp = arr[idx];
int pos = idx - gsp;
while (pos >= 0 && arr[pos] > temp)
{
//搬移,从后向前搬移
arr[pos + gsp] = arr[pos];
pos = pos - gsp;
}
arr[pos + gsp] = temp;
}
}
}关于gsp的取法,最初希尔Shell提取出d = n/2,再取d=n/2,知道d=1;该思路的缺点,奇数位置的元素在最后一步才会与偶数位置进行比较,使得希尔排序效率降低。
时间复杂度:O(n^1.25)
稳定性:不稳定的。反例{2,4,1,2}
本文详细介绍直接插入排序和希尔排序两种排序算法。直接插入排序通过逐步插入元素并调整位置实现排序;希尔排序则通过分组并逐步减少增量进行排序。文章还提供了算法的时间复杂度和稳定性分析。
1492

被折叠的 条评论
为什么被折叠?



