資料結構之(二叉)堆

2021-06-22 12:36:23 字數 2975 閱讀 9220

(二叉)堆是乙個陣列,是一顆近似完全二叉樹,分為大頂堆&小頂堆。表示堆的陣列a有兩個屬性:(1)a.length表示陣列元素的個數;(2)a.heap-size表示有多少個堆元素儲存在陣列a中。更多的關於堆的性質的介紹:演算法導論第三版:p85-p89、程式設計珠璣:p141-p145。

堆的操作主要包括堆插入堆刪除兩個,而堆插入設計到siftup操作(自底向上調整),堆刪除涉及到siftdown操作(自頂向下調整,大頂堆時對應演算法導論上的max-heapify操作)。

下面是大頂堆和小頂堆的基本操作的c++的實現:

#pragma once

templateclass heap

virtual ~heap()

void insert(const t &e);

void delete(const t &e);

int search(const t &e) const;

void print() const;

protected:

t *arr;

const int max_size; //max array elements

int size; //size of heap

virtual void siftdown(int i) = 0; //adjust from up to down

virtual void siftup(int i) = 0; //adjust from down to up

};templatevoid heap::insert(const t &e)

templatevoid heap::delete(const t &e)

templateint heap::search(const t &e)const

templatevoid heap::print()const

最大堆:maxheap.h

#pragma once

#include "heap.h"

#include using std::cout;

using std::endl;

templateclass maxheap : public heap

~maxheap() {}

private:

virtual void siftdown(int i); //adjust from up to down

virtual void siftup(int i); //adjust from down to up

};templatevoid maxheap::siftdown(int i)

arr[i] = tmp;

}templatevoid maxheap::siftup(int i)

arr[i] = tmp;

}

最小堆:minheap.h

#pragma once

#include "heap.h"

#include using std::cout;

using std::endl;

templateclass minheap : public heap

~minheap(){}

private:

virtual void siftdown(int i);

virtual void siftup(int i);

};templatevoid minheap::siftdown(int i)

arr[i] = tmp;

}templatevoid minheap::siftup(int i)

arr[i] = tmp;

}

測試**:

#include "maxheap.h"

#include "minheap.h"

int main()

; maxheapmaxheap(20);

minheapminheap(20);

for (int i = 0; i < 12; i++)

maxheap.insert(a[i]); //向上調整

maxheap.print();

maxheap.delete(4); //向下調整

maxheap.print();

for (int i = 0; i < 12; i++)

minheap.insert(a[i]); //向上調整

minheap.print();

minheap.delete(4); //向下調整

minheap.print();

getchar();

return 0;

}

這裡用的是插入的方法建堆:最壞情況下,建立乙個包含n個元素的堆的時間複雜度是o(nlgn),大theta。

一般地,還要k叉堆:演算法導論第三版p93。

利用堆可以實現:堆排序

、優先佇列

。在dijkstra演算法中: extract-min(q) 操作,就可以先建立最小堆,然後從最小佇列中,每次抽取最小結點(參考 最短路徑之dijkstra演算法 一文的參考資料鏈結)。

此外,堆還可以用於:海量資料中選擇前k個最大(最小)的數。

思想:在乙個很大的無序陣列裡面選擇前k個最大(最小)的資料,最直觀的做法是把陣列裡面的資料全部排好序,然後輸出前面最大(最小)的k個資料。但是,排序最好需要o(nlogn)的時間,而且我們不需要前k個最大(最小)的元素是有序的。這個時候我們可以建立k個元素的最小堆(得出前k個最大值)或者最大堆(得到前k個最小值),我們只需要遍歷一遍陣列,在把元素插入到堆中去只需要logk的時間,這個速度是很樂觀的。利用堆得出前k個最大(最小)元素特別適合海量資料的處理。

資料結構之二叉堆

二叉堆的介紹 二叉堆是完全二元樹或者是近似完全二元樹,按照資料的排列方式可以分為兩種 最大堆和最小堆。示意圖如下 二叉堆一般都通過 陣列 來實現。陣列實現的二叉堆,父節點和子節點的位置存在一定的關係。有時候,我們將 二叉堆的第乙個元素 放在陣列索引0的位置,有時候放在1的位置。當然,它們的本質一樣 ...

基礎資料結構之二叉堆

二叉堆一般用於涉及插入 刪除 查詢最值得題目。往往配合其它題型使用。對頂堆 對頂堆常用於動態維護的問題。動態中位數 動態求解前i個數的中位數。黑盒子 動態求解前u i 個數第i大的數。超市 貪心題目。需要用到二叉堆的查詢最值 插入和刪除功能。序列 多路歸併問題。注意到是求和問題,題目讓求m個序列 合...

資料結構 二叉堆

二叉堆一般用來實現優先佇列 優先佇列是一種至少允許以下兩種操作的資料結構 insert 以及 deletemin 同查詢樹一樣,二叉堆具有結構性與堆序性,對二叉堆的基本操作可能會破壞這些性質,所以二叉堆的操作要直到其基本性質滿足才能結束。一 結構性 二叉堆在結構上為完全二叉樹,其具有完全二叉樹的結構...