Реализация очереди на C

от автора

Привет, сегодня я покажу как сделать очередь на C. Ко мне пришла идея сделать зацикленную работу в очереди. То есть добавляются данные от конца в начало и если указатель дошел до начала, то начинать добавлять с конца. Статья маленькая, но может кому будет полезно. Кстати, я решил посмотреть как у других сделано и решил, что мой пример тоже не помешает.

Сама очередь состоит из такой структуры.

struct queue {         uint8_t *data;  // указатель на данные         int low;        // указатель на нижнюю границу         int high;       // указатель на верхнюю границу         int count;      // количество элементов в очереди         int max;        // максимальное количество элементов };

Инициализируем очередь.

struct queue *init (size_t size) {         struct queue * q = calloc (1, sizeof (struct queue));         q->data = calloc (size, sizeof (uint8_t));         q->low = q->high = size - 1;         q->max = size;          return q; }

Добавляем в очередь.

void queue_add (struct queue *q, uint8_t a) {          if (q->count == q->max) {                 fprintf (stderr, "not enough queue size\n");                 return;         }          q->data[q->low--] = a;         q->count++;          if (q->low < 0) {                 q->low = q->max - 1;         }  }

Удаляем из очереди.

uint8_t queue_get (struct queue *q) {         uint8_t a = q->data[q->high--];         q->count--;          if (q->high < 0) {                 q->high = q->max - 1;         }          return a; } 

Алгоритм до того простой, что из него можно сделать очередь с приоритетом, подправив структуру и функции. Приведу сразу весь код очереди с приоритетом и проверкой результата.

Не знаю как мне приходят такие идеи и я не помню как другие реализуют очередь с приоритетом, но моя реализация будет такая.

Оставляю здесь код для вас и для себя.

#include <stdio.h> #include <stdlib.h> #include <stdint.h>  struct queue { uint8_t **data; int *low; int *high; int *count; int *max; int max_prio; };  struct queue *init (size_t size, int size_prio) { struct queue * q = calloc (1, sizeof (struct queue)); q->max_prio = size_prio;  q->data = calloc (size_prio, sizeof (void *)); q->low = calloc (size, sizeof (int)); q->high = calloc (size, sizeof (int)); q->max = calloc (size, sizeof (int)); q->count = calloc (size, sizeof (int));  for (int i = 0; i < size_prio; i++) { q->data[i] = calloc (size, sizeof (uint8_t)); q->low[i] = q->high[i] = size - 1; q->max[i] = size; }  return q; }  void queue_add (struct queue *q, uint8_t a, int prio) {  if (q->count[prio] == q->max[prio]) { fprintf (stderr, "not enough queue size\n"); return; }  q->data[prio][q->low[prio]--] = a; q->count[prio]++;  if (q->low[prio] < 0) { q->low[prio] = q->max[prio] - 1; }  }  uint8_t queue_get (struct queue *q) { uint8_t a = 0; int found = 0; for (int i = 0; i < q->max_prio; i++) { if (q->count[i] > 0) { found = 1; a = q->data[i][q->high[i]--]; q->count[i]--;  if (q->high[i] < 0) { q->high[i] = q->max[i] - 1; }  return a; } }  if (found == 0) { printf ("queue is empty\n"); }  return a; }  int main (int argc, char **argv) { struct queue *q = init (10, 4);  queue_add (q, 2, 3); queue_add (q, 10, 1); queue_add (q, 15, 1); queue_add (q, 20, 0);  for (int i = 0; i < 4; i++) { printf ("%d: %d\n", i, queue_get (q)); } }


ссылка на оригинал статьи https://habr.com/ru/post/668580/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *