Google Answers Logo
View Question
 
Q: Queue/Heap C Code Needed ( No Answer,   7 Comments )
Question  
Subject: Queue/Heap C Code Needed
Category: Computers > Algorithms
Asked by: sdsanchez-ga
List Price: $16.00
Posted: 02 Nov 2005 20:32 PST
Expires: 06 Nov 2005 14:06 PST
Question ID: 588264
I am looking for a complete C code that implements a prioritized queue
(Heap Method preferred). I am trying to implement several prioritized
buffers on an Atmel microcontrollers (Electrical Engineering, no much
software knowledge) using standard C code (no C++, classes or OOP).
Basically, I have a previously defined Structure such as follows:

typedef struct
{
	unsigned char prority;
	unsigned char packetType;
	unsigned int destinationAddress; 	
	unsigned int sourceAddress; 			
	char payload[26]; 			
} Packet;

I need to be able to have a FIFO Buffer / Priority Queue to hold 10
"Packet" structures and they need to be ordered based upon the
priority (zero being the highest). It needs to have the regular Queue
functions:

- AddItem [Enqueue] : Add item and orders it by priority, moving all
that are necessary to be moved, and also in a FIFO fashion.
- RemoveItem [Dequeue] : Removes the item with highest priority (or if
more than one has the same priority, the first one that came, regular
FIFO).
- isEmpty : check if buffer is empty.
- isFull : check if buffer is full.

and any other you think it is necessary. The functions will most
likely pass a BUFFER and the Element to be add [AddItem], or pass a
BUFFER and return the removed element [removeItem].

I have to stress out that since this is for a microcontroller, it must
not use any OOP, classes or advance techniques, pure and simple ANSI C
code. If you use special libraries please make sure to let me know,
because not all of them are available on my compiler (CodeVision AVR).

Thank you very much! Sorry for asking this like that, but I have never
taken a Data Structures Class and I am just trying to attempt a packet
manager on a AVR microcontroller.

Thanks again.
Answer  
There is no answer at this time.

Comments  
Subject: Re: Queue/Heap C Code Needed
From: doopdoop-ga on 03 Nov 2005 19:06 PST
 
/*priority queue, using a binary heap with static maximum size
This code is in the public domain, but I would be glad if you leave my name in:
Rene Wiermer, rwiermer@googlemail.com. Feedback is welcome.

The implemementation is based on Heapsort as described in
"Introduction to Algorithms" (Cormen, Leiserson, Rivest, 24. printing)
*/

/*needed for test only*/
#include <stdio.h>
/**/

#define MAX_SIZE 10

typedef struct
{
        unsigned char priority;
        unsigned char packetType;
        unsigned int destinationAddress;        
        unsigned int sourceAddress;                     
        char payload[26];                       
} Packet;

typedef struct {
	Packet* packets[MAX_SIZE];
	unsigned int size;
} PacketHeap;


void heap_init(PacketHeap* h) {
	h->size=0;
}

void heap_heapify(PacketHeap* h,int i) {
	int l,r,smallest;
	Packet* tmp;
	l=2*i; /*left child*/
	r=2*i+1; /*right child*/

	if ((l < h->size)&&(h->packets[l]->priority < h->packets[i]->priority))
		smallest=l;
	else 
		smallest=i;
	if ((r < h->size)&&(h->packets[r]->priority < h->packets[smallest]->priority))
		smallest=r;
	if (smallest!=i) {
		/*exchange to maintain heap property*/
		tmp=h->packets[smallest];
		h->packets[smallest]=h->packets[i];
		h->packets[i]=tmp;
		heap_heapify(h,smallest);
	}
}

void heap_addItem(PacketHeap* h,Packet* packet) {
	unsigned int i,parent;	
	h->size=h->size+1;
	i=h->size-1;
	parent=i/2;
	/*find the correct place to insert*/
	while ((i > 0)&&(h->packets[parent]->priority > packet->priority)) {
		h->packets[i]=h->packets[parent];
		i=parent;
		parent=i/2;
	}
	h->packets[i]=packet;
}

Packet* heap_extractMin(PacketHeap* h) {
	Packet* max;
	if (heap_isEmpty(h))
		return 0;
	max=h->packets[0];
	h->packets[0]=h->packets[h->size-1];
	h->size=h->size-1;
	heap_heapify(h,0);
	return max;
}

int heap_isEmpty(PacketHeap *h) {
	return h->size==0;
}

int heap_isFull(PacketHeap *h) {
	return h->size>=MAX_SIZE;
}

/*Test code*/
int main() {
	PacketHeap heap;
	unsigned char i;
	Packet p[10];
	p[0].priority=123;
	p[1].priority=23;
	p[2].priority=0;
	p[3].priority=22;
	p[4].priority=255;
	p[5].priority=1;
	p[6].priority=10;
	p[7].priority=3;
	p[8].priority=101;
	p[9].priority=102;

	heap_init(&heap);
	for (i=0;i<10;i++) {
		printf("Add %i\n",p[i].priority);
		heap_addItem(&heap,&(p[i]));
	}
	while (!heap_isEmpty(&heap)) {
		i=heap_extractMin(&heap)->priority;
		printf("%i\n",i);
	}
}
Subject: Re: Queue/Heap C Code Needed
From: doopdoop-ga on 03 Nov 2005 19:28 PST
 
So, the previous post is my attempt on it. A good excercise to brush
up old C knowledge.

Since you are using only a maximum of 10 elements, this solution with
a heap maybe overkill. There should be not much difference to a
reasonably implemented linear search.

But i have to think a bit, whether this algorithms acts like a FIFO
when there are equal priorities or not.
Subject: Re: Queue/Heap C Code Needed
From: doopdoop-ga on 04 Nov 2005 13:13 PST
 
