1. 程式人生 > >最大堆(最小堆)C++實現原始碼

最大堆(最小堆)C++實現原始碼

寫在前面

最近漸漸愛上寫部落格,覺得每天學到的知識需要保鮮,寫的原始碼也能及時與大家分享,接下來進入正題。

最大堆(最小堆)

最大堆(最小堆)是非常重要的資料結構,公司面試時經常會被問到,在這裡,我不會詳細介紹它的原理,而是介紹它的適用場景以及兩種寫法,對原理不瞭解的可以檢視:
https://en.wikipedia.org/wiki/Heap_%28data_structure%29
假設有10萬個數,讓你求最小的k個數,你會怎麼做?

  • 先排序,然後取前k個數,時間複雜度O(nlogn)
  • 維護k個數的最大堆,時間複雜度O(nlogk)

考慮第一種方式,當記憶體有限時,沒法一次載入10萬個數,排序不可取,而第二種方式,每次只載入一個數,最多儲存k個數(最大堆),當堆滿時,通過比較當前數與堆頂值,若堆頂值大,則刪除堆頂,插入當前數,反之,則不做任何操作,也就是說,最大堆一直儲存著當前載入數裡最小的k個數。

最大堆C++實現原始碼

這裡給出了兩種寫法,最小堆同理,值得注意的是,最大堆(最小堆)一定是一顆完全二叉樹,可以用陣列表示,如有錯誤還望指正。

  • 非遞迴寫法
#include <vector>
#include <cassert>
using namespace std;
class MaxHeap
{
private:
    vector<int> heap;
    int size;
public:
    void make_heap(vector<int>& nums, int s)
    {
        //構建堆
heap.assign(nums.begin(), nums.end()); size = s; for (int i = size / 2 - 1; i >= 0; i--) down(i); } void push(int num) { //插入元素 heap.push_back(num); size++; up(size - 1); } int pop() { //刪除元素 assert(size > 0
); int result = heap[0]; heap[0] = heap[size - 1]; heap.pop_back(); size--; down(0); return result; } void down(int index) { assert(index >= 0); int temp = heap[index]; index = index * 2 + 1; while (index < size) { if (index + 1 < size && heap[index] < heap[index + 1]) index++; if (heap[index] < temp) break; else { heap[(index - 1) / 2] = heap[index]; index = index * 2 + 1; } } heap[(index - 1) / 2] = temp; } void up(int index) { assert(index < size); int temp = heap[index]; while (index > 0 && temp > heap[(index - 1) / 2]) { heap[index] = heap[(index - 1) / 2]; index = (index - 1) / 2; } heap[index] = temp; } };
  • 遞迴寫法

void down(int index)
{
    assert(index >= 0);
    int temp = index;
    index = index * 2 + 1;
    if (index >= size) return;
    if (index + 1 < size && heap[index] < heap[index + 1]) index++;
    if (heap[index] < heap[temp]) return;
    else
    { 
        swap(heap[index], heap[temp]);
        down(index);
    }
}
void up(int index)
{
    assert(index < size);
    if (index == 0) return; 
    if (heap[index] < heap[(index - 1) / 2]) return;
    else 
    {
        swap(heap[index], heap[(index - 1) / 2]);
        up((index - 1) / 2);
    }
}

很明顯,遞迴寫法兩元素交換次數比非遞迴寫法多。

相關推薦

大堆C++實現原始碼

寫在前面 最近漸漸愛上寫部落格,覺得每天學到的知識需要保鮮,寫的原始碼也能及時與大家分享,接下來進入正題。 最大堆(最小堆) 最大堆(最小堆)是非常重要的資料結構,公司面試時經常會被問到,在這裡,我不會詳細介紹它的原理,而是介紹它的適用場景以及兩種寫法

【演算法】大堆大頂實現

