个人名片:
作者简介:一名乐于分享在学习道路上收获的大二在校生
❄个人主页:GOTXX
个人WeChat:ILXOXVJE
本文由GOTXX原创,首发CSDN
系列专栏:零基础学习C语言----- 数据结构的学习之路
每日一句:如果没有特别幸运,那就请特别努力!
————————————————
目录
1.选择排序
1.1选择排序的基本思想
图解:
1.2代码实现
1.3性能分析
2.堆排序
2.1堆排序的基本思想
图解:
2.2代码实现
2.3性能分析
基本思想:
遍历一遍待排数据,将最大值与最小值的下标记录,然后把最小值与数组最前面的数据交换,将最大值与数组最后一个数据交换,这样遍历一遍,就将最大值和最小值放到了正确的位置;
将除了上面已经在正确位置的数据,将剩下的数据看成待排数组,然后重复上述操作,这样,遍历2/n次,就可以将所有数据排好序;
void SelectSort(int* a, int n)
{
for (int j = 0; j < n/2; j++)
{
//假设数组中最大最小值的下标是j
int maxi = j;
int mini = j;
for (int i = j; i < n -j; i++)
{
//有比max大的,就改变下标
if (a[i] > a[maxi])
{
maxi = i;
}
//有比min小的,就改变下标
if (a[i] < a[mini])
{
mini = i;
}
}
//将找到的最小值放到待排数组最前面
Swap(&a[mini], &a[j]);
//如果最大值在待排数组最前面,在把最小值换到前面的时候,会将最大值的下标改变
//所以这里需要更新最大值的下标,如上图第三步中8的交换
if (maxi == j)
{
maxi = mini;
}
//将最大值放到待排数组的后面
Swap(&a[maxi], &a[n - 1-j]);
}
}
最坏情况:逆序
时间复杂度:O(N^2)
空间复杂度:O(1)
要了解堆排序要先了解堆,堆的相关知识http://t.csdnimg.cn/GoxJO
利用大堆的特点,父亲都大于孩子,所以堆的根结点是整个二叉树中的最大数;
先将根结点与树中最后一个节点交换(对应在数组中,就是将数组中第一个数据与最后一个数字交换),这样,最大的数就在数组最后,在正确的位置上了,交换过后,(树的左右子树都是大堆)这样再利用向下调整建堆,将剩下的数据变成大堆,这样最大的数据又在根结点了,重复上面操作就可以将所有数据变成有序;
void Adjustdown(int* a, int parent, int n)
{
assert(a);
int child = parent * 2 + 1;
while (child < n)
{
//假设左孩子大
if (child + 1 < n && a[child] < a[child + 1])
{
//假设不成立,调整
child = child + 1;
}
if (a[child] > a[parent])
{
Swap(&a[parent], &a[child]);
parent = child;
child = child * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(int* a, int n)
{
assert(a);
//从最后一个非叶子节点向下调整
//n-1是最后一个结点,(n-1-1)/2是它父亲
for (int i = (n-1-1) / 2; i >= 0; i--)
{
Adjustdown(a, i, n);
}
int end = n-1;
while (end > 0)
{
Swap(&a[0],&a[end]);
Adjustdown(a,0, end);
end--;
}
}
数据个数为N,则高度为:logN
N个数据,每个数据向下调整,时间复杂度需要logN
时间复杂度:O(N*logN)
空间复杂度为:O(N)