Heapsort is not stable, which means that this priority queue does not
hold the FIFO condition for elements with same priority.
If you need this (e.g. if you want to guarantee, that a packet is
leaving in a reasonable time), you need to modify the algorithm (e.g.
add a secondary key, which holds information about the sequence of
adding) or use another one (linear search, for example).
Subject: Re: Queue/Heap C Code Needed
From: sdsanchez-ga on 04 Nov 2005 15:40 PST
 
Do you have code for the Linear Search you are telling me about? The
final use for this task will be a FIFO for basically only three type
of packages with priorities 1,2 and 3 respectively. Therefore the FIFO
quality should be met. I mentioned Heap because that is the only term
I found was associated with Priority Queues always (I have to say it
again, not very good at programming). What would you suggest? I really
need help on this! The reason what I am also worring about speed, it's
because this will run on a microcontroller with limited processing and
RAM.

Thank you again for understanding the problem :)
Subject: Re: Queue/Heap C Code Needed
From: doopdoop-ga on 05 Nov 2005 17:00 PST
 
/*priority queue using a sorted ring buffer with static maximum size.
FIFO property is maintained.
This code is in the public domain, but I would be glad if you leave my name in:
Rene Wiermer, rwiermer@googlemail.com. Feedback is welcome.

*/

/*needed for test only*/
#include <stdio.h>
/**/

#define MAX_SIZE 10

typedef struct
{
        unsigned char priority;
        unsigned char packetType;
        unsigned int destinationAddress;        
        unsigned int sourceAddress;                     
        char payload[26];                       
} Packet;

typedef struct {
        Packet* packets[MAX_SIZE];
        unsigned int size;
	unsigned int currentmin; /*current minimum element*/
} PacketQueue;


void queue_init(PacketQueue* q) {
	q->size=0;
	q->currentmin=0;
}

int queue_nextElem(PacketQueue* q,int i) {
	if (i==queue_lastElem(q))
		return q->currentmin;
	return (i+1)%MAX_SIZE;
}

int queue_prevElem(PacketQueue* q,int i) {
	if (i==q->currentmin)
		return queue_lastElem(q);
	return (i+MAX_SIZE-1)%MAX_SIZE;
}

int queue_lastElem(PacketQueue* q) {
	return (q->currentmin+q->size-1)%MAX_SIZE;
}


void queue_addItem(PacketQueue* q,Packet* p) {
/*WARNING: no check performed, if buffer is full*/
	if (q->size==0) {
		q->currentmin=0;
		q->packets[q->currentmin]=p;
		q->size=1;
	}
	else {
		unsigned int stop,maxelem,i;
		unsigned char key;
		key=p->priority;
		i=queue_lastElem(q);
		q->size=q->size+1;
		stop=queue_lastElem(q);
		/*Insert into the sorted ring buffer, starting from the back to
maintain FIFO property*/
		while (i!=stop&&(q->packets[i]->priority>key)) {
			q->packets[queue_nextElem(q,i)]=q->packets[i];
			i=queue_prevElem(q,i);		
		}
		q->packets[queue_nextElem(q,i)]=p;
	}
	
}

Packet* queue_extractMin(PacketQueue* q) {
/*WARNING: no check performed, if buffer is empty*/
	Packet* min;
	min=q->packets[q->currentmin];
	q->currentmin=queue_nextElem(q,q->currentmin);
	q->size=q->size-1;
	return min;
}

int queue_isFull(PacketQueue* q) {
	return	q->size>=MAX_SIZE;
}

int queue_isEmpty(PacketQueue* q) {
	return q->size==0;
}
int main() {
        PacketQueue heap;
        int i,j;
        Packet p[10];
        p[0].priority=123;
        p[1].priority=124;
        p[2].priority=0;
        p[3].priority=222;
        p[4].priority=245;
        p[5].priority=1;
        p[6].priority=101;
        p[7].priority=3;
        p[8].priority=101;
        p[9].priority=102;

        queue_init(&heap);
	for (j=0;j<1000000;j++) {
        for (i=0;i<10;i++) {
                queue_addItem(&heap,&(p[i]));
        }

	
        while (!queue_isEmpty(&heap)) {
                i=queue_extractMin(&heap)->priority;
        }
	}
}
Subject: Re: Queue/Heap C Code Needed
From: doopdoop-ga on 05 Nov 2005 17:16 PST
 
This code is not exactly linear search (searching the minimum in a
list at extraction) but instead does the hard work when adding an item
(maintaing a sorted list), but the theoretical complexity of the
algorithm should be the same. It is implemented as a circular buffer
with static size.
To give a rough estimate of running time: On my 1Ghz Athlon, with GCC
3.4 and all optimization, 10.000.000 round of completely filling and
removing from the queue:

Heap (no FIFO)   Sorted List (FIFO)
1.547s           4.625s

I am to lazy to make the heap implementation FIFO-proof. It should'nt
be that hard, though (e.g. write a comparison routine for packets,
which also includes a secondary key, which reflects the order of
inclusion).  Some registered expert could to it for the money. Also
the code needs thorough testing in all different situations.
If you or an expert is  willing to donate some money for my work, I
would suggest "Books for Africa" (http://www.booksforafrica.org/).
Subject: Re: Queue/Heap C Code Needed
From: sdsanchez-ga on 06 Nov 2005 14:05 PST
 
Dear Rene Wiermer,

I extremely appreciate your help and time. I did not know that you
were not answering the question as a researcher. I am going to close
this discussion and donate http://www.booksforafrica.org the money
that I intended for this question as it has been answered :)

Thank you once again!

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy