The C language Implementation code _c language of Priority queue (Priority_queue)

Source: Internet
Author: User
Tags data structures

The precedence queue (priority_queue) is consistent with the function interface of the general queue (queue), and, in contrast, the priority queue is the smallest (or largest) element in the entire queue each time it is queued.

This paper briefly introduces a priority queue based on an array two-fork heap, defines the data structure and implements the function interface as follows:

One, the key value pairs the structure body: keyvalue

Copy Code code as follows:

=============keyvalue struct==================================
typedef struct KEY_VALUE_STRUCT keyvalue;
struct KEY_VALUE_STRUCT
{
int _key;
void *_value;
};
KeyValue *key_value_new (int key, void *value);
void Key_value_free (KeyValue *kv, Void (*freevalue) (void *));

Key-value pairs are saved as the data in the precedence queue, where key holds the priority and _value is used to point to the actual data.

Key_value_new is used to create a keyvalue structure, key_value_free to release memory for a keyvalue structure,

The parameter freevalue is used to free the memory pointed to by the data pointer _value.

Second, priority queue structure body: Priorityqueue

Copy Code code as follows:

=============priorityqueue struct==============================
#define PRIORITY_MAX 1
#define PRIORITY_MIN 2
typedef struct PRIORITY_QUEUE_STRUCT Priorityqueue;
struct PRIORITY_QUEUE_STRUCT
{
KeyValue **_nodes;
int _size;
int _capacity;

int _priority;
};
Priorityqueue *priority_queue_new (int priority);
void Priority_queue_free (Priorityqueue *pq, Void (*freevalue) (void *));
Const KeyValue *priority_queue_top (Priorityqueue *pq);
KeyValue *priority_queue_dequeue (Priorityqueue *pq);
void Priority_queue_enqueue (Priorityqueue *pq, keyvalue *kv);
int priority_queue_size (Priorityqueue *pq);
int Priority_queue_empty (Priorityqueue *pq);
void Priority_queue_print (Priorityqueue *pq);


1)Where the Nodes field is a two-fork heap array, _capacity is the number of keyvalue* pointers that nodes points to, and _size is the number of elements actually stored in nodes.

_priority can be either Priority_max or priority_min, representing the maximum element first and the minimum element first.

2) priority_queue_new and Priority_queue_free are used to create and release priority queues, respectively.

3) priority_queue_top is used to get the queue head element,

4) Priority_queue_dequeue is used to get the queue header element and to move the element out.

The basic idea of its implementation, with the highest priority queue description is as follows:

① the queue header nodes[0] as the return value

② the queue tail nodes[_size-1] in nodes[0] position, and make _size=_size-1

③ makes the current parent node parent (Nodes[i]) equal to the new queue header (i=0) element.

Parent points to the son node of the element left = nodes[2 * i + 1] and rigth = nodes[2 * i + 2],

Compare left and right to get higher priority son nodes, set to Nodes[j] (j = 2 *i + 1 or 2 *i + 2),

④ if the current parent node parent has precedence over nodes[j], swaps nodes[i] and nodes[j, and updates the current parent node,

Be i=j, and circulate ③;

If the current parent node has a lower priority than NODES[J], the process ends.

5) Priority_queue_enqueue is used to KeyValue row

The basic idea of its implementation, with the highest priority queue description is as follows:

① set Nodes[_size] for the new keyvalue, and make _size++

The ② makes the current son node child (Nodes[i]) The new Queue Tail node (i=_size-1), and the parent of children is nodes[j],

of which j= (i-1)/2

③ if the current son node child's priority is higher than parent, swap nodes[i] and nodes[j], and update the current son node

i = j, and cyclic ③;

If the current son node has a lower priority than parent, the processing ends.

6 priority_queue_size is used to get the number of elements in the queue, Priority_queue_empty is used to determine whether the queue is empty.

7) Priority_queue_print is used to output the contents of the queue.

The file pq.h gives the data structure and function declaration, the file pq.c gives the concrete implementation, the MAIN.C file is used for the test. Although the use of procedural programming in C language, you can see the specific coding in the application of object-based ideas, we have to data structures and related functions to do a certain degree of aggregation and encapsulation.

Copy Code code as follows:

/*
*file:pq.h
*purpose:declaration of priority queue in C
*/
#ifndef _priority_queue_h
#define _priority_queue_h

=============keyvalue struct==================================
typedef struct KEY_VALUE_STRUCT keyvalue;
struct KEY_VALUE_STRUCT
{
int _key;
void *_value;
};
KeyValue *key_value_new (int key, void *value);
void Key_value_free (KeyValue *kv, Void (*freevalue) (void *));

=============priorityqueue struct==============================
#define PRIORITY_MAX 1
#define PRIORITY_MIN 2
typedef struct PRIORITY_QUEUE_STRUCT Priorityqueue;
struct PRIORITY_QUEUE_STRUCT
{
KeyValue **_nodes;
int _size;
int _capacity;

int _priority;
};
Priorityqueue *priority_queue_new (int priority);
void Priority_queue_free (Priorityqueue *pq, Void (*freevalue) (void *));
Const KeyValue *priority_queue_top (Priorityqueue *pq);
KeyValue *priority_queue_dequeue (Priorityqueue *pq);
void Priority_queue_enqueue (Priorityqueue *pq, keyvalue *kv);
int priority_queue_size (Priorityqueue *pq);
int Priority_queue_empty (Priorityqueue *pq);
void Priority_queue_print (Priorityqueue *pq);

#endif

