直接选择排序
动图:
升序:把数组中最大的数与数组最后一个位置的值交换,再在除最后位置以外的数据里里重复上述操作。
void SelectSort(int*arr, int n)//升序
{
int i;
for (i = n - 1; i > 0; --i)//选最大数,换到最后面,倒着来
{
int max = arr[0];
int maxindex = 0;
for (int j = 0; j<=i; ++j)
{
if (arr[j] > max)
{
max = arr[j];
maxindex = j;//交换一次,记录max下标
}
}
int tmp = arr[maxindex];
arr[maxindex] = arr[i];
arr[i] = tmp;
}
}
我们可以看到直接选择排序时间复杂度是O(n*n)。它是一种不稳定的排序。
堆排序
有关堆的操作,请参考:小堆的实现
https://blog.csdn.net/vickers_xiaowei/article/details/80353014
用小堆来举例:
动图演示:
1、在小堆的基础上,把arr[0]数组的最后一个元素交换;
2、操作的元素个数-1;
3、由于第一步之后,堆不再是小堆,所以向下调整。
把数组调整成最堆,以及每次将元素交换后进行调整的时间复杂度都是O(logN),所以堆排序的时间复杂度为:O(N*logN)。堆排序不稳定。
void Swap(int* a, int*b)
{
int tmp = *a;
*a= *b;
*b = tmp;
}
void Adjustdown(int* arr, int from,int n)//小堆向下调整
{
int father = from;
int child = 2 * father + 1;
while (child<n)
{
if (child + 1 < n&&arr[child] > arr[child + 1])
child++;
if (child < n&&arr[child] < arr[father])
{
Swap(&arr[child], &arr[father]);
father = child;
child = 2 * father + 1;
}
else
break;
}
}
void HeapSort(int* arr, int n)//升序
{
int FirstNotLeaf = (n - 2) >> 1;//n-1是最后一个结点的下标
for (int i = FirstNotLeaf; i >= 0; --i)
Adjustdown(arr, i, n);;// 小堆建成
int j = n - 1;
while (j>0)
{
Swap(&arr[0], &arr[j]);
--j;
Adjustdown(arr, 0, j);
}
}
有关其它排序:
排序一——直接插入排序and希尔排序
https://blog.csdn.net/vickers_xiaowei/article/details/80613544
排序二——冒泡排序、快速排序三种递归实现and快排非递归
https://blog.csdn.net/vickers_xiaowei/article/details/80646873
排序三——选择排序and堆排序
https://blog.csdn.net/vickers_xiaowei/article/details/80646990
排序四——归并排序和排序结:
https://blog.csdn.net/vickers_xiaowei/article/details/80646992