Minimum Heap/priority queue (implemented in C)

Source: Internet
Author: User

I recently asked for an internship to review the data structure.

A Complete Binary Tree has two forms: All Subtrees of a binary tree either have no children or have left children. Another type is binary tree, which either does not have Subtrees or must have left and right Subtrees.

Heap is a fully sorted binary tree. The data values of any non-terminal node are not greater than (or less than) the values of its left and right child nodes.

The maximum heap and the minimum heap are two types of binary heap.

Max heap: the key value of the root node is the one among the key values of all heap nodes.

Minimum heap: the key value of the root node is the smallest of all heap nodes.

In a priority queue, an element is given a priority. When an element is accessed, the element with the highest priority is deleted first. The priority queue has the highest (largest-in, first-out) behavior characteristics. The priority queue can be implemented through heap.

Next we use arrays to implement a minimum heap.

The Code is as follows:

MinHeap. h

# Ifndef destroy # define incluminheap; typedef struct MinHeap * MinPriorityQueue; typedef int ElementType; // initialize the heap initialize (int maxElements); // destroy the heap void destroy (paipqueue ); // clear the void makeEmpty (MinPriorityQueue pqueue) element in the heap; // insert void insert (ElementType x, MinPriorityQueue pqueue); // Delete the smallest operator, returns the deleted top-level element ElementType deleteMin (MinPriorityQueue pqueue). // you can specify the smallest (heap top) ElementType findMin (MinPriorityQueue pqueue ); // determine whether the heap is empty int isEmpty (MinPriorityQueue pqueue); // determine whether the heap is full int isFull (MinPriorityQueue pqueue); // create a heap using an array, it is equivalent to converting the unordered tree implemented by arrays into the heap sequence tree MinPriorityQueue buildHeap_insert (int * arr, int n); MinPriorityQueue buildHeap_percolate (int * arr, int n ); // print the heap void printMinPriorityQueue (MinPriorityQueue pqueue); # endif

MinHeap. c

# Include
 
  
# Include
  
   
# Include "MinHeap. h "/* mark nodes, similar to the header node in the linked list * The value must be smaller than the elements in all the smallest heaps, set the value to-1 */# define SentinelElement-1/** use arrays to achieve the maximum capacity of the ** capacity array * size array length * array of elements stored in the elements heap */struct MinHeap {int capacity; int size; ElementType * elements; // The number of heap elements is size. In fact, the length of the array used for storage is size + 1, which also includes an sentinel element}; voidPQueueNULLWarning () {printf ("Warning: Minimum Priority Queue is NULL");} voidoutOfSpaceFatalError () {printf ("Fatal E Rror: Out of space "); abort ();} MinPriorityQueueinitialize (int maxElements) {MinPriorityQueue pqueue; if (maxElements <= 0) {printf (" Fail to initialize: maxElements <= 0 "); return NULL;} pqueue = malloc (sizeof (struct MinHeap); if (pqueue = NULL) outOfSpaceFatalError (); // The 0th elements of the array are sentinel mark nodes, which are included in the array capacity, but not included in capcaity or size pqueue-> size = 0; pqueue-> capacity = maxElements; pqueue-> elements = mallo C (sizeof (ElementType) * (pqueue-> capacity + 1); if (pqueue-> elements = NULL) outOfSpaceFatalError (); else pqueue-> elements [0] = SentinelElement; return pqueue;} voiddestroy (MinPriorityQueue pqueue) {if (pqueue! = NULL) {// In the GNU99 standard, free (NULL) returns nothing directly, so you do not need to judge whether pqueue-> elements is NULL free (pqueue-> elements ); free (pqueue) ;}} voidmakeEmpty (MinPriorityQueue pqueue) {if (pqueue! = NULL) pqueue-> size = 0; else PQueueNULLWarning ();}/** when inserting, the elements in the heap perform the filter operation * When deleting, the time complexity of inserting elements in the heap into the filter operation * // ** is O (log N), and N is the minimum number of elements in the heap * actually, the average execution time is O (1) */voidinsert (ElementType x, MinPriorityQueue pqueue) {if (pqueue = NULL) PQueueNULLWarning (); if (isFull (pqueue )) {printf ("Fail to insert: Priority Queue is Full"); return;} else {int I; // The sentinel element is compared as elements [0] Here, is the condition for loop termination (I = ++ pqueue-> size; x <pqueue-> elements [I/2]; I/= 2) pqueue-> elements [I] = pqueue-> elements [I/2]; // pqueue-> elements [I] = x ;}} /** the average deletion time is O (log N) */ElementTypedeleteMin (MinPriorityQueue pqueue) {if (pqueue = NULL) {PQueueNULLWarning (); return SentinelElement ;} if (isEmpty (pqueue) {printf ("Fail to delete: Priority Queue is Empty"); return SentinelElement;} int I, child; ElementType minElement, lastElement; // when filtering a node, determine whether the node has two sons or one son minElement = pqueue-> elements [1]. lastElement = pqueue-> elements [pqueue-> size --]; for (I = 1; I * 2 <= pqueue-> size; I = child) {child = I * 2; // when node I has only one child, I * 2 = pqueue-> size if (child <pqueue-> size & pqueue-> elements [child]> pqueue-> elements [child + 1]) child ++; if (lastElement <pqueue-> elements [child]) break; else pqueue-> elements [I] = pqueue-> elements [child]; // filtering operation} pqueue-> elements [I] = lastElement; return minElement; // return the deleted element}/** execution time: O (1) */ElementTypefindMin (paipqueue) {if (pqueue = NULL) {Queue (); return SentinelElement;} else return pqueue-> elements [1];} intisEmpty (MinPriorityQueue pqueue) {if (pqueue = NULL) {PQueueNULLWarning (); return-1;} else return (pqueue-> size = 0);} intisFull (MinPriorityQueue pqueue) {if (pqueue = NULL) {PQueueNULLWarning (); return-1;} else return (pqueue-> size = pqueue-> capacity);} voidpercolateDown (int * arr, int len, int I) {int n = len-1; int tmp; if (I * 2 = n & arr [I]> arr [n]) // only the left son node, and the left son is smaller than the current node value, switch {tmp = arr [I]; arr [I] = arr [n]; arr [n] = tmp;} else // node with two sons {if (arr [I * 2]> arr [I * 2 + 1]) // The right son is relatively small {if (arr [I]> arr [I * 2 + 1]) // if the current node is larger than the right son, exchange {tmp = arr [I]; arr [I] = arr [I * 2 + 1]; arr [I * 2 + 1] = tmp ;}} else // The left son is relatively small {if (arr [I]> arr [I * 2]) // if the current node is larger than the left son, exchange {tmp = arr [I]; arr [I] = arr [I * 2]; arr [I * 2] = tmp ;}}} MinPriorityQueuebuildHeap_percolate (int * arr, int n) {if (arr = NULL) {printf ("Error: Array is NULL"); return NULL;} MinPriorityQueue pqueue; pqueue = malloc (sizeof (struct MinHeap); if (pqueue = NULL) outOfSpaceFatalError (); ElementType * elements = malloc (sizeof (ElementType) * (n + 1 )); if (elements = NULL) outOfSpaceFatalError (); int I; for (I = 1; I <= n; I ++) elements [I] = arr [I-1]; elements [0] = SentinelElement; for (I = n/2; I> 0; I --) percolateDown (elements, n + 1, I); pqueue-> elements = elements; pqueue-> size = n; pqueue-> capacity = n * 2; return pqueue ;} /** create a heap by inserting n elements. Since the average execution time of each insert is O (1), the average heap creation time is O (N) */MinPriorityQueuebuildHeap_insert (int * arr, int n) {MinPriorityQueue pqueue; if (arr = NULL) {printf ("Array is NULL, fail to build heap "); return NULL;} pqueue = initialize (n * 2); for (int I = 0; I <n; I ++) insert (arr [I], pqueue ); return pqueue;} voidprintMinPriorityQueue (MinPriorityQueue pqueue) {if (pqueue = NULL) {PQueueNULLWarning (); return;} if (pqueue-> elements = NULL) {printf ("Fail to print: Elements of priority queue is NULL"); return;} if (isEmpty (pqueue) {printf ("Empty Prioirty Queue \ n "); return;} printf ("Priority Queue \ n"); for (int I = 1; I <= pqueue-> size; I ++) printf ("Element [% d] = % d \ n", I, pqueue-> elements [I]); printf ("\ n ");}
  
 

Heap creation test code:

#include 
 
  #include 
  
   #include "MinHeap.h"int main(int argc, const char * argv[]){    int a[5] = {5, 4, 3, 2, 1};        MinPriorityQueue pqueue_ins = buildHeap_insert(a, 5);    MinPriorityQueue pqueue_per = buildHeap_percolate(a, 5);    printMinPriorityQueue(pqueue_ins);    printMinPriorityQueue(pqueue_per);        return 0;}
  
 

The heap is created using the insert and filter methods respectively, so the result is different and the output is as follows:

Priority QueueElement[1] = 1Element[2] = 2Element[3] = 4Element[4] = 5Element[5] = 3Priority QueueElement[1] = 1Element[2] = 5Element[3] = 3Element[4] = 2Element[5] = 4


The maximum heap implementation is similar.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.