1. 程式人生 > >資料結構——最大堆和最小堆(C語言)

資料結構——最大堆和最小堆(C語言)

定義:

    最大堆和最小堆都是一棵完全二叉樹。

    最大堆:是指根節點的關鍵字值是堆中的最大關鍵字值,且每個節點若有兒子節點,其關鍵字值都不小於其兒子節點的關鍵字值。

    最小堆:是指根節點的關鍵字值是堆中的最小關鍵字值,且每個節點若有兒子節點,其關鍵字值都不大於其兒子節點的關鍵字值。

    以下的操作以最大堆為例,最小堆相似。


最大堆的插入操作

   步驟:

  1. 把待增加的節點編號 i 設定為已知堆的總節點數加 1 即 i=++(*n),因此,新增的元素放在最下一層作為新的葉子節點。求出節點 i 的父節點 parent=i/2; 判斷是否為空堆,並比較所插入元素與父節點關鍵字值的大小;
  2. 若所插入節點關鍵字值大於父節點關鍵字值即item>heap[parent],則把父節點向下移,並把父節點作為當前節點,依次求父節點,即依次沿著樹枝向上延伸直到根節點;
  3. 把元素item插入到正確位置;

最大堆的刪除操作

    最大堆的刪除,即刪除最大的元素。我們先取最後的元素提到根結點,然後刪除最大值,然後再把新的根節點放到合適的位置。

   首先刪除根節點,並把最後一個節點臨時作為新的根節點,將新的根節點作為當前節點與其孩子節點中最大的關鍵值節點進行比較,若小於其孩子節點的關鍵值,則與其孩子節點進行交換位置,並把新位置作為當前節點繼續與其孩子節點進行比較,一直延伸下去,直到沒有孩子節點為止;


源程式

    函式宣告:

#ifndef HEAP_H_INCLUDED
#define HEAP_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10
int heap[MAX_SIZE];
void max_Heap_insert(int *heap,int *n,int item);
int max_Heap_delete(int *heap,int *n);
#endif // HEAP_H_INCLUDED
   函式的定義:
#include"heap.h"

/*最大堆的插入操作*/
/*注:堆的下標是從1開始,而不是0*/
void max_Heap_insert(int *heap,int *n,int item)
{
    int i,parent;//i為當前節點,parent為i的父節點
    if((*n)==MAX_SIZE)//堆為滿
    {
        printf("The heap is full\n");
        exit(1);
    }
    i=++(*n);
    parent=i/2;
    while((i!=1) && (item>heap[parent]))//若堆為非空,且所插入資料item大於父節點的關鍵字值
    {
        heap[i]=heap[parent];//父節點關鍵字值下移
        i=parent;//把父節點作為當前節點
        parent/=2;//依次求父節點
    }
    heap[i]=item;//插入到正確的位置
}
/*最大堆的刪除操作*/
int max_Heap_delete(int *heap,int *n)
{
    int item,temp;
    int child,parent;
    if(*n==0)//若為空堆
    {
        printf("The heap is empty.\n");
        exit(1);
    }
    item=heap[1];//把最大堆的最大元素賦給item
    temp=heap[(*n)--];//堆的最後節點關鍵字值
    parent=1;
    child=2*parent;
    while(child<=(*n))
    {
        if(child<*n && heap[child]<heap[child+1])
            child++;//找出堆中最大關鍵字值的節點
        if(temp>=heap[child])break;//把最大節點關鍵字值與最後節點關鍵字值比較
        else
        {//若堆中存在比最後節點關鍵字值大的節點,則交換位置
            heap[parent]=heap[child];
            parent=child;
            child*=2;
        }
    }
    heap[parent]=temp;//插入到正確位置
    return item;//返回刪除的關鍵字值
}
    程式測試:
#include"heap.h"


int main()
{
    int item,i;
    int n=0;
    for(i=1;i<MAX_SIZE;i++)
    {
        scanf("%d",&item);
        max_Heap_insert(heap,&n,item);
    }
    for(i=1;i<=n;i++)
        printf("%d ",heap[i]);
    printf("\n");
    item=max_Heap_delete(heap,&n);
    printf("The deleted data is:%d",item);
    printf("\n");
    for(i=1;i<=n;i++)
        printf("%d ",heap[i]);
    return 0;
}