資料結構&堆&heap&priority_queue&實現

Chicago_01發表於2018-09-21

什麼是堆?

堆是一種資料結構,可以用來實現優先佇列

大根堆

大根堆,顧名思義就是根節點最大。我們先用小根堆的建堆過程學習堆的思想。

小根堆

下圖為小根堆建堆過程
小根堆建堆過程

堆的操作

  • 上浮
  • 下沉
  • 插入
  • 彈出
  • 取頂
  • 堆排序

    STL heap

    所在庫 #include

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
bool cmp(int x,int y)
{
    return x>y;
}
int main()
{
    vector<int> a;
    int num,n=10;
    for(int i=0;i<n;i++)
    {
        num = rand()%(233*2);
        a.push_back(num);
    }
    
    for(vector<int>::iterator i=a.begin();i!=a.end();i++) 
    {
        cout<<*i<<ends;
    }cout<<endl<<endl;

    make_heap(a.begin(),a.end());//預設的大根堆
    for(vector<int>::iterator i=a.begin();i!=a.end();i++) 
    {
        cout<<*i<<ends;
    }cout<<endl<<endl;

    make_heap(a.begin(),a.end(),cmp);//自制的小根堆
    for(vector<int>::iterator i=a.begin();i!=a.end();i++) 
    {
        cout<<*i<<ends;
    }cout<<endl<<endl;

    a.push_back(2333);
    push_heap(a.begin(),a.end(),cmp);//將新加的元素加入堆中
    for(vector<int>::iterator i=a.begin();i!=a.end();i++) 
    {
        cout<<*i<<ends;
    }cout<<endl<<endl;
    
    a.pop_back(); //刪除尾部
    for(vector<int>::iterator i=a.begin();i!=a.end();i++) 
    {
        cout<<*i<<ends;
    }cout<<endl<<endl;

    getchar();getchar();getchar();getchar();
    return 0;
}

STL queue

所在庫#include

#include<bits/stdc++.h>
using namespace std;

struct student{
    int grade;
    string name;
};
struct cmp{
    bool operator() (student s1,student s2){
    return s1.grade < s2.grade;
    }
};

int main(int argc, char const *argv[])
{
    int n=10,num;
    /*
    1. push 【入隊插到隊尾】
    2. pop 【隊首元素出隊】
    3. size 【返回佇列中元素的個數】
    4. front 【返回佇列中第一個元素】
    5. back 【返回佇列中最後一個元素】
    6. empty 【判斷佇列是否為空】
    */
    //cout<<"佇列:"<<endl;
    queue<int> a;
    for(int i=1;i<n;i++){
        num = rand()%233;
        a.push(num);
    }
    //數列長度
    cout<<a.size()<<endl;
    //數列頭元素
    cout<<a.front()<<endl;
    //數列尾元素
    cout<<a.back()<<endl;
    //數列是否為空
    while(!a.empty()){
        cout<<a.front()<<ends;
        a.pop();
    }cout<<endl<<endl;
    
    priority_queue<int> pq_1;
    for(int i=1;i<n;i++){
        num = rand()%233;
        pq_1.push(num);
    }
    //預設情況下,數值大的在隊首位置(降序)
    while(!pq_1.empty()){
        //注意這裡的訪問頭元素為.top
        cout<<pq_1.top()<<ends;
        pq_1.pop();
    }cout<<endl;
    
    //以下情況下,數值小的在隊首位置(升序)
    priority_queue<int,vector<int>,greater<int> > pq_2;
    for(int i=1;i<n;i++){
        num = rand()%233;
        pq_2.push(num);
    }

    while(!pq_2.empty()){
        //注意這裡的訪問頭元素為.top
        cout<<pq_2.top()<<ends;
        pq_2.pop();
    }cout<<endl;cout<<endl;
    
    //運算子過載
    
    priority_queue<student,vector<student>,cmp> q;
    student s1,s2,s3;
    s1.grade = 90;
    s1.name = "Tom";

    s2.grade = 80;
    s2.name = "Jerry";

    s3.grade = 100;
    s3.name = "Kevin";

    q.push(s1);
    q.push(s2);
    q.push(s3);

    while(!q.empty()){
        cout<<q.top().name<<":"<<q.top().grade<<endl;
        q.pop();
    } 
    getchar();
    return 0;
}

相關文章