🔥博客主页:小王又困了
📚系列专栏:数据结构
🌟人之为学,不日近则日退
❤️感谢大家点赞👍收藏⭐评论✍️
目录
🗒️前言:
一、排序的概念及其分类
📒1.1排序的概念
📒1.2排序的分类
二、插入排序
📒2.1直接插入排序
🎀2.1.1直接插入排序的思想
🎀2.1.2排序步骤
- 将有序数据的最后一个元素的下标记为 end,则第一个待插入元素的下标为 end+1,记作 tmp
- 将 tmp 与有序数据从后向前依次比较
- 如果 tmp < a[end],就将 a[end] 向后移动,end--,再去找下一位进行比较
- 直到 tmp > a[end] 或者 end < 0,将 tmp 插入到 end+1 的位置
- 重复步骤,就可以实现排序
🎀2.1.3代码实现
void InsertSort(int* a, int n)
{
for (int i = 0; i < n - 1; i++)
{
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + 1] = a[end];
}
else
{
break;
}
--end;
}
a[end + 1] = tmp;
}
}
🎀2.1.4直接插入排序的特点
📒2.2希尔排序
🎀2.2.1希尔排序法的基本思想
🎀2.2.2排序步骤
- 选取一个合适的 gap 作为间距
- 将间距为 gap 的数据分为一组,分成 gap 组
- 每一组数据都进行直接插入排序,使数据接近有序
- 不断缩小间距,当 gap==1 时,数据进行直接插入排序,实现排序
🎀2.2.3代码实现
void ShellSort(int* a, int n)
{
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = 0; i < n - gap; i++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
将 i+=gap 改为 i++, 将分组排序,变为多组并排,减少了循环。
gap = gap / 3 + 1 的目的是保证 gap 最后的值为1.
🎀2.2.4希尔排序的特点
三、选择排序
📒3.1直接选择排序
🎀3.1.1直接选择排序的思想
🎀3.1.2排序步骤
- 先遍历一遍数组,找到最大的数和最小的数,记住它们的下标
- 将最小的数交换到数组的左边,最大的数交换到数组的右边
- begin++,end--,重复上述步骤,即可实现排序
🎀3.1.3代码实现
void SelectSort(int* a, int n)
{
int begin = 0, end = n - 1;
while (begin < end)
{
int min = begin, max = begin;
for (int i = begin + 1; i <= end; i++)
{
if (a[min] > a[i])
{
min = i;
}
if (a[max] < a[i])
{
max = i;
}
}
Swap(&a[min], &a[begin]);
if (max == begin)
{
max = min;
}
Swap(&a[max], &a[end]);
begin++;
end--;
}
}
我们要注意,当 a[max] 在数组元素的第一个,进行 Swap(&a[min], &a[begin]) 后,最大的元素的位置就发生了改变,要及时修改 max。
🎀3.1.4直接选择排序的特点
📒3.2堆排序
🎀3.2.1堆排序的思想
🎀3.2.2排序步骤
- 将待排序的数据构造成一个大堆,当前堆的根节点(堆顶)就是该组数组中最大的元素;
- 将堆顶元素和最后一个元素交换,将剩下的节点重新构造成一个大堆;
- 重复步骤2,每次循环构建都能找到当前堆中的最大值,并通过交换的方式把它放到该大堆的尾部,直至所有元素全部有序
🎀3.2.3代码实现
void HeapSort(int* a, int n)
{
//第一步:建大堆
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(a, n, i);
}
//第二步:堆删除思想进行排序(依次选数,调堆)
for (int i = n - 1; i > 0; i--)
{
Swap(&a[0], &a[i]);
AdjustDown(a, i , 0);
}
}
void AdjustDown(HPDataType* a, int n, int parent)
{
//默认左孩子是较小的
int child = parent * 2 + 1;
while (child < n)
{
// 找出小的那个孩子
if (child + 1 < n && a[child + 1] < a[child])
{
++child;
}
if (a[child] < a[parent])
{
Swap(&a[child], &a[parent]);
// 继续往下调整
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}