堆排序

来源:互联网 发布:js函数传递对象参数 编辑:程序博客网 时间:2024/06/03 18:02

一、概念

  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 100typedef 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 MINHEAPtemplate<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_Heapvoid 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");}