📄 deque.c
字号:
/* +++Date last modified: 05-Jul-1997 */
/****************************************************************
*
* File : DEQUE.c
*
* Author: Peter Yard [1993.01.02] -- 02 Jan 1993
*
* Disclaimer: This code is released to the public domain.
*
* Description:
* Generic double ended queue (Deque pronounced DEK) for handling
* any data types, with sorting.
*
* By use of various functions in this module the caller
* can create stacks, queues, lists, doubly linked lists,
* sorted lists, indexed lists. All lists are dynamic.
*
* It is the responsibility of the caller to malloc and free
* memory for insertion into the queue. A pointer to the object
* is used so that not only can any data be used but various kinds
* of data can be pushed on the same queue if one so wished e.g.
* various length string literals mixed with pointers to structures
* or integers etc.
*
* Enhancements:
* A future improvement would be the option of multiple "cursors"
* so that multiple locations could occur in the one queue to allow
* placemarkers and additional flexibility. Perhaps even use queue
* itself to have a list of cursors.
*
* Usage:
*
* /x init queue x/
* queue q;
* Q_Init(&q);
*
* To create a stack :
*
* Q_PushHead(&q, &mydata1); /x push x/
* Q_PushHead(&q, &mydata2);
* .....
* data_ptr = Q_PopHead(&q); /x pop x/
* .....
* data_ptr = Q_First(&q); /x top of stack x/
*
* To create a FIFO:
*
* Q_PushHead(&q, &mydata1);
* .....
* data_ptr = Q_PopTail(&q);
*
* To create a double list:
*
* data_ptr = Q_First(&q);
* ....
* data_ptr = Q_Next(&q);
* data_ptr = Q_Last(&q);
* if (Q_Empty(&q)) ....
* .....
* data_ptr = Q_Previous(&q);
*
* To create a sorted list:
*
* Q_PushHead(&q, &mydata1); /x push x/
* Q_PushHead(&q, &mydata2);
* .....
* if (!Q_Sort(&q, MyFunction))
* .. error ..
*
* /x fill in key field of mydata1.
* * NB: Q_Find does linear search
* x/
*
* if (Q_Find(&q, &mydata1, MyFunction))
* {
* /x found it, queue cursor now at correct record x/
* /x can retrieve with x/
* data_ptr = Q_Get(&q);
*
* /x alter data , write back with x/
* Q_Put(&q, data_ptr);
* }
*
* /x Search with binary search x/
* if (Q_Seek(&q, &mydata, MyFunction))
* /x etc x/
*
*
****************************************************************/
#include <stdlib.h>
#include "deque.h"
static void QuickSort(void *list[], int low, int high,
int (*Comp)(const void *, const void *));
static int Q_BSearch(queue *q, void *key,
int (*Comp)(const void *, const void *));
/* The index: a pointer to pointers */
static void **index;
static datanode **posn_index;
/***
*
** function : Q_Init
*
** purpose : Initialise queue object and pointers.
*
** parameters : 'queue' pointer.
*
** returns : True_ if init successful else False_
*
** comments :
***/
int Q_Init(queue *q)
{
q->head = q->tail = NULL;
q->cursor = q->head;
q->size = 0;
q->sorted = False_;
return True_;
}
/***
*
** function : Q_Start
*
** purpose : tests if cursor is at head of queue
*
** parameters : 'queue' pointer.
*
** returns : boolean - True_ is at head else False_
*
** comments :
*
***/
int Q_Start(queue *q)
{
return (q->cursor == q->head);
}
/***
*
** function : Q_End
*
** purpose : boolean test if cursor at tail of queue
*
** parameters : 'queue' pointer to test.
*
** returns : True_ or False_
*
** comments :
*
***/
int Q_End(queue *q)
{
return (q->cursor == q->tail);
}
/***
*
** function : Q_Empty
*
** purpose : test if queue has nothing in it.
*
** parameters : 'queue' pointer
*
** returns : True_ if empty queue, else False_
*
** comments :
*
***/
int Q_Empty(queue *q)
{
return (q->size == 0);
}
/***
*
** function : Q_Size
*
** purpose : return the number of elements in the queue
*
** parameters : queue pointer
*
** returns : number of elements
*
** comments :
*
***/
int Q_Size(queue *q)
{
return q->size;
}
/***
*
** function : Q_First
*
** purpose : position queue cursor to first element (head) of queue.
*
** parameters : 'queue' pointer
*
** returns : pointer to data at head. If queue is empty returns NULL
*
** comments :
*
***/
void *Q_First(queue *q)
{
if (Q_Empty(q))
return NULL;
q->cursor = q->head;
return q->cursor->data;
}
/***
*
** function : Q_Last
*
** purpose : locate cursor at tail of queue.
*
** parameters : 'queue' pointer
*
** returns : pointer to data at tail , if queue empty returns NULL
*
** comments :
*
***/
void *Q_Last(queue *q)
{
if (Q_Empty(q))
return NULL;
q->cursor = q->tail;
return q->cursor->data;
}
/***
*
** function : Q_PushHead
*
** purpose : put a data pointer at the head of the queue
*
** parameters : 'queue' pointer, void pointer to the data.
*
** returns : True_ if success else False_ if unable to push data.
*
** comments :
*
***/
int Q_PushHead(queue *q, void *d)
{
node *n;
datanode *p;
q->head->prev = malloc(sizeof(datanode));
if (q->head->prev == NULL)
return False_;
n = q->head;
p = q->head->prev;
q->head = (node*)p;
q->head->prev = NULL;
if (q->size == 0)
{
q->head->next = NULL;
q->tail = q->head;
}
else q->head->next = (datanode*)n;
q->head->data = d;
q->size++;
q->cursor = q->head;
q->sorted = False_;
return True_;
}
/***
*
** function : Q_PushTail
*
** purpose : put a data element pointer at the tail of the queue
*
** parameters : queue pointer, pointer to the data
*
** returns : True_ if data pushed, False_ if data not inserted.
*
** comments :
*
***/
int Q_PushTail(queue *q, void *d)
{
node *p;
datanode *n;
q->tail->next = malloc(sizeof(datanode));
if (q->tail->next == NULL)
return False_;
p = q->tail;
n = q->tail->next;
q->tail = (node *)n;
if (q->size == 0)
{
q->tail->prev = NULL;
q->head = q->tail;
}
else q->tail->prev = (datanode *)p;
q->tail->next = NULL;
q->tail->data = d;
q->cursor = q->tail;
q->size++;
q->sorted = False_;
return True_;
}
/***
*
** function : Q_PopHead
*
** purpose : remove and return the top element at the head of the
* queue.
*
** parameters : queue pointer
*
** returns : pointer to data element or NULL if queue is empty.
*
** comments :
*
***/
void *Q_PopHead(queue *q)
{
datanode *n;
void *d;
if (Q_Empty(q))
return NULL;
d = q->head->data;
n = q->head->next;
free(q->head);
q->size--;
if (q->size == 0)
q->head = q->tail = q->cursor = NULL;
else
{
q->head = (node *)n;
q->head->prev = NULL;
q->cursor = q->head;
}
q->sorted = False_;
return d;
}
/***
*
** function : Q_PopTail
*
** purpose : remove element from tail of queue and return data.
*
** parameters : queue pointer
*
** returns : pointer to data element that was at tail. NULL if queue
* empty.
*
** comments :
*
***/
void *Q_PopTail(queue *q)
{
datanode *p;
void *d;
if (Q_Empty(q))
return NULL;
d = q->tail->data;
p = q->tail->prev;
free(q->tail);
q->size--;
if (q->size == 0)
q->head = q->tail = q->cursor = NULL;
else
{
q->tail = (node *)p;
q->tail->next = NULL;
q->cursor = q->tail;
}
q->sorted = False_;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -