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

📄 deque.c

📁 C语言库函数的源代码,是C语言学习参考的好文档。
💻 C
📖 第 1 页 / 共 2 页
字号:

      return d;
}



/***
 *
 ** function    : Q_Next
 *
 ** purpose     : Move to the next element in the queue without popping
 *
 ** parameters  : queue pointer.
 *
 ** returns     : pointer to data element of new element or NULL if end
 *                of the queue.
 *
 ** comments    : This uses the cursor for the current position. Q_Next
 *                only moves in the direction from the head of the queue
 *                to the tail.
 ***/

void *Q_Next(queue *q)
{
      if (q->cursor->next == NULL)
            return NULL;

      q->cursor = (node *)q->cursor->next;

      return  q->cursor->data ;
}



/***
 *
 ** function    : Q_Previous
 *
 ** purpose     : Opposite of Q_Next. Move to next element closer to the
 *                head of the queue.
 *
 ** parameters  : pointer to queue
 *
 ** returns     : pointer to data of new element else NULL if queue empty
 *
 ** comments    : Makes cursor move towards the head of the queue.
 *
 ***/

void *Q_Previous(queue *q)
{
      if (q->cursor->prev == NULL)
            return NULL;

      q->cursor = (node *)q->cursor->prev;

      return q->cursor->data;
}



/***
 *
 ** function    : Q_DelCur
 *
 ** purpose     : Delete the current queue element as pointed to by
 *                the cursor.
 *
 ** parameters  : queue pointer
 *
 ** returns     : pointer to data element.
 *
 ** comments    : WARNING! It is the responsibility of the caller to
 *                free any memory. Queue cannot distinguish between
 *                pointers to literals and malloced memory.
 *
 ***/

void *Q_DelCur(queue *q)
{
      void        *d;
      datanode    *n, *p;

      if (q->cursor == NULL)
            return NULL;

      if (q->cursor == q->head)
            return Q_PopHead(q);

      if (q->cursor == q->tail)
            return Q_PopTail(q);

      n = q->cursor->next;
      p = q->cursor->prev;
      d = q->cursor->data;

      free(q->cursor);
      if (p != NULL)
            q->cursor = p;
      else  q->cursor = n;
      q->size--;

      q->sorted = False_;

      return d;
}



/***
 *
 ** function    : Q_Get
 *
 ** purpose     : get the pointer to the data at the cursor location
 *
 ** parameters  : queue pointer
 *
 ** returns     : data element pointer
 *
 ** comments    :
 *
 ***/

void *Q_Get(queue *q)
{
      if (q->cursor == NULL)
            return NULL;
      return q->cursor->data;
}



/***
 *
 ** function    : Q_Put
 *
 ** purpose     : replace pointer to data with new pointer to data.
 *
 ** parameters  : queue pointer, data pointer
 *
 ** returns     : boolean- True_ if successful, False_ if cursor at NULL
 *
 ** comments    :
 *
 ***/

int Q_Put(queue *q, void *data)
{
      if (q->cursor == NULL)
            return False_;

      q->cursor->data = data;
      return True_;
}


/***
 *
 ** function    : Q_Find
 *
 ** purpose     : Linear search of queue for match with key in *data
 *
 ** parameters  : queue pointer q, data pointer with data containing key
 *                comparison function here called Comp.
 *
 ** returns     : True_ if found , False_ if not in queue.
 *
 ** comments    : Useful for small queues that are constantly changing
 *                and would otherwise need constant sorting with the
 *                Q_Seek function.
 *                For description of Comp see Q_Sort.
 *                Queue cursor left on position found item else at end.
 *
 ***/

int Q_Find(queue *q, void *data,
               int (*Comp)(const void *, const void *))
{
      void *d;
      d = Q_First(q);
      do
      {
            if (Comp(d, data) == 0)
                  return True_;
            d = Q_Next(q);
      } while (!Q_End(q));

      if (Comp(d, data) == 0)
            return True_;

      return False_;
}

/*========  Sorted Queue and Index functions   ========= */


static void QuickSort(void *list[], int low, int high,
                      int (*Comp)(const void *, const void *))
{
      int     flag = 1, i, j;
      void    *key, *temp;

      if (low < high)
      {
            i = low;
            j = high + 1;

            key = list[ low ];

            while (flag)
            {
                  i++;
                  while (Comp(list[i], key) < 0)
                        i++;

                  j--;
                  while (Comp(list[j], key) > 0)
                        j--;

                  if (i < j)
                  {
                        temp = list[i];
                        list[i] = list[j];
                        list[j] = temp;
                  }
                  else  flag = 0;
            }

            temp = list[low];
            list[low] = list[j];
            list[j] = temp;

            QuickSort(list, low, j-1, Comp);
            QuickSort(list, j+1, high, Comp);
      }
}


