堆排序

一、概念

  1.  完全二叉树(Complete Binary Tree):若设二叉树的深度为h,除第 h层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
  2. 堆:是一种完全二叉树或者近似完全二叉树。
  3. 堆排序:是选择排序的一种,主要是利用完全叉树这种数据结构所设计的一种排序算法。

二、堆的分类
堆分为大根堆(最大堆)和小根堆(最小堆);
1. 大根堆(最大堆):根结点(亦称为堆顶)的关键字(数据)是堆里所有结点关键字中最大者,称为大根堆,又称最大堆。
2. 小根堆(最小堆):根结点(亦称为堆顶)的 关键字(数据)是堆里所有结点关键字中最小者的堆称为小根堆,又称最小堆。
这里写图片描述
三、堆结构特点即完全二叉树的特点

  • 设某个节点索引值为i,
  • 则节点的左子节点索引为:2*i+1;
  • 右子节点索引为:2*i+2;
    父节点索引为:(i-1)/2。
    四,代码
//Heap.h 堆排序头文件
#ifndef HEAP_H
#define HEAP_H
#define HEAPSIZE 100
typedef int ElemType;
typedef struct
{
    ElemType *data;
    int maxsize;
    int cursize;
}Heap;

bool Init_Heap(Heap *hp);
void Destroy_Heap(Heap *hp);
void Clear_Heap(Heap *hp);
bool Empty_Heap(Heap *hp);
bool Full_Heap(Heap *hp);
int  Size_Heap(Heap *hp);
ElemType Pop_Heap(Heap *hp);
void Insert_Heap(Heap *hp,ElemType *ar,int n);
void Push_Heap(Heap *hp,ElemType x);
void Make_Heap(Heap *hp);
void Make_Sort(Heap *hp);
void Print_Heap(Heap *hp);
#endif
//函数文件
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include<stdlib.h>
#include"Heap.h"
#define MINHEAP

template<class Type>
/*void Swap(Type &a,Type &b)
{
    Type tmp = a;
    a = b;
    b = tmp;
}*/
void FilterDown(ElemType *ar,int start,int end)
{
    int i = start; // root
    int j = i*2+1; // leftchild;
    ElemType tmp = ar[i];
    while(j <= end)
    {
#ifdef MINHEAP  //判断最小堆输出还是最大堆输出
        if(j < end && ar[j] >= ar[j+1]) j+=1;
        if(tmp <= ar[j])  break;
#else
        if(j < end && ar[j] <= ar[j+1]) j+=1;
        if(tmp >= ar[j]) break;
#endif
        ar[i] = ar[j];
        i = j;
        j = i*2+1;
    }
    ar[i] = tmp;
}
void FilerUp(ElemType *ar,int start)
{
    int j = start, i = (j-1)/2;
    ElemType tmp = ar[j];
    while(j > 0)
    {
#ifdef MINHEAP  //判断最小堆输出还是最大堆输出
        if(ar[i] <= tmp)
#else
        if(ar[i] >= tmp)
#endif
            break;
        ar[j] = ar[i];
        j = i;
        i = (j-1)/2;
    }
    ar[j] = tmp;

}
bool Init_Heap(Heap *hp)
{
    assert(hp != NULL);
    hp->cursize = 0;
    hp->maxsize = HEAPSIZE;
    hp->data = (ElemType*)malloc(sizeof(ElemType)*hp->maxsize);
    if(hp->data == NULL) exit(1); // return false;
    return true;
}
void Destroy_Heap(Heap *hp)//摧毁函数
{
    assert(hp != NULL);
    free(hp->data);//一定要释放,这是空指针,与野指针不同
    hp->data = NULL;
    hp->maxsize = 0;
    hp->cursize = 0;

}
void Clear_Heap(Heap *hp)//清空函数
{
    assert(hp != NULL);
    hp->cursize = 0;
}
bool Empty_Heap(Heap *hp)//是否为空;
{
    assert(hp != NULL);
    return hp->cursize == 0;//判断当前是否为0
}
bool Full_Heap(Heap *hp)//是否满了
{
    assert(hp != NULL);
    return hp->cursize == hp->maxsize;
}
int  Size_Heap(Heap *hp)//
{
    assert(hp != NULL);
    return hp->cursize;
}

ElemType Pop_Heap(Heap *hp)
{
    assert(hp != NULL);
    int tmp = hp->data[0];
    Swap(hp->data[0],hp->data[hp->cursize-1]);
    hp->cursize -= 1;
    FilterDown(hp->data,0,hp->cursize-1);
    return tmp;
}


void Make_Heap(Heap *hp)
{
    assert(hp != NULL);
    int end = hp->cursize -1;
    int pos = (end-1)/2;
    while(pos >= 0)
    {
        FilterDown(hp->data,pos,end);
        --pos;
    }
}
void Insert_Heap(Heap *hp,ElemType *ar,int n)//插入函数
{
    assert(hp != NULL &&  ar != NULL && n>0 );
    for(int i = 0;i<n;++i)
    {
        hp->data[i] = ar[i];
    }
    hp->cursize = n;
    Make_Heap(hp);
}
void Push_Heap(Heap *hp,ElemType x)
{
    assert(hp != NULL);
    if(Full_Heap(hp))
    {
        // Inc_Heap(ph);
    }
    hp->data[hp->cursize] = x;
    hp->cursize +=1;
    FilerUp(hp->data,hp->cursize - 1);
}
/*void Print_Heap(HeapElem *heap,int n)
{
    assert(heap != NULL);
    for(int i = 0; i<n;++i)
    {
        printf("%d ",heap[i]);
    }
    printf("\n");
}*/
//测试函数
#include<stdio.h>
#include"heap.h"
bool greater_equ(ElemType a,ElemType b)
{
    return a>=b;
}
bool less_equ(ElemType a,ElemType b)
{
    return a<=b;
}
//作为函树指针传入Push_Heap
void main()
{
    Heap hp;
    Init_Heap(&hp);
    ElemType x;
    ElemType ar[]={89,12,56,78,12,45,67,34,90,18};
    int n = sizeof(ar)/sizeof(ar[0]);
    ElemType br[]={12,67,89,100,34,23,78,56};
    int m = sizeof(br)/sizeof(br[0]);
    for(int i = 0;i<n;++i)
    {
        Push_Heap(&hp,ar[i],greater_equ);
    }
    scanf("%d",&x);
    Push_Heap(&hp,x);
    while(!Empty_Heap(&hp))
    {
        x = Pop_Heap(&hp);
        printf("%d ",x);
    }
    printf("\n");


}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值