堆排序

堆排序:将堆中的数据按照升序/降序排列。

在这里也会用到堆的调整、创建操作,具体代码点连接:https://mp.csdn.net/mdeditor/82346337

分析:如果我们要按升序排的话,我们要把这个堆建立成大堆,如果我们要按降序排的话,我们要把这个堆建立成小堆。例如:我们要把它排成升序,先把它建立成一个大堆,那堆顶元素就是最大元素了,我们让最后一个元素和堆顶元素交换,那最后一个元素就是整个堆中最大的元素了,我把除了最后一个元素外的size-1个元素调整为大堆,这size-1个元素组成了一个新的大堆,再让新堆中的最后一个元素与堆顶元素交换,调整……直到新堆中只剩堆顶元素最后一个元素;降序同理。
这里写图片描述
SortHeap.h

#ifndef __SORTHEAP_H__
#define __SORTHEAP_H__

#include"Heap.h"

typedef struct Sort
{
    Heap hp;
}Sort;

void SortHeapUp(Sort* s, HPDataType array, int size);
void SortHeapDown(Sort* s, HPDataType array, int size);

#endif //__SORTHEAP_H__

SortHeap.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"SortHeap.h"

void SortHeapUp(Sort* s, HPDataType array, int size)
{
    assert(s);
    //先创建一个大堆
    CreateHeap(&(s->hp), array, size, Great);
    Print(s->hp);
    //堆顶元素(最大)和最后一个元素交换(最小),除去最后一个元素(因为已经是最大了),把前n-1个元素调整为大堆...循环,每次少调整一个元素
    int end = s->hp._size - 1;
    int hpsize = s->hp._size;
    while (s->hp._size)
    {
        s->hp._size -= 1;

        Swap(&(s->hp._hp[0]), &(s->hp._hp[s->hp._size]));
        //end--;
        //int root = (s->hp._hp[s->hp._size] - 2) >> 1;
        AdjustDown(&(s->hp), 0, Great);
    }
    s->hp._size = hpsize;
}

void SortHeapDown(Sort* s, HPDataType array, int size)//降序
{
    assert(s);
    //先建一个小堆
    CreateHeap(&(s->hp), array, size, Less);
    Print(s->hp);
    //将堆顶元素与最后一个元素交换,除了交换后的最后一个元素,将size-1个元素调整为小堆,size--再将堆顶元素与最后一个交换(倒数第二个)
    int end = s->hp._size - 1;
    int hpsize = s->hp._size;//因为hp->_size被改变了,Print函数还需要用size打印,所以先标记起来,最后赋给size
    while (end)
    {
        Swap(&(s->hp._hp[0]), &(s->hp._hp[end]));
        s->hp._size -= 1;
        AdjustDown(&s->hp, 0, Less);
        end--;
    }
    s->hp._size = hpsize;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"SortHeap.h"

int main()
{
    Sort s;
    HPDataType array[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 };
    SortHeapDown(&s, array, 9);
    Print(s.hp);

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值