/***
 *
 ** function    : Q_Sort
 *
 ** purpose     : sort the queue and allow index style access.
 *
 ** parameters  : queue pointer, comparison function compatible with
 *                with 'qsort'.
 *
 ** returns     : True_ if sort succeeded. False_ if error occurred.
 *
 ** comments    : Comp function supplied by caller must return
 *                  -1 if data1  < data2
 *                   0 if data1 == data2
 *                  +1 if data1  > data2
 *
 *                    for Comp(data1, data2)
 *
 *                If queue is already sorted it frees the memory of the
 *                old index and starts again.
 *
 ***/

int Q_Sort(queue *q, int (*Comp)(const void *, const void *))
{
      int         i;
      void        *d;
      datanode    *dn;

      /* if already sorted free memory for tag array */

      if (q->sorted)
      {
            free(index);
            free(posn_index);
            q->sorted = False_;
      }

      /* Now allocate memory of array, array of pointers */

      index = malloc(q->size * sizeof(q->cursor->data));
      if (index == NULL)
            return False_;

      posn_index = malloc(q->size * sizeof(q->cursor));
      if (posn_index == NULL)
      {
            free(index);
            return False_;
      }

      /* Walk queue putting pointers into array */

      d = Q_First(q);
      for (i=0; i < q->size; i++)
      {
            index[i] = d;
            posn_index[i] = q->cursor;
            d = Q_Next(q);
      }

      /* Now sort the index */

      QuickSort(index, 0, q->size - 1, Comp);

      /* Rearrange the actual queue into correct order */

      dn = q->head;
      i = 0;
      while (dn != NULL)
      {
            dn->data = index[i++];
            dn = dn->next;
      }

      /* Re-position to original element */

      if (d != NULL)
            Q_Find(q, d, Comp);
      else  Q_First(q);

      q->sorted = True_;

      return True_;
}


/***
 *
 ** function    : Q_BSearch
 *
 ** purpose     : binary search of queue index for node containing key
 *
 ** parameters  : queue pointer 'q', data pointer of key 'key',
 *                  Comp comparison function.
 *
 ** returns     : integer index into array of node pointers,
 *                or -1 if not found.
 *
 ** comments    : see Q_Sort for description of 'Comp' function.
 *
 ***/

static int Q_BSearch( queue *q, void *key,
                      int (*Comp)(const void *, const void*))
{
      int low, mid, hi, val;

      low = 0;
      hi = q->size - 1;

      while (low <= hi)
      {
            mid = (low + hi) / 2;
            val = Comp(key, index[ mid ]);

            if (val < 0)
                  hi = mid - 1;

            else if (val > 0)
                  low = mid + 1;

            else /* Success */
                  return mid;
      }

      /* Not Found */

      return -1;
}


/***
 *
 ** function    : Q_Seek
 *
 ** purpose     : use index to locate data according to key in 'data'
 *
 ** parameters  : queue pointer 'q', data pointer 'data', Comp comparison
 *                function.
 *
 ** returns     : pointer to data or NULL if could not find it or could
 *                not sort queue.
 *
 ** comments    : see Q_Sort for description of 'Comp' function.
 *
 ***/

void *Q_Seek(queue *q, void *data, int (*Comp)(const void *, const void *))
{
      int idx;

      if (!q->sorted)
      {
            if (!Q_Sort(q, Comp))
                  return NULL;
      }

      idx = Q_BSearch(q, data, Comp);

      if (idx < 0)
            return NULL;

      q->cursor = posn_index[idx];

      return index[idx];
}



/***
 *
 ** function    : Q_Insert
 *
 ** purpose     : Insert an element into an indexed queue
 *
 ** parameters  : queue pointer 'q', data pointer 'data', Comp comparison
 *                function.
 *
 ** returns     : pointer to data or NULL if could not find it or could
 *                not sort queue.
 *
 ** comments    : see Q_Sort for description of 'Comp' function.
 *                WARNING! This code can be very slow since each new
 *                element means a new Q_Sort.  Should only be used for
 *                the insertion of the odd element ,not the piecemeal
 *                building of an entire queue.
 ***/

int Q_Insert(queue *q, void *data, int (*Comp)(const void *, const void *))
{
      Q_PushHead(q, data);

      if (!Q_Sort(q, Comp))
            return False_;

      return True_;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -