應用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 ...