1.选择排序
基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
//选择排序
void SelectSort(int* a, int sz)
{
int left = 0;
int right = sz - 1;
while (left < right)
{
int maxi = left;
int mini = left;
int cur = left;
while (cur <= right)
{
if (a[cur] > a[maxi])
{
maxi = cur;
}
if (a[cur] < a[mini])
{
mini = cur;
}
cur++;
}
Swap(&a[left], &a[mini]);
//当maxi==left时,交换后maxi对应的值为mini对应的值
if ( maxi==left )
{
maxi = mini;
}
Swap(&a[right], &a[maxi]);
left++;
right--;
}
}
2.堆排序
(1)向下调整法
第一步,找到parent的左孩子child,child=parent*2+1
第二步,比较左右孩子哪个大,将大的孩子与parent进行比较,若孩子大则进行交换,直至找到叶节点。
void AdjustDwon(int* a, int sz, int root)
{
int parent = root;
int child = parent * 2 + 1;
//大堆
while (child < sz)
{
if (child + 1 < sz && a[child] > a[child + 1])
{
child = child + 1;
}
if (a[child] < a[parent])
Swap(&a[child], &a[parent]);
parent = child;
child = parent * 2;
}
}
(2)将数组排列成堆
将一个数组看成一个完全二叉树
先找到最后一个叶子节点,进行向下调整
即图中画圈的节点 公式:最后一个叶子节点=(总结点数-1)/ 2
将所有叶节点调整完后,则可以得到一个堆
int i = (sz - 2) / 2;
while (i >= 0)
{
AdjustDwon(a, sz, i);
i--;
}
堆的性质:根节点为最大或最小的一个数
(3)排列成一个有序数组
利用堆的性质,将根节点与最后一个进行交换,再将前n-1个数,再次看成一个堆,并进行向下调整,直至全部调整完毕后,得到一个有序数组。
while (i>0)
{
Swap(&a[0], &a[i]);
AdjustDwon(a, i, 0);
i--;
}