此坑待埋。 下面來說一說具體演算法。 堆排序解釋第一篇(描述不太清楚) 1.堆   堆實際上是一棵完全二叉樹,其任何一非葉節點滿足性質:   Key[i]<=key[2i+1]&&Key[i]<=key[2i+2

排序C++

堆分為大根堆(最大堆)和小根堆(最小堆),堆排序就是二叉堆的升級版,實際上是一棵完全二叉樹 不同的是這棵二叉樹裡每個節點保證父節點都小於孩子節點 最後進行堆排序,將堆頂最小的節點(第一個)與最後一個節點(最大的節點)進行交換,對剩下的進行調節,令其滿足最小堆 #incl

AVL樹自平衡樹——c++實現

html pub private 檢查 具體實現 htm lose show data- AVL樹是高度平衡的而二叉樹。它的特點是:AVL樹中任何節點的兩個子樹的高度最大差別為1。 AVL樹本質上還是一棵二叉搜索樹,它的特點是: 1.本身首先是一棵二叉

Personal deposit calculator個人存款計算器C#實現----需求分析

參考招商銀行 個人存款計算器:http://www.cmbchina.com/CmbWebPubInfo/Cal_Saving_Per.aspx?chnl=ckjsq 需求分析,先上圖,有了這張圖需求分析完成一大半了 具體存款種類 2.1 初始介面

【LeetCode】1. Two Sum兩數之和-C++實現的兩種方法

本題是一下公司的面試題: 問題描述:   問題求解: 使用無序容器unorder_map實現: #include <iostream> #include <vector> #include <cassert> #inclu

簡單工廠模式/靜態工廠模式Static Factory Method C++實現

#include <iostream> using namespace std; typedef enum ProductType { TypeA, TypeB } PRODUCTTYPE; class AbsProduct { public : virtual vo

LRU近期最少使用演算法C++實現原始碼

寫在前面 今天一同學去公司實習面試,面試官要求手寫LRU演算法,有些懵。在這裡想寫篇部落格給他作為參考,同時也給大家作為參考。 LRU(最近最少使用演算法) LRU是CPU cache中n-w

資料結構——大堆C語言

定義:     最大堆和最小堆都是一棵完全二叉樹。     最大堆:是指根節點的關鍵字值是堆中的最大關鍵字值,且每個節點若有兒子節點,其關鍵字值都不小於其兒子節點的關鍵字值。     最小堆:是指根節

大堆 詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

大堆詳解

一、堆樹的定義 堆樹的定義如下: (1)堆樹是一顆完全二叉樹; (2)堆樹中某個節點的值總是不大於或不小於其孩子節點的值; (3)堆樹中每個節點的子樹都是堆樹。 當父節點的鍵值總是大於或等於任何一個

heapmax-heap大堆、min-heap

參考: 《STL原始碼剖析》 heap概述 heap並不歸屬於STL容器元件,它是個幕後英雄,扮演priority_queue的助手(底層實現)。所謂binary heap就是一種完全二叉樹,也就是說,整顆binary tree除了最底層的葉子節點之外,是填滿的,而最

大堆

一、堆樹的定義堆樹的定義如下:(1)堆樹是一顆完全二叉樹;(2)堆樹中某個節點的值總是不大於或不小於其孩子節點的值;(3)堆樹中每個節點的子樹都是堆樹。當父節點的鍵值總是大於或等於任何一個子節點的鍵值時為最大堆。 當父節點的鍵值總是小於或等於任何一個子節點的鍵值時為最小堆。如

大堆定義及其C++程式碼實現

資料:https://blog.csdn.net/guoweimelon/article/details/50904346 但是它的最大堆刪除部分的程式碼有問題,詳見連結裡的評論區 定義 堆首先必須是一棵完全二叉樹 最大堆:完全二叉樹,父節點的值不小於子節點的值 最小堆:完全二叉樹,父節

C++ multiset通過greater、less指定排序方式,實現大堆功能

    STL中的set和multiset基於紅黑樹實現,預設排序為從小到大。     定義三個multiset例項,進行測試: multiset<int, greater<int>> greadterSet;

排序--【演算法導論】

堆排序的思想在堆排序(最大堆)已做說明,故不再贅述; 總之,思想就是首先進行建堆,由於這是最小堆,故而必須保證父節點都小於孩子節點,若不滿足條件,則進行調節; 最後進行堆排序,不斷將最小的提取出來,並對剩下的進行調節,使之滿足最小堆; 故而將最大堆中的判斷父節點與孩子大小部

7-5 中的路徑

將一系列給定數字插入一個初始為空的小頂堆H[]。隨後對任意給定的下標i,列印從H[i]到根結點的路徑。 輸入格式: 每組測試第1行包含2個正整數N和M(≤1000),分別是插入元素的個數、以及需要列印的路徑條數。下一行給出區間[-10000, 10000]內的N個要被插入一個初始為空的小頂堆

哈夫曼樹 ->求結點值與權值積的和

#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; priority_queue<

【高效能定時器】時間

最小堆及其應用:時間堆 一、 堆 1. 概念 堆是一種經過排序的完全二叉樹,其中任一非終端節點的資料值均不大於(或不小於)其左子節點和右子節點的值。 其中,兩個葉子節點的大小沒有順序。 堆又分為兩種,最大堆、最小堆。由上面的

資料結構實現優先佇列

package xwq.dt; import java.util.Comparator; import java.util.Iterator; import java.util.NoSuchElementException; import xwq.util.