堆排序<二>---利用顺序表完成

利用顺序表构建堆结构,可以实现增删改查等操作。

Heap.h

#ifndef HEAP_H
#define HEAP_H
#define HEAP_SIZE 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

Heap.cpp

#include "Heap.h"
#include <malloc.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

template<class Type>
void Swap(Type &a,Type &b)
{
    Type tmp = a;
    a = b;
    b = tmp;
}
bool Init_Heap(Heap *hp)    //初始化 堆
{
    assert(hp != NULL);
    hp->cursize = 0;
    hp->maxsize = HEAP_SIZE;
    hp->data = (ELEMTYPE *)malloc(sizeof(ELEMTYPE)*hp->maxsize);
    if(hp->data == NULL) exit(1);
    return true;
}

void Destroy_Heap(Heap *hp)   //销毁堆
{
    assert(hp != NULL);
    free(hp->data);
    hp->data = NULL;
    hp->cursize = 0;
    hp->maxsize = 0;
}

void Clear_Heap(Heap *hp)   //清空
{
    assert(hp != NULL);
    hp->cursize = 0;
}

void FileterDown(ELEMTYPE *p,int start,int end)  // 向下调整
{   int i = start;
    int j = i*2 +1;
    ELEMTYPE tmp = p[i];
    while(j<=end){
        if(j < end && p[j]>p[j+1]) j+=1;
        if(tmp <= p[j]) break;
        p[i] = p[j]; 
        i = j;
        j = i*2+1;
    }
    p[i] = tmp; 
}

void FileterUp(ELEMTYPE *p,int start)    //向上调整
{   int i = start;
    int j = (i-1)/2;
    ELEMTYPE tmp = p[i];
    while(i>0){
        if(tmp >= p[j]) break;
        p[i] = p[j]; 
        i = j;
        j = (i-1)/2;
    }
    p[i] = tmp; 
}

bool Empty_Heap(Heap *hp)      //判断空
{
    assert(hp != NULL);
    return hp->cursize == 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);
    ELEMTYPE tmp = hp->data[0];
    Swap(hp->data[0],hp->data[hp->cursize-1]);
    hp->cursize--;
    FileterDown(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)
    {
        FileterDown(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(hp);
    }
    hp->data[hp->cursize] = x;
    hp->cursize++;
    FileterUp(hp->data,hp->cursize-1);
}

void Make_Sort(Heap *hp)    //排序
{
    int pos = hp->cursize-1;
    while(pos > 0)
    {
        Swap(hp->data[0],hp->data[pos]);
        FileterDown(hp->data,0,--pos);
    }
}
void Print_Heap(Heap *hp)     //打印
{
    assert(hp != NULL);
    for(int i = 0;i<hp->cursize;++i)
    {
        printf("%d ",hp->data[i]);
    }
    printf("\n");
}


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]);
    }
    scanf("%d",&x);
    Push_Heap(&hp,x);
    while(!Empty_Heap(&hp))
    {
        x = Pop_Heap(&hp);
        printf("%d ",x);
    }
    printf("\n");
}

// int *p ; 野指针
/* p = (int *)malloc(sizeof(int))
free(p);
*p = 1000; //无效指针 ==>解决: free后需要将 p = NULL;
free(p); // 会出现 单线程:可能崩溃 多线程:可能被其他线程malloc
*/
问题:用函数指针控制 建立的是大堆 还是小堆
用宏定义实现单个堆时的 大堆小堆指令问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值