目录
一.选择排序
1.直接选择排序
选择排序(Selection Sort)是一种简单直观的排序算法。它的基本思想是每次遍历找到最小(或最大)的元素,然后将其放置在已排序序列的末尾。在每次遍历过程中,选择排序从未排序部分中选择最小(或最大)的元素,依次放置到已排序序列的末尾,直到所有元素都排序完毕。
这里我们选择同时选择最大和最小的的数,然后放在数组头和数组尾。
这是非常好理解的,如下图所示:
//直接选择排序
void SelectSort(int* a, int left,int right)
{
//注意这里的left和right都是下标
while (left < right)
{
int begin = left;
int end = right;
int max = end;
//注意这里的max和min的取值等于begin或者end,因为之后找最大和最小
//都是在begin和end的区间找,如果你将min赋值为0,就会出错
int min = end;
for (int i = begin; i <= end; i++)
{
if (a[i] > a[max])
{
max = i;//找出最大数的下标
}
if (a[i] < a[min])
{
min = i;//找出最小数的下标
}
}
Swap(&a[begin], &a[min]);
if (begin == max)
{
max = min;
}
Swap(&a[end], &a[max]);
left++;
right--;
}
}
注意这里还有一个很重要的点需要注意。 这个代码是什么意思?
if (begin == max)
{
max = min;
}
可以看出,交换后,并没有使得最大和最小的数,放在数组的两端,就是数组没交换前,max就已经和begin重叠了, 这样原本max的值就跑到min上面去了,所以我们要加这个代码,避免这种情况。
直接选择排序的特性总结:
1.
直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
2.
时间复杂度:
O(N^2)
3.
空间复杂度:
O(1)
4.
稳定性:不稳定
2.堆排序
这里我们把代码放在这里,之前小陈同学已经把堆排序写得很清楚了,不懂的可以点击链接跳转过去看:堆的实现+堆的应用
//交换函数
void Swap(int* p1, int* p2)
{
int ret = *p1;
*p1 = *p2;
*p2 = ret;
}
//向下调整法
void AdjustDown(int* a, int n, int parent)
{
int child = parent * 2 + 1;
while (child<n)
{
if (child+1<n&&a[child] < a[child + 1])
{
child++;
}
if (a[parent] < a[child])
{
Swap(&a[parent], &a[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
//堆排序
void HeapSort(int* a, int n)
{
for (int i = (n-1-1)/2; i>=0; i--)
{
AdjustDown(a, n, i);
}
int end = n - 1;
while (end > 0)
{
Swap(&a[end], &a[0]);
AdjustDown(a, end, 0);
end--;
}
}