Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
db40734d
Commit
db40734d
authored
Apr 18, 2007
by
Christian Würdig
Browse files
initial checkin of priority queue implementation
[r12714]
parent
d3b4ae2f
Changes
2
Hide whitespace changes
Inline
Side-by-side
ir/adt/pqueue.c
0 → 100644
View file @
db40734d
#include
"array.h"
#include
"pqueue.h"
/**
* Implements a heap.
*
* Implementation note: It might seem strange that we start indexing at 0
* but use 2*i and 2*i+1 to find the left and right sucessor of an index.
* The trick is that for index 0 the left successor is 0 again, and the
* right successor is 1 in this scheme. For the right successor 1 everything
* works like usual. We simply took care in the algorithms that they still
* work with the left child of 0 being 0 again. This was possible without
* any extra ifs or arithmetic.
* Thus we can save the wastage of 1 array position you can see in other
* implementations or the ugly (i+1)*2 - 1 and (i+1)*2 for calculating the
* left and right child. (At the expense that stuff easily breaks when you make
* changes and don't think that the left child of 0 is 0 :-/)
* @author matze
*
*/
typedef
struct
_pqueue_el_t
{
void
*
data
;
int
key
;
}
pqueue_el_t
;
struct
_pqueue_t
{
pqueue_el_t
*
elems
;
};
/**
* Enforces the heap characteristics if the queue
* starting from element at position @p pos.
*/
static
void
pqueue_heapify
(
pqueue
*
q
,
int
pos
)
{
int
len
=
ARR_LEN
(
q
->
elems
);
while
(
pos
*
2
<
len
)
{
pqueue_el_t
tmp
;
int
exchange
=
pos
;
if
(
q
->
elems
[
exchange
].
key
<
q
->
elems
[
pos
*
2
].
key
)
{
exchange
=
pos
*
2
;
}
if
((
pos
*
2
+
1
)
<
len
&&
q
->
elems
[
exchange
].
key
<
q
->
elems
[
pos
*
2
+
1
].
key
)
{
exchange
=
pos
*
2
+
1
;
}
if
(
exchange
==
pos
)
break
;
tmp
=
q
->
elems
[
pos
];
q
->
elems
[
pos
]
=
q
->
elems
[
exchange
];
q
->
elems
[
exchange
]
=
tmp
;
pos
=
exchange
;
}
}
/**
* Sifts up a newly inserted element at position @p pos.
*/
static
void
pqueue_sift_up
(
pqueue
*
q
,
int
pos
)
{
while
(
q
->
elems
[
pos
].
key
>
q
->
elems
[
pos
/
2
].
key
)
{
pqueue_el_t
tmp
;
tmp
=
q
->
elems
[
pos
];
q
->
elems
[
pos
]
=
q
->
elems
[
pos
/
2
];
q
->
elems
[
pos
/
2
]
=
tmp
;
pos
/=
2
;
}
}
/**
* Creates a new priority queue.
* @return A priority queue of initial length 0.
*/
pqueue
*
new_pqueue
()
{
pqueue
*
res
=
xmalloc
(
sizeof
(
*
res
));
res
->
elems
=
NEW_ARR_F
(
pqueue_el_t
,
0
);
return
res
;
}
/**
* Frees all memory allocated by the priority queue.
* @param q The priority queue to destroy.
*/
void
del_pqueue
(
pqueue
*
q
)
{
DEL_ARR_F
(
q
->
elems
);
free
(
q
);
}
/**
* Inserts a new element into a priority queue.
* @param q The priority queue the element should be inserted to.
* @param data The actual data which should be stored in the queue.
* @param key The priority for the data.
*/
void
pqueue_put
(
pqueue
*
q
,
void
*
data
,
int
key
)
{
pqueue_el_t
el
;
el
.
data
=
data
;
el
.
key
=
key
;
ARR_APP1
(
pqueue_el_t
,
q
->
elems
,
el
);
pqueue_sift_up
(
q
,
ARR_LEN
(
q
->
elems
));
}
/**
* Returns and removes the first element, ie. that one with the highest priority, from the queue.
* @param q The priority queue.
* @return The first element of the queue. Asserts if queue is empty.
*/
void
*
pqueue_get
(
pqueue
*
q
)
{
switch
(
ARR_LEN
(
q
->
elems
))
{
case
0
:
assert
(
0
&&
"Attempt to retrieve element from empty priority queue."
);
return
NULL
;
break
;
case
1
:
ARR_SHRINKLEN
(
q
->
elems
,
0
);
return
q
->
elems
[
0
].
data
;
break
;
default:
{
void
*
data
=
q
->
elems
[
0
].
data
;
int
len
=
ARR_LEN
(
q
->
elems
)
-
1
;
q
->
elems
[
0
]
=
q
->
elems
[
len
];
ARR_SHRINKLEN
(
q
->
elems
,
len
);
pqueue_heapify
(
q
,
0
);
return
data
;
}
}
}
/**
* Get the length of the priority queue.
* @param q The priority queue.
* @return The length of the queue.
*/
int
pqueue_length
(
pqueue
*
q
)
{
return
ARR_LEN
(
q
->
elems
);
}
/**
* Returns true if queue is empty.
* @param q The priority queue.
* @return 1 if the queue is empty, 0 otherwise.
*/
int
pqueue_empty
(
pqueue
*
q
)
{
return
ARR_LEN
(
q
->
elems
)
==
0
;
}
ir/adt/pqueue.h
0 → 100644
View file @
db40734d
/**
* @file pqueue.h
* @date 18.04.2007
* @author Christian Wuerdig
* @brief Implementation of a priority queue. This is the ported version of the
* original Java implementation by Matthias Braun.
* @version $Id$
*/
#ifndef _PQUEUE_H_
#define _PQUEUE_H_
typedef
struct
_pqueue_t
pqueue
;
/**
* Creates a new priority queue.
* @return A priority queue of initial length 0.
*/
pqueue
*
new_pqueue
();
/**
* Frees all memory allocated by the priority queue.
* @param q The priority queue to destroy.
*/
void
del_pqueue
(
pqueue
*
q
);
/**
* Inserts a new element into a priority queue.
* @param q The priority queue the element should be inserted to.
* @param data The actual data which should be stored in the queue.
* @param key The priority for the data.
*/
void
pqueue_put
(
pqueue
*
q
,
void
*
data
,
int
key
);
/**
* Returns and removes the first element, ie. that one with the highest priority, from the queue.
* @param q The priority queue.
* @return The first element of the queue. Asserts if queue is empty.
*/
void
*
pqueue_get
(
pqueue
*
q
);
/**
* Get the length of the priority queue.
* @param q The priority queue.
* @return The length of the queue.
*/
int
pqueue_length
(
pqueue
*
q
);
/**
* Returns true if queue is empty.
* @param q The priority queue.
* @return 1 if the queue is empty, 0 otherwise.
*/
int
pqueue_empty
(
pqueue
*
q
);
#endif
/* _PQUEUE_H_ */
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment