# <center><font size=10>priority_queue.a</font> <br> <font size=5>優先權佇列使用說明書</font> <br> <font size=4>by 李奕承</font></center> # <center>摘要</center> 本library提供的結構如下 ```c typedef struct HeapType { void * elements; int numElementds; }Heap_t; typedef enum { MINHEAP = 0, MAXHEAP }H_class; // 使用者會操作的 typedef struct PQ { H_class pqClass; Heap_t heap; int maxSize; int elementSize; int (*compare)(void * elementA, void * elementB); }PQ_t; ``` 本 library 使用陣列跟index換算來模擬二元樹的走訪,並提供以下幾種函數 - 產生優先權佇列 - 判斷優先權佇列是否為空 - 以完全二元樹印出優先權佇列 - 插入 - 計算優先權佇列Level - 判斷優先權佇列是否已滿 - 取出 # <center>使用方法</center> ### 1.帶入標頭檔 ```c #include"pqSpec.h" ``` ### 2.創造 priority queue 宣告一個 PQ_t ,使用 createPQ() 填入PQ_t的各項設定,例如: ```c PQ_t first_pq; createPQ(&first_pq, MINHEAP, 10, compareMath); ``` first_pq : 是優先權佇列的指標 MINHEAP : 是枚舉值,代表值越小的優先 10 : 是資料的數量,本 priority queue 在創建時會申請一塊固定大小的記憶體作為指標陣列 compareMath : 是用來比較值的函數,由使用者編寫並提供函數指標 ### 3.編寫並提供回調函數指標 以下兩個需要使用者編寫並提供回調函數指標 ```c createPQ pq_printf_tree ``` ### 4.編譯 - pqSpec.h 要記得放在引用標頭檔的路徑下 - 編譯時記得加入 priority_queue.a ``` gcc -I include -Wall -o ./bin/test test.c priority_queue.a ``` # <center>函數介紹與範例</center> ## 範例使用的結構 下面是範例用到的結構 ```c typedef struct test_element { char ID[10]; int math; int eng; }student_t; ``` 下面是範例中使用者提供給 libary 用來比較 priority 的函數 ```c int compareMath(void* elementA, void* elementB) { if(((student_t *)elementA)->math > ((student_t *)elementB)->math) { return 1; } else if(((student_t *)elementA)->math < ((student_t *)elementB)->math) { return -1; } return 0; } ``` 下面範例中使用者用來取出元素中數值的函數 ```clike char* get_math(void* element) { static char buffer[20]; sprintf(buffer, "%d", ((student_t*)element)->math); return buffer; } ``` ## 產生優先權佇列 ```clike void createPQ(PQ_t* pq, H_class pqClass, int maxSize, int(*compare)(void* elementA, void* elementB)); ``` 當你宣告一個 PQ_t 之後,要使用這個函數來設定 PQ_t 中需要用到的值 其中包括 PQ_t 的地址、Heap的類型(最大或最小)、priority queue 容納的上限、用來比較 priority 的函數(由使用者提供),以下是範例。 ```clike PQ_t first_pq; createPQ(&first_pq, MINHEAP, 10, compareMath); ``` ## 判斷優先權佇列是否為空 ```clike int IsEmpty(PQ_t* pq); ``` 使用這個函數可以判斷 priority queue 是否為空,以下是範例。 ```clike printf("is queue empty? 0->true 1->false : %d\n", IsEmpty(&first_pq)); ``` 終端機的輸出 ``` is queue empty? 0->true 1->false : 0 ``` ## 以完全二元樹印出優先權佇列 ```clike void pq_printf_tree(PQ_t* pq, char*(*get_data)(void* queue_member)); ``` 使用這個函數可以將 priority queue 以完全二元樹的形式印出來,便於除錯,以下是範例 ```clike pq_printf_tree(&first_pq, get_math); ``` 終端機的輸出可以在後續的敘述中看到 ## 插入 ```clike int Enqueue(PQ_t* pq, void* elementA); ``` 使用這個函數可以在 priority queue 中加入新的元素,以下是範例。 ```clike student_t node[10] = { {"A", 70, 100}, {"B", 60, 90}, {"C", 80, 95}, {"D", 65, 90}, {"E", 10, 70}, {"F", 90, 90}, {"G", 20, 60}, {"H", 30, 50}, {"I", 40, 40}, {"J", 50, 30} }; for(int i = 0 ; i < 10 ; i++) { Enqueue(&first_pq, &node[i]); pq_printf_tree(&first_pq, get_math); } ``` 終端機的輸出 ``` 70 60 / / 70 60 / \ / \ 70 80 60 / \ / \ / \ 65 80 / / 70 10 / \ / \ / \ 60 80 / \ / \ 70 65 10 / \ / \ / \ 60 80 / \ / / \ / 70 65 90 10 / \ / \ / \ 60 20 / \ / \ / \ / \ 70 65 90 80 10 / \ / \ / \ / \ / \ / \ / \ 30 20 / \ / \ / \ / \ / \ / \ 60 65 90 80 / / 70 10 / \ / \ / \ / \ / \ / \ / \ 30 20 / \ / \ / \ / \ / \ / \ 40 65 90 80 / \ / \ 70 60 10 / \ / \ / \ / \ / \ / \ / \ 30 20 / \ / \ / \ / \ / \ / \ 40 50 90 80 / \ / / \ / 70 60 65 ``` ## 計算Level ```clike int count_pq_level(PQ_t* pq); ``` 使用這個函數可以算出 priority queue 的Level數,以下是範例。 ```clike pq_printf_tree(&first_pq, get_math); printf("the tree level is : %d\n", count_pq_level(&first_pq)); ``` ``` 10 / \ / \ / \ / \ / \ / \ / \ 30 20 / \ / \ / \ / \ / \ / \ 40 50 90 80 / \ / / \ / 70 60 65 the tree level is : 3 ``` ## 判斷是否已滿 ```clike int IsFull(PQ_t* pq); ``` 使用這個函數可以判斷 priority queue 是否已滿,以下是範例。 ```clike printf("is queue full? 0->true 1->false : %d\n", IsFull(&first_pq)); ``` 終端機的輸出 ``` is queue full? 0->true 1->false : 0 ``` ## 取出 ```clike void* Dequeue(PQ_t* pq); ``` 使用這個函數可以在 priority queue 中取出最上層的元素,以下是範例。 ```clike pq_printf_tree(&first_pq, get_math); for(int i = 0 ; i<10 ; i++) { printf("-----------------------------------------\n"); printf("get : %s\n", get_math(Dequeue(&second_pq))); pq_printf_tree(&second_pq, get_math); } ``` 終端機的輸出 ``` 10 / \ / \ / \ / \ / \ / \ / \ 30 20 / \ / \ / \ / \ / \ / \ 40 50 90 80 / \ / / \ / 70 60 65 ----------------------------------------- get : 10 20 / \ / \ / \ / \ / \ / \ / \ 30 65 / \ / \ / \ / \ / \ / \ 40 50 90 80 / \ / \ 70 60 ----------------------------------------- get : 20 30 / \ / \ / \ / \ / \ / \ / \ 40 65 / \ / \ / \ / \ / \ / \ 60 50 90 80 / / 70 ----------------------------------------- get : 30 40 / \ / \ / \ 50 65 / \ / \ / \ / \ 60 70 90 80 ----------------------------------------- get : 40 50 / \ / \ / \ 60 65 / \ / / \ / 80 70 90 ----------------------------------------- get : 50 60 / \ / \ / \ 70 65 / \ / \ 80 90 ----------------------------------------- get : 60 65 / \ / \ / \ 70 90 / / 80 ----------------------------------------- get : 65 70 / \ / \ 80 90 ----------------------------------------- get : 70 80 / / 90 ----------------------------------------- get : 80 90 ----------------------------------------- get : 90 ```