typedef int HpDataType;
//交换数据
void Swp(HpDataType* p1, HpDataType* p2)
{
assert(p1 && p2);
HpDataType tmp = *p2;
*p2 = *p1;
*p1 = tmp;
}
//大堆:向上调整,child 为孩子
void AdjustUpBig(HpDataType* a, int child)
{
assert(a);
//parent 父亲结点
int parent = (child - 1) / 2;
//循环的进行从3个方面考虑:
// 1、初始条件
// 2、中间过程
// 3、结束条件
//循环有2种写法:
while (child > 0 && a[child] > a[parent])
{
//互换;
Swp(&a[child], &a[parent]);
child = parent;
parent = (child - 1) / 2;
}
}
//大堆:向下调整 //数组 元素个数 parent 父亲节点
void AdjustDownBig(HpDataType* a, int n, int parent)
{
assert(a);
//用到假设法:我们要保证我的父亲节点比最大的儿子节点大或者相等;假设左孩子大
int child = 2 * parent + 1;
while (child < n)
{//判断一下,完全二叉树,有可能会有有孩子不存在的情况
if (a[child] < a[child + 1] && child + 1 < n)
{
//拿孩子大的去和父亲比较
child = child + 1;
}
if (a[child] > a[parent])
{
Swp(&a[child], &a[parent]);
parent = child;
child = 2 * parent + 1;
}
else
{
break;
}
}
}
//打印
void Prin(int* a, int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
}
//大堆:变量含义:数组 元素个数
//大堆:向上调整实现升序
void HpBig(int* a, int n)
{
int i;
//从第二层的第一孩子开始向上调整建堆
for (i = 1; i < n; i++)
{
AdjustUpBig(a, i);
}
int k = n;
//排序
for (i = n - 1; i > 0; i--)
{
Swp(&a[0], &a[i]);
k--;
AdjustDownBig(a, k, 0);
}
//打印
Prin(a, n);
}
//大堆:向下调整实现升序
void HpBig2(int* a, int n)
{
int i;
//向下调整建堆
for(i = (n - 1-1); i >=0; i--)
{
AdjustDownBig(a, n, i);
}
int k = n;
//排序
for (i = n - 1; i > 0; i--)
{
Swp(&a[0], &a[i]);
k--;
AdjustDownBig(a, k, 0);
}
//打印
Prin(a, n);
}
三、降序的实现:通过建小堆实现
>思路:
将待排序数组构造成一个小堆
这个序列最小值在堆顶
将其与末尾元素进行交换,末尾变成最小值
将剩下的n-1个结点重新调整为小堆
再次将最小值与此时(为n-1个结点的小堆)的末尾元素交换
重复下去,到最后就是有序的了,整个数组最大的元素此时在栈顶
1、向上调整算法实现小堆的建立:了解即可
思路一样的,流程图都是大差不差的,无非就是变成了孩子小于爹就交换
2、向下调整算法实现小堆的建立:
3、排序:
都是大堆实现过的,思路就是一样的,就是要注意性质,决定了符号(大于还是小于)
代码:
cpp复制代码
//因为是直接复制过来的,所以用来Typedef改名
typedef int HpDataType;
//交换数据
void Swp(HpDataType* p1, HpDataType* p2)
{
assert(p1 && p2);
HpDataType tmp = *p2;
*p2 = *p1;
*p1 = tmp;
}
//打印
void Prin(int* a, int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
}
//小堆:向上调整完成降序
void HpSmall(int* a, int n)
{
int i;
//从第二层开始调整
for (i = 1; i < n; i++)
{
AdjustUpSmall(a, i);
}
int k = n;
//排序:
for (i = (n - 1-1); i > 0; i--)
{
Swp(&a[0], &a[i]);
k--;
AdjustDownSmall(a, k, 0);
}
//打印
Prin(a, n);
}
//小堆:向下调整实现降序
void HpSmall2(int* a, int n)
{
int i;
//建堆
for(i = n - 1; i >=0; i--)
{
AdjustDownSmall(a, n, i);
}
int k = n;
//排序:
for (i = n - 1; i > 0; i--)
{
Swp(&a[0], &a[i]);
k--;
AdjustDownSmall(a, k, 0);
}
//打印
Prin(a, n);
}