/*
*file:pq.c
*purpose:definition of priority queue in C
*author:puresky
*date:2011/04/27
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Pq.h"

Private functions
static void Priority_queue_realloc (Priorityqueue *pq);

static void Priority_queue_adjust_head (Priorityqueue *pq);

static void Priority_queue_adjust_tail (Priorityqueue *pq);

static int Priority_queue_compare (Priorityqueue *pq,
int POS1,
int pos2);
static void Priority_queue_swap (KeyValue **nodes,
int POS1,
int pos2);

Functions of KeyValue Struct
KeyValue *key_value_new (int key,
void *value)
{
KeyValue *pkv = (KeyValue *) malloc (sizeof (keyvalue));
Pkv->_key = key;
Pkv->_value = value;
return pkv;
}
void Key_value_free (KeyValue *kv,
void (*freevalue) (void *))
{
if (KV)
{
if (Freevalue)
{
Freevalue (Kv->_value);
}
Free (kv);
}
}


//functions of Priorityqueue Struct
Priorityqueue *priority_queue_new (int priority)
{
       priorityqueue *PQ = (Priorityqueue *) malloc (sizeof (priorityqueue));
      pq->_capacity =//default initial value
      pq->_size = 0;
      pq->_priority = priority;

      pq->_nodes = (keyvalue * *) malloc (sizeof (keyvalue *) * pq->_capacity);
      return PQ;
}

Void Priority_queue_free (Priorityqueue *pq,
               void (*freevalue) (void *)
{
      int i;
      if (PQ)
      {
             for (i = 0; i < pq->_size; ++i)
                   Key_value_free (Pq->_nodes[i], freevalue);
            Free (pq->_nodes);
            Free (PQ);
     }
}

Const KeyValue *priority_queue_top (Priorityqueue *pq)
{
if (pq->_size > 0)
Return pq->_nodes[0];
return NULL;
}

KeyValue *priority_queue_dequeue (Priorityqueue *pq)
{
KeyValue *pkv = NULL;
if (pq->_size > 0)
{
PKV = pq->_nodes[0];
Priority_queue_adjust_head (PQ);
}
return pkv;
}

void Priority_queue_enqueue (Priorityqueue *pq,
KeyValue *kv)
{
printf ("Add key:%d\n", Kv->_key);
Pq->_nodes[pq->_size] = kv;
Priority_queue_adjust_tail (PQ);
if (pq->_size >= pq->_capacity)
Priority_queue_realloc (PQ);
}

int priority_queue_size (Priorityqueue *pq)
{
Return pq->_size;
}

int Priority_queue_empty (Priorityqueue *pq)
{
return pq->_size <= 0;
}

Void Priority_queue_print (Priorityqueue *pq)
{
      int i;
      KeyValue *kv;
      printf ("Data in the pq->_nodes\n");
      for (i = 0; i < pq->_size; ++i)
             printf ("%d", pq->_nodes[i]->_key);
      printf ("\ n");

      printf ("Dequeue all data\n");
      while (!priority_queue_empty (PQ))
      {
             kv = Priority_queue_dequeue (PQ);
            printf ("%d", kv->_key);
     }
      printf ("\ n");
}

static void Priority_queue_realloc (Priorityqueue *pq)
{
pq->_capacity = pq->_capacity * 2;
Pq->_nodes = realloc (pq->_nodes, sizeof (keyvalue *) * pq->_capacity);
}

static void Priority_queue_adjust_head (Priorityqueue *pq)
{
int I, J, parent, left, right;

i = 0, j = 0;
Parent = left = right = 0;
Priority_queue_swap (pq->_nodes, 0, pq->_size-1);
pq->_size--;
while (I < (pq->_size-1)/2)
{
parent = i;

left = i * 2 + 1;
right = left + 1;
j = left;
if (Priority_queue_compare (PQ, left, right) > 0)
j + +;
if (Priority_queue_compare (PQ, parent, J) > 0)
{
Priority_queue_swap (Pq->_nodes, I, J);
i = j;
}
Else
Break

}

}

static void Priority_queue_adjust_tail (Priorityqueue *pq)
{
int I, parent, child;

i = pq->_size-1;
pq->_size++;
while (i > 0)
{
Child = i;
Parent = (child-1)/2;

if (Priority_queue_compare (PQ, parent, Child) > 0)
{
Priority_queue_swap (Pq->_nodes, child, parent);
i = parent;
}
Else
Break

}
}


static int Priority_queue_compare (Priorityqueue *pq,
int POS1,
int Pos2)
{
int adjust =-1;
int r = pq->_nodes[pos1]->_key-pq->_nodes[pos2]->_key;
if (pq->_priority = = Priority_max)
R *= adjust;
return R;
}

static void Priority_queue_swap (KeyValue **nodes,
int POS1,
int Pos2)
{
KeyValue *temp = nodes[pos1];
NODES[POS1] = Nodes[pos2];
NODES[POS2] = temp;
}

/*
*file:main.c
*purpose:tesing Priority queue in C
*author:puresky
*date:2011/04/27
*/

#include <stdio.h>
#include <stdlib.h>
#include "Pq.h"

int main (int argc, char **argv)
{
int i;
Priorityqueue *PQ = priority_queue_new (Priority_max);


int A[]={1, 9, 7, 8, 5, 4, 3, 2, 1, 100, 50, 17};

for (i = 0; i < sizeof (a)/sizeof (int); ++i)
{
KeyValue *kv = Key_value_new (A[i], NULL);
Priority_queue_enqueue (PQ, KV);
}

Priority_queue_print (PQ);
Priority_queue_free (PQ, NULL);

System ("pause");
return 0;
}

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.