heap.h
#pragma once
#includetypedef int heaptype;
#define heapmaxsize 1000
typedef int(*compare)(heaptype a, heaptype b);
typedef struct heapheap;
/*初始化*/
void heapinit(heap* heap);
/*插入元素*/
void heapinsert(heap* heap, heaptype value);
/*取堆頂元素*/
heaptype heaproot(heap* heap);
/*刪除堆頂元素*/
void heaperase(heap* heap);
/*堆判空*/
int heapempty(heap* heap);
/*求堆的大小*/
size_t heapsize(heap* heap);
/*銷毀堆*/
void heapdestory(heap* heap);
/*堆排序*/
void heapsort(heaptype data, size_t size);
heap.c
#define _crt_secure_no_warnings 1
#include"heap.h"
#include#include#include/*大堆用的函式*/
int no_less(heaptype a, heaptype b)
/*小堆用的函式*/
int less(heaptype a, heaptype b)
/*交換兩個數*/
void swap(heaptype* a, heaptype* b)
/*初始化*/
void heapinit(heap* heap)
heap->size = 0;
heap->cmp = less;
}/*這裡把乙個堆中最後乙個元素上浮*/
void adjustup(heaptype data, size_t size, compare cmp, size_t index)
cur = f_cur; }}
void adjustdown(heaptype data, size_t size, compare cmp, size_t index)
if (!cmp(data[parent], data[child]))
else
parent = child;
child = parent * 2 + 1; }}
/*小堆插入元素*/
void heapinsert(heap* heap, heaptype value)
if (heap->size >= heapmaxsize)
/*尾插乙個元素,然後上浮*/
size_t cur = heap->size;
heap->data[heap->size++] = value;
/* while (1)
//每次與父節點比較
//如果value小,返回1進入迴圈
size_t f_cur = (cur - 1) / 2;
if (heap->cmp(heap->data[cur], heap->data[f_cur]))
cur = f_cur;
} */
adjustup(heap->data, heap->size, less, heap->size - 1);
}/*取堆頂元素*/
heaptype heaproot(heap* heap)
if (heap->size == 0)
else
}/*刪除堆頂元素*/
void heaperase(heap* heap)
if (heap->size == 0)
/*先把堆頂元素和最後乙個位置的元素交換*/
swap(&heap->data[0], &heap->data[heap->size - 1]);
--heap->size;
/*然後再把堆重新排好*/
adjustdown(heap->data, heap->size, less, 0);
}/*堆判空*/
int heapempty(heap* heap)
return heap->size == 0 ? 1 : 0;
}/*求堆的大小*/
size_t heapsize(heap* heap)
return heap->size;
}/*銷毀堆*/
void heapdestory(heap* heap)
heap->size = 0;
heap->cmp = null;
}#if 0
/***堆排序
**這裡是小堆排序,如果需要大堆排序,需要把adjustup和adjustdown的cmp函式換成no_less
*/void heapsort(heaptype data, size_t size)
/*先用陣列建立乙個*/
size_t heap_size = 0;
/*直接用當前陣列進行堆的建立*/
for (; heap_size < size; ++heap_size)
/*然後對這個陣列進行排序*/
while (heap_size > 1)
}#elif 1
void heapsort(heaptype data, size_t size)
/*把當前陣列變成小堆*/
//size是陣列的元素個數,size - 1是當前最後乙個元素的下標位置,然後再 減1除以2,找到最後乙個結點的父節點
size_t start = (size - 1 - 1) / 2;
/*因為start是無符號長整型,所以在這個迴圈裡不能為0*/
for (; start > 0; --start)
adjustdown(data, size, less, start);
/*然後對這個陣列進行排序*/
while (size > 1)
}#endif
test.c
#define _crt_secure_no_warnings 1
#include"heap.h"
#include#include#define testheadr printf("--------------%s--------------\n",__function__)
void printheap(heap* heap, char* msg)
printf("%s:\n\n", msg);
if (heap->size == 0)
int i = 0;
for (; i < heap->size; i++)
printf("\n\n\n");
}void testinit()
void testinsert()
void testheaproot()
void testerase()
void testempty()
void testheapsize()
void testheapdestory()
void testheapsort() ;
size_t size = sizeof(data) / sizeof(data[0]);
heapsort(data, size);
int i = 0;
for (; i < size; i++)
printf("\n");
}int main()
資料結構 堆的基本操作及堆排序
首先我們要將資料結構中的堆和記憶體中的堆區區分開來,記憶體中的堆區是作業系統管理的,和資料結構中的堆沒有半毛錢關係。堆只有兩種,大堆和小堆。我們通常用乙個陣列來表示乙個堆,陣列中存放的是堆的層序遍歷結果,第乙個元素即根節點 定義乙個比較函式的函式指標,用來指明該堆是小堆還是大堆 typedef in...
堆(資料結構)及堆排序
這裡的堆是指一種資料結構 或資料結構屬性 非指堆記憶體。堆屬性用二叉樹來體現,具堆屬性的資料結構才可被叫做為堆。具堆屬性的資料結構滿足以下筆記的 順序 和 形狀 兩個條件。將某資料結構如陣列,將陣列的元素依次安排在二叉樹中的根結點 根結點的左孩子 根結點的右孩子位置之上,再將剩餘元素依次安排在根結點...
資料結構 堆以及堆排序
堆可以看作是一棵完全二叉樹,除最後一層外,每一層都是填滿的,最後一層從左到右依次填入 在堆上,對任意乙個結點來說,越接近頂部,權值就越大 一般指大頂堆 並且它的權值大於等於它所在子樹所有點的權值 我們把根結點權值大於等於樹中結點權值的稱為大根堆,小於等於樹種結點權值的稱為小根堆 下圖就是乙個大根堆的...