堆及其應用

2021-08-01 03:01:37 字數 4598 閱讀 5342

應用1.優先順序佇列

優先順序佇列 是不同於先進先出佇列的另一種佇列。每次從佇列中取出的是具有最高優先權的元素。

#pragma once

#include

#include

#include

#include "heap.h"

using

namespace

std;

template

class priorityqueue

void push(const t& d)

void pop()

const t& top()

protected:

heap _h;

};void testpriorityqueue()

; priorityqueue a1(a, 10);

}

應用2.n個數中找出最大的前k個數

在有大量的資料時,找出最大的前k個數。此類問題可以用堆來解決。

首先,取出n個資料中的前k個數,建立乙個有k個資料的小堆。

然後,把後面的資料依次和堆頂的資料比較,找出倆個數中大的資料放在堆頂,呼叫向下調整演算法,保證這是乙個小堆。這樣就可以找出最大的前k個數。

找出最小的k個數的方法也類似。

注意:找最大數時建的是小堆,找最小數時建的是大堆。

#pragma once

#include

#include

#include

using

namespace

std;

#define k 10

#define n 10000

template

//將根節點向下調整

void adjustdown(t *top,int root)

if (top[child] < top[parent] && child < k)

else

}}template

void gettopk(t *arr,t *top)

for (int j = (k - 2) / 2; j >= 0; j--)//建立乙個有k個資料的小堆

for (size_t i = k; i < n; i++)//比較第k+1--第n個資料,找出最大的k個數

}}template

void print(t *top)

cout

<< endl;

}void testgettopk()

; int top[k] = ;

for (size_t i = 0; i < n; i++)

gettopk(arr, top);

print(top);

}

應用3.堆排序

以公升序為例,堆排序首先建乙個小堆,找到最小的資料,放到最後。通過向下調整演算法(此時不用管陣列的最後乙個元素),找到最小的資料,放到最後,這樣依次操作,可把陣列排序。

#pragma once

#include

#include

#include

using

namespace

std;

template

void adjustdown(t* arr ,size_t root,size_t size)

if (arr[child] < arr[parent] && child < size)

else

}}template

void heapsort(t* arr, size_t size)

size_t end = size - 1;

while (end > 0)

};template

void print(t* arr,size_t size)

cout

<< endl;

}void testheapsort()

; heapsort(a, sizeof(a)/sizeof(a[0]));

print(a, sizeof(a) / sizeof(a[0]));

}

堆的性質

1、可以通過乙個簡單的陣列實現

2、支援最壞情況為o(logn)的insert和deletemin

3、支援常量平均時間的insert操作以及常量平均最壞時間的findmin操作。

4、二叉堆是實現優先順序佇列的典型方法

堆所支援的基本操作:

template

class binaryheap

;

一、堆的建立

堆的建立有兩種方式,一種是建立乙個空堆,另一種是通過複製乙個記錄陣列並對其加以調整形成乙個堆。

binaryheap()  

:_heap(0)

, _size(0)

{}

binaryheap(const

vector

&v)

:_heap(v.size()+1) //為了便於計算,多開闢乙個空間

, _size(v.size())

buildheap();

}

時間複雜度:o(n*lgn)

二、insert操作

insert所需要的是上滑調整,直接向_heap中插入資料,然後通過上滑調整順序。

void insert(const node& data)  

else

//如果父親結點比插入值大

} _heap[i] = data;

}

時間複雜度:o(lgn)

三、deletemin操作

由於最小堆的性質,根節點總是最小值,所以將陣列中最後乙個結點的值放到根節點的位置,然後_size自減,再從根節點開始進行一次下滑操作恢復堆的順序。

void

deletemin(node& data=node

()) //刪除最小元素,可以通過引數返回最小值

時間複雜度:o(lgn)

完整**:

#pragma once  

#include

#include

template

struct heapnode

heapnode(const t& data,size_t key)

:_data(data)

, _key(key)

{}

friend ostream& operator

<<(ostream& os,const heapnode& heap)

friend

bool

operator>(const heapnode& h1,const heapnode& h2)

friend

bool

operator

<(const heapnode& h1, const heapnode& h2)

};

template

class binaryheap

binaryheap(const

vector

&v)

:_heap(v.size()+1) //為了便於計算,多開闢乙個空間

, _size(v.size())

buildheap();

} void insert(const node& data)

else

//如果父親結點比插入值大

} _heap[i] = data;

} void deletemin(node& data=node()) //刪除最小元素,可以通過引數返回最小值

void makeheap() //置空堆

bool isempty()const

//判斷堆是不是為空

const node& findmin()const

//查詢堆中的最小元素

protected:

void buildheap() //恢復堆的順序

} void percolate(int hole) //從hole開始下滑調整

else

//如果tmp大於等於孩子的值,則繼續調整

} _heap[child] = tmp;

} protected:

vector

_heap;

int _size;

};

堆及其應用

對於堆的資料結構的介紹,在網上搜了下,具體講的不是很多。發現比較好的一篇介紹堆的部落格是在此感謝他。通過對上面那篇部落格的學習,然後自己也去翻了下 演算法導論 裡面關於堆排序 heapsort 的介紹。這樣就對堆有了更加深刻的認識,在此,我結合自己的一點點理解,主要還是基於上面那篇部落格的內容 主要...

堆及其應用學習小結

堆及其應用 堆結構是一種陣列物件,它可以被視為一棵完全二叉樹。如果一棵深度為k二叉樹,1至k 1層的結點都是滿的,即滿足2i 1,只有最下面的一層的結點數小於2i 1,並且最下面一層的結點都集中在該層最左邊的若干位置,則此二叉樹稱為完全二叉樹。樹中每個結點與陣列中存放該結點中值的那個元素相對應 大根...

堆及其操作

堆及其操作 include include include define maxdata 1000 該值根據具體情況定義為大於堆中所有可能元素的值 define error 1 錯誤標誌 應根據具體情況定義為堆中不可能出現的元素值 堆的c語言描述 struct hnode struct hnode ...