📄 qqd.c
字号:
/************************************************************************/
/* */
/* QQD.C - Implements a double-ended queuing mechanism for doubles. */
/* */
/* Public domain by Bob Stout */
/* */
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "qqd.h"
const VAR64_ QQD_NaN = {-1L}; /* NaN bit pattern (all 1's) */
/*
** QQDopen() - Queue initialization function.
**
** Parameters: 1 - Address of a queue of type struct QQ
** 2 - Number of entries
**
** Returns: Success_ or Error_
**
** Side effects: Allocated memory, zeros head and tail pointers,
** sets length, clears full flag.
*/
Boolean_T QQDopen(struct QQD **queue, size_t len)
{
if (NULL == (*queue = malloc(sizeof(struct QQD))))
return Error_;
if (NULL == ((*queue)->queue = calloc(len, sizeof(double))))
return Error_;
(*queue)->len = len;
(*queue)->head = (*queue)->tail = 0;
(*queue)->full = False_;
return Success_;
}
/*
** QQDclose() - Close a queue.
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: Nothing.
**
** Side effects: Deallocates memory.
*/
void QQDclose(struct QQD **queue)
{
FREE(*queue);
}
/*
** QQDenqueue() - FIFO enqueuing function.
**
** Parameters: 1 - Address of a queue of type struct QQD
** 2 - Double datum to enqueue
**
** Returns: Success_ or Error_
**
** Side effects: Adjusts head pointer.
*/
Boolean_T QQDenqueue(struct QQD *queue, double datum)
{
int diff;
if (queue->full)
return Error_;
diff = (int)queue->head - (int)queue->tail;
if (diff < 0)
diff += (int)queue->len;
if (diff >= (int)queue->len)
return Error_;
queue->queue[queue->head++] = datum;
if (queue->head >= queue->len)
queue->head = 0;
if (queue->head == queue->tail)
queue->full = True_;
return Success_;
}
/*
** QQDdequeue() - FIFO dequeuing function
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: Oldest datum in queue or QQD_EMPTY.
**
** Side effects: Adjusts tail pointer
*/
double QQDdequeue(struct QQD *queue)
{
double retval;
if ((queue->head == queue->tail) && !queue->full)
return QQD_EMPTY;
retval = queue->queue[queue->tail++];
if (queue->tail >= queue->len)
queue->tail = 0;
queue->full = False_;
return retval;
}
/*
** QQDpeekF() - FIFO peek function - CAUTION: returns the oldest data in the
** queue without removing it from the queue.
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: Oldest datum in queue or QQD_EMPTY.
**
** Side effects: None.
*/
double QQDpeekF(struct QQD *queue)
{
if ((queue->head == queue->tail) && !queue->full)
return QQD_EMPTY;
return queue->queue[queue->tail];
}
/*
** QQDpush() - LIFO enqueuing function.
**
** Parameters: 1 - Address of a queue of type struct QQD
** 2 - Double datum to enqueue
**
** Returns: Success_ or Error_
**
** Side effects: Adjusts head pointer.
**
** Notes: Wrapper for QQDenqueue().
*/
Boolean_T QQDpush(struct QQD *queue, double datum)
{
return QQDenqueue(queue, datum);
}
/*
** QQDpop() - LIFO dequeuing function
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: Newest datum in queue or QQD_EMPTY.
**
** Side effects: Adjusts head pointer
*/
double QQDpop(struct QQD *queue)
{
double retval;
if ((queue->head == queue->tail) && !queue->full)
return QQD_EMPTY;
queue->head -= 1;
if (queue->head < 0 || queue->head > queue->len)
queue->head = queue->len - 1;
retval = queue->queue[queue->head];
queue->full = False_;
return retval;
}
/*
** QQDpeekL() - LIFO peek function - CAUTION: returns the newest data in the
** queue without removing it from the queue.
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: Newest datum in queue or QQD_EMPTY.
**
** Side effects: None.
*/
double QQDpeekL(struct QQD *queue)
{
size_t tmp_head;
if ((queue->head == queue->tail) && !queue->full)
return QQD_EMPTY;
tmp_head = queue->head - 1;
if (tmp_head < 0 || tmp_head > queue->len)
tmp_head = queue->len - 1;
return queue->queue[tmp_head];
}
/*
** QQDisfull() - Function to determine is a queue is full.
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: True_ if queue is full, False_ if not full.
*/
Boolean_T QQDisfull(struct QQD *queue)
{
return queue->full;
}
/*
** QQDisempty() - Function to determine is a queue is empty.
**
** Parameters: 1 -Address of a queue of type struct QQD
**
** Returns: True_ if queue is empty, False_ if not empty.
*/
int QQDisempty(struct QQD *queue)
{
return ((queue->head == queue->tail) && !queue->full);
}
/*
** QQDflush() - FIFO queue flushing function.
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: N.A.
**
** Side effects: Adjusts head and tail pointers
*/
void QQDqflush(struct QQD *queue)
{
queue->head = queue->tail = 0;
queue->full = False_;
}
/*
** QQDnum_enqueued() - FIFO queue function to return the number of queue
** entries.
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: Number of data in the queue
**
** Side effects: Adjusts head and tail pointers
*/
size_t QQDnum_enqueued(struct QQD *queue)
{
int diff;
if (queue->full)
return queue->len;
diff = (int)queue->head - (int)queue->tail;
if (diff < 0)
diff += (int)queue->len;
if (diff >= (int)queue->len)
return queue->len;
else return (size_t)diff;
}
/*
** QQDdump() - Utility function to dump (print) the contents of a queue
**
** Parameters: 1 - Address of a queue of type struct QQD
**
** Returns: N.A.
**
** Side effects: None
*/
void QQDdump(struct QQD *queue)
{
size_t i, tailtmp, qlen;
if (QQDisempty(queue))
{
puts("QQDdump(): Queue is empty\n");
return;
}
else puts("QQDdump(): Dumping queue, tail first");
for (i = 0, qlen = queue->len, tailtmp = queue->tail; i < QQDnum_enqueued(queue); ++i)
{
printf("%2d: %f\n", i, queue->queue[tailtmp++]);
if (tailtmp >= qlen)
tailtmp = 0;
}
}
#ifdef TEST
main()
{
int i;
struct QQD *queue, *stack;
QQDopen(&queue, 10);
printf("QQDnum_enqueued() returned %d\n\n",
QQDnum_enqueued(queue));
for (i = 0; i < 11; ++i)
{
int n = 5 * (i + 1);
printf("QQDenqueue(%d) returned %d\n", n,
QQDenqueue(queue, (double)n));
}
printf("\nQQDnum_enqueued() returned %d\n\n",
QQDnum_enqueued(queue));
for (i = 0; i < 7; ++i)
{
printf("QQDpeekF() returned %f\n", QQDpeekF(queue));
printf("QQDdequeue() returned %f\n",
QQDdequeue(queue));
printf("QQDnum_enqueued() returned %d\n",
QQDnum_enqueued(queue));
}
for (i = 0; i < 2; ++i)
{
int n = 3 * (i + 1);
printf("QQDenqueue(%d) returned %d\n", n,
QQDenqueue(queue, (double)n));
}
printf("\nQQDnum_enqueued() returned %d\n\n",
QQDnum_enqueued(queue));
for (i = 0; i < 7; ++i)
{
printf("QQDpeekF() returned %f\n", QQDpeekF(queue));
printf("QQDdequeue() returned %f\n",
QQDdequeue(queue));
printf("QQDnum_enqueued() returned %d\n",
QQDnum_enqueued(queue));
}
QQDqflush(queue);
printf("QQDnum_enqueued() returned %d\n\n",
QQDnum_enqueued(queue));
for (i = 0; i < 11; ++i)
{
int n = 5 * (i + 1);
printf("QQDpush(%d) returned %d\n", n,
QQDpush(queue, (double)n));
}
printf("\nQQDnum_enqueued() returned %d\n\n",
QQDnum_enqueued(queue));
for (i = 0; i < 7; ++i)
{
printf("QQDpeekL() returned %f\n", QQDpeekL(queue));
printf("QQDpop() returned %f\n",
QQDpop(queue));
printf("QQDnum_enqueued() returned %d\n",
QQDnum_enqueued(queue));
}
for (i = 0; i < 2; ++i)
{
int n = 3 * (i + 1);
printf("QQDpush(%d) returned %d\n", n,
QQDpush(queue, (double)n));
}
printf("\nQQDnum_enqueued() returned %d\n\n",
QQDnum_enqueued(queue));
for (i = 0; i < 7; ++i)
{
printf("QQDpeekL() returned %f\n", QQDpeekL(queue));
printf("QQDpop() returned %f\n",
QQDpop(queue));
printf("QQDnum_enqueued() returned %d\n",
QQDnum_enqueued(queue));
}
QQDclose(&queue);
return 0;
}
#endif /* TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -