优先队列(一)——二叉堆

十年热恋 提交于 2019-12-04 01:39:36

二叉堆的抽象数据类型:

 1 #ifndef _BinHeap_H
 2 #define ElementType int
 3 #define MinElement -1000
 4 struct HeapStruct;
 5 typedef struct HeapStruct *PriorityQueue;                   //结构体指针
 6 PriorityQueue Initialize(int MaxElements);                  //初始化一个二叉堆
 7 void Destroy(PriorityQueue H);                              //销毁二叉堆的操作
 8 void MakeEmpty(PriorityQueue H);                            //置空一个二叉堆的操作
 9 void Insert(ElementType X, PriorityQueue H);                //插入操作
10 ElementType DeleteMin(PriorityQueue H);                     //删除最小元的操作
11 ElementType FindMin(PriorityQueue H);                       //找到最小元的操作
12 int IsEmpty(PriorityQueue H);                               //判断二叉堆是否为空的操作
13 int IsFull(PriorityQueue H, int MaxElement);                //判断二叉堆是否已满的操作
14 PriorityQueue CreateHeap(ElementType a[], PriorityQueue H, int n);//利用数组创建二叉堆的操作
15 void BuildHeap(ElementType a[], PriorityQueue H, int N);    //利用数组创建二叉堆的操作
16 #endif
17 
18 struct HeapStruct{
19     int Capacity;
20     int size;
21     ElementType *Elements;
22 };

二叉堆的一般操作实现:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "Heap.h"
using namespace std;

//初始化一个二叉堆
PriorityQueue Initialize(int MaxElements){
    PriorityQueue H = (PriorityQueue)malloc(sizeof(struct HeapStruct));
    H->Capacity = MinElement;
    H->size = 0;
    H->Elements = (ElementType *)malloc(MaxElements*sizeof(ElementType));
    return H;
}

//插入操作,主要的动作是——上滤
void Insert(ElementType X, PriorityQueue H){
    int i;
    for(i = ++H->size; i / 2 >= 1; i /= 2){
        if(H->Elements[i / 2] > X){
            H->Elements[i] = H->Elements[i/2];
        }
        else{
            break;
        }
    }
    H->Elements[i] = X;
}

//用一个数组创建一个二叉堆,通过反复调用Insert()操作来保证新的元素进入时的堆序性
PriorityQueue CreateHeap(ElementType a[],PriorityQueue H, int n){
    for (int i = 0; i < n; i++)
    {
        Insert(a[i], H);
    }
}

//输出整个二叉堆的所有元素,输出顺序是Elements数组的顺序
void PrintBinHeap(PriorityQueue H){
    printf("优先队列为:");
    for (int i = 1; i <= H->size; i++)
    {
        printf("\t%d", H->Elements[i]);
    }
    printf("\n");
}

//删除二叉堆堆顶的元素,即最小的那个元素;主要的操作是——下滤
ElementType DeleteMin(PriorityQueue H){
    ElementType LastElement = H->Elements[H->size--];
    ElementType MinElements = H->Elements[1];
    int i, Child;
    for(i  = 1; i * 2 <= H->size; i = Child){
        Child = i * 2;
        if(Child != H->size && H->Elements[Child + 1] < H->Elements[Child]){    //判断某个结点是否只有一个孩子结点
            Child++;
        }
        if(H->Elements[Child] < LastElement){
            H->Elements[i] = H->Elements[Child];
        }
        else{
            break;
        }
    }
    H->Elements[i] = LastElement;
    return MinElements;
}

//销毁二叉堆
void Destroy(PriorityQueue H){
    free(H->Elements);
    free(H);
}

//清空二叉堆,并返回一个空的二叉堆
void MakeEmpty(PriorityQueue H){
    free(H->Elements);
}

//判断二叉堆是否为空
int IsEmpty(PriorityQueue H){
    return H == NULL;
}

//判断二叉堆是否已满
int IsFull(PriorityQueue H, int MaxElement){
    return H->size > MaxElement;
}

ElementType FindMin(PriorityQueue H){
    return H->Elements[1];
}

//利用数组创建二叉堆的操作,只需花费线性时间O(N)
void PercolateDown(ElementType a[], int i, int N){
    int Child, Element = a[i];
    int k;
    for(k = i; k * 2 <= N; k = Child){
        Child = k * 2;
        if(Child != N && a[Child+1] < a[Child]){
            Child++;
        }
        if(Element > a[Child]){
            a[k] = a[Child];
        }
        else{
            break;
        }
    }
    a[k] = Element;
}

void BuildHeap(ElementType a[], PriorityQueue H, int N){
    for(int i = N/2; i > 0; i--){
        PercolateDown(a, i, N);
    }
    for(int i = 1; i <= N; i++){
        H->Elements[i] = a[i];
        H->size++;
    }
}

void Election()

int main(){
    PriorityQueue H;
    int n;
    printf("请输入元素个数:\n");
    scanf("%d", &n);
    ElementType a[n+1];
    printf("请输入元素,以空格分隔:\n");
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    H = Initialize(68);
    BuildHeap(a, H, n);
    PrintBinHeap(H);
    printf("%d", FindMin(H));
    system("pause");
    return 0;
}
 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!