1、堆
堆代碼實現與堆排序
#include<iostream>
#include<queue>
#include <math.h>
using namespace std;
#define MAX_HEAP_SIZE 11
/************************************************************************/
/*
6
3#4
1#9 2#8
10#7 5# ## ##
*/
/************************************************************************/
typedef union myheap
{
int m_size;
int m_heapmem[MAX_HEAP_SIZE];
}*ptrHeap;
void init_heap(ptrHeap* heap, int size = 10){
if (size + 1>MAX_HEAP_SIZE)
{
printf("out of memery\n"); return;
}
*heap = (ptrHeap)malloc(sizeof(myheap));
int temp[10] = { 6, 3, 4, 1, 9, 2, 8, 10, 7, 5 };
(*heap)->m_size = size;
for (int i = 0; i < size; ++i)
{
(*heap)->m_heapmem[i + 1] = temp[i];
}
}
void swap(int& a, int& b){
if (a == b)
{
return;
}
a = a^b;
b = a^b;
a = a^b;
}
//完全二叉樹 逐層層序遍歷,堆在數組中存儲時的程序遍歷只需遍歷一遍數組即可,時間複雜度爲O(n)
/*
教訓總結:
寫代碼前一定要想將思路理順了,跟着邏輯走,而不要跟着記憶走,“隱約的記得好像其他類似的做法是這樣的”這樣的思維方式很有問題,抓不住問題的本質,即使順着記憶做出來了,下次也可能會忘記,
而且容易沉溺於“想不起上次的做法”而苦惱的境地。
*/
void dump_heap(ptrHeap heap){
int size = heap->m_size;
queue<int> level;
level.push(heap->m_heapmem[1]);
int i = 0;
int le = 0;
while (i<size)
{
while (!level.empty())
{
printf(" %d ", level.front()); level.pop();
i++;
}
printf("\n");
//找到各層結點的開始下標和結束下標(太傻叉了 這個實現,完全沒有必要用隊列啊)
for (int j = i / 2 + 1; j < i / 2 + 1 + (int)pow(2, le) && 2 * j <= size; ++j)
{
level.push(heap->m_heapmem[j * 2]);
if (2 * j + 1 <= size)
{
level.push(heap->m_heapmem[j * 2 + 1]);
}
}
le++;
}
}
void dump_heap2(ptrHeap heap)
{
int size = heap->m_size;
int maxlevel = size / 2;
int count = 0;
//找到各層的起點和終點下標,然後進行遍歷
for (int level = 0; level < maxlevel && count < size; ++level){
int startIndex = (1 << level) /* (int)pow(2, level)*/;
int endIndex = startIndex + (1 << level) /*(int)pow(2, level)*/;
for (; startIndex < endIndex && startIndex<=size; ++startIndex){
printf("%d ", heap->m_heapmem[startIndex]);
count++;
}
printf("\n");
}
}
void heapify(ptrHeap* heap, int parent,int size){
int maxIndex = 0;
int left = 0;
int right = 0;
while (true)
{
maxIndex = parent;
left = parent * 2;
right = left + 1;
if ((*heap)->m_heapmem[maxIndex] < (*heap)->m_heapmem[left] && (left <= size)){
maxIndex = left;
}
if ((*heap)->m_heapmem[maxIndex] < (*heap)->m_heapmem[right] && (right <= size)){
maxIndex = right;
}
if (maxIndex == parent){
break;
}
swap((*heap)->m_heapmem[parent], (*heap)->m_heapmem[maxIndex]);
parent = maxIndex;
}
}
void dump(ptrHeap heap){
printf("\n");
int size = heap->m_size;
for (int i = 1; i <= size; ++i){
printf(" %d ", heap->m_heapmem[i]);
}
printf("\n");
}
void build_heap(ptrHeap heap)
{
int size = heap->m_size;
for (int i = size / 2; i > 0; --i){
heapify(&heap, i,size);
}
}
void heap_sort(ptrHeap pHeap){
int size = pHeap->m_size;
while (size>1)
{
//堆化
for (int i = size / 2; i > 0; --i){
heapify(&pHeap, i,size);
}
//堆化後將最大元素(第一個元素)放在最後一位
swap(pHeap->m_heapmem[1], pHeap->m_heapmem[size]);
size--;
}
}
int main()
{
ptrHeap pHeap = nullptr;
cout << "before build heap:" << endl;
init_heap(&pHeap);
dump_heap2(pHeap);
cout << "after build heap:" << endl;
build_heap(pHeap);
dump_heap2(pHeap);
printf("before heap sort:\n");
dump(pHeap);
printf("after heap sort:\n");
heap_sort(pHeap);
dump(pHeap);
system("pause");
return 0;
}