选择排序
- 直接选择排序
- 堆排序
直接选择排序
基本思想:
- 在元素集合a[i]–a[n-1]中选择关键码最大(小)的数据元素
- 若它不是这组元素中国最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个元素)交换
- 在剩余的a[i]-a[n-2](a[i+1]-a[n-2])集合中,重复上面的步骤,直到集合剩余1个元素
时间复杂度为O(n2),不稳定
代码:
void Swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void Select(int num[], int len)
{
if (num == NULL || len <= 0)
return;
int i = 0;
//1.确定循环躺数
for (; i < len - 1; i++)
{
int minindex = i;
int j = i + 1;
//2.找到无序区的最小值
for (; j < len; j++)
{
if (num[minindex] > num[j])
{
minindex = j;
}
}
//与无序区第一个元素交换
if (minindex != i)
Swap(&num[minindex], &num[i]);
}
}
算法优化,一次选两个,一个最大的,一个最小的
void Select_OP(int arr[], int len)
{
int i = 0;
int k = 0;//保存无序区第一个元素下标,方便比较
//一趟确定一个有序区元素,最后一次不用确定,总共len-1次
for (i = 0; i < len - 1; i++)
{
k = i;
int j = 0;
//确定无序区最小元素下标
for (j = i + 1; j < len; j++)
{
if (arr[j] < arr[k])
{
k = j;
}
}
//如果无序区第一个元素为最小,则没有必要交换
if (i != k)
{
int tmp = arr[k];
arr[k] = arr[i];
arr[i] = tmp;
}
}
}
堆排序
步骤:
- 创建堆:升序->大堆,降序->小堆
- 执行如下步骤,直到数组为空
- 把栈顶元素和当前最堆的最后一个元素交换
- 堆元素个数减1
- 再次调整根节点
时间复杂度:O(n*log2n)不稳定
代码:
#include<stdio.h>
void AdjustDown(int* num, int n, int parent)
{
if (num == NULL || n <= 0)
return;
int child = 2 * parent + 1;
while (child < n)
{
//处理让child指向左右孩子中较大的哪一个
if ((child + 1 < n) && (num[child] < num[child + 1]))
child++;
//比较交换并调整
if (num[child]>num[parent])
{
Swap(&num[child], &num[parent]);
parent = child;
child = 2 * parent + 1;
}
else
{
break;
}
}
}
//堆排序
void HeapSort(int* num, int len)
{
if (num == NULL || len <= 0)
return;
//1.建堆(升序->大堆,降序->小堆)
for (int i = (2 * len - 2) / 2; i >= 0; i--)
{
AdjustDown(num, len, i);
}
//2.交换最后一个元素和第一个元素
int end = len - 1;
while (end > 0)
{
Swap(&num[0], &num[end]);
AdjustDown(num, end, 0);
--end;
}
}