📄 deque.c
字号:
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_; 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 + -