堆排序代码
const int max_num = 10;
int n = max_num;
int data[max_num + 1] = { 0, 1, 3, 10, 5, 8, 6, 7, 9, 2, 4 };
void shiftup(int i)
{
//新来一个节点i,将其放在最后,然后与其父节点比较
int flag = 1;
int tmp;
while (i > 1 && data[i] < data[i / 2] && flag)
{
//交换元素
tmp = data[i / 2];
data[i / 2] = data[i];
data[i] = tmp;
i = i / 2;
if (i == 1)
flag = 0;
}
}
void shiftdown(int i)
{
int t = data[i];
int tmp;
int min_index = i;
int flag = 1;
while (2 * i <= n && flag == 1)
{
if (data[i] > data[2 * i])
{
t = data[2 * i];//记录当前最小值
min_index = 2 * i;
}
if (2 * i + 1 <= n)
{
if (t > data[2 * i + 1])
{
t = data[2 * i + 1];//记录当前最小值
min_index = 2 * i + 1;
}
}
if (min_index != i)
{
//交换
tmp = data[i];
data[i] = data[min_index];
data[min_index] = tmp;
i = min_index;
}
else
{
flag = 0;
}
}
}
void creatHeap1(int* data, int len)
{
for (int i = 1; i <= max_num; i++)//从1开始
{
shiftup(i);//假设已有小堆k(已经有序,上层的根节点肯定小于下层的子节点,往下延伸,只会逐渐增大),再来一个节点,从第一个非叶子节点开始比较,一直比较到根节点,是否往上移, 直到顶点
}
}
//方法二
void creatHeap2(int* data, int len)
{
for (int i = len / 2; i >= 1; i--)//从1开始
{
shiftdown(i);//从第1个非叶子节点开始,本层节点与下层节点比较,是否需要往下移(当本层节点大于下层节点时,往下移)
}
}
int main(int argc, const char* argv[])
{
//堆排序
//首先创建堆,此处以小堆为例(父节点小于两个子节点)
//creatHeap1(data, max_num);
//for (int i = 1; i <= max_num; i++)
//{
// printf("%d ", data[i]);
//}
creatHeap2(data, max_num);
for (int i = 1; i <= max_num; i++)
{
printf("%d ", data[i]);
}
printf("\n");
//建成堆后,如何有序展示
//方式1:取出堆顶,然后将最后一个元素放置,往下移,调整成堆,直到堆为空
//n = max_num;
//while (n >= 1)
//{
// int top = data[1];
// data[1] = data[n];
// n--;
// shiftdown(1);//此处n的值需要变化,所以内部不能用max_num
// printf("%d ", top);
//}
//方式2:将最后一个元素与根节点位置交换,最后一个位置保存的是最小值,向下移
while (n >= 1)
{
int tmp = data[n];
data[n] = data[1];
data[1] = tmp;
n--;
shiftdown(1);
}
for (int i = 1; i <= max_num; i++)
{
printf("%d ", data[i]);
}
//如果要获得从小到大,则事先创建大顶堆
return 0;
}
找出第k大的元素
//找出第k大的元素
int k = 5;
creatHeap2(data, k);//创建小堆
for (int i = 1; i <= k; i++)
{
printf("%d ", data[i]);
}
for (int i = k+1; i <= max_num; i++)
{
if (data[i] > data[1])//如果大于堆顶点,则加上去,向上移
{
data[1] = data[i];
shiftdown(1);
}
}
printf("\n");
//堆顶元素就是第k大
printf("%d ", data[1]);//6; 第5大的元素

浙公网安备 33010602011771号