⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deque.c

📁 C语言库函数的源代码,是C语言学习参考的好文档。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* +++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 + -