【C++】大頂堆(最大堆)手工模擬優先隊列

前言

本文采用結構體重載比較運算符的方式進行大根堆的建立,算法邏輯參考STL的priority queue。

結構體

struct num{
    int n;
    num(){//空參構造
        n=0;
    }
    num(int i){//含參構造
        n=i;
    }
    bool operator<(const num &right)const{//小於重載
        return n<right.n;
    }
};

向上調整堆

void adjustUp(num heap[],int i){
    if(i==1) return;
    if(heap[i/2]<heap[i]) swap(heap[i/2],heap[i]);//小於父結點交換
    adjustUp(heap,i/2);//遞歸調整
}

刪除堆頂元素

void deleteHeap(num heap[],int &len){
    //交換堆頂和尾部元素
    heap[0].n=heap[len].n;
    heap[len].n=heap[1].n;
    heap[1].n=heap[0].n;
    len--;//長度-1
    int i=1;//分支選擇i
    while(2*i<=len){
        i=2*i+1;//進入下一層
        if(i>len || heap[i]<heap[i-1]) i--;
    }
    while(i>1){
        if(!(heap[i]<heap[0])) swap(heap[i],heap[0]);//比較當前結點和哨兵
        i/=2;//找父結點
    }
    heap[1].n=heap[0].n;//堆頂等於哨兵
}

完整代碼

#include <iostream>
#include <algorithm>
#define maxsize 101//最大maxsize-1長,0是哨兵,下標1~maxsize-1
using namespace std;
struct num{
    int n;
    num(){//空參構造
        n=0;
    }
    num(int i){//含參構造
        n=i;
    }
    bool operator<(const num &right)const{//小於重載
        return n<right.n;
    }
};

void adjustUp(num[],int);
void deleteHeap(num[],int&);

int main(){
    num heap[maxsize];
    int len;//len是當前長度
    int n;
    printf("輸入隊列個數:\n");
    scanf("%d",&n);//輸入個數
    printf("輸入入隊元素:\n");
    for(len=1;len<=n;len++){
        scanf("%d",&heap[len].n);
        adjustUp(heap,len);//每輸入一個需要調整一次
    }
    len=n;//循環退出時len=n+1,需要還原
    printf("出隊順序:\n");
    while(len>0){
        printf("%d ",heap[1].n);
        deleteHeap(heap,len);
    }
    return 0;
}

void deleteHeap(num heap[],int &len){
    //交換堆頂和尾部元素
    heap[0].n=heap[len].n;
    heap[len].n=heap[1].n;
    heap[1].n=heap[0].n;
    len--;//長度-1
    int i=1;//分支選擇i
    while(2*i<=len){
        i=2*i+1;//進入下一層
        if(i>len || heap[i]<heap[i-1]) i--;
    }
    while(i>1){
        if(!(heap[i]<heap[0])) swap(heap[i],heap[0]);//比較當前結點和哨兵
        i/=2;//找父結點
    }
    heap[1].n=heap[0].n;//堆頂等於哨兵
}

void adjustUp(num heap[],int i){
    if(i==1) return;
    if(heap[i/2]<heap[i]) swap(heap[i/2],heap[i]);//小於父結點交換
    adjustUp(heap,i/2);//遞歸調整
}

樣例IO

輸入隊列個數:
7
輸入入隊元素:
1 2 3 4 5 6 7
出隊順序:
7 6 5 4 3 2 1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章