Browse Source

sliding_win

master
Charlie Root 1 day ago
parent
commit
6ddc69fec4
  1. 99
      lib/swm_min.c
  2. 41
      lib/swm_min.h

99
lib/swm_min.c

@ -0,0 +1,99 @@
/* sliding_window_min.c */
#include "sliding_window_min.h"
#include <stdlib.h>
#include <limits.h>
struct SlidingWindowMin {
int* data; /* кольцевой буфер значений */
int* deq; /* deque индексов (тоже кольцевой) */
int dq_head;
int dq_tail;
int deq_count;
int cur_pos;
int window_size;
};
SlidingWindowMin* swm_create(int window_size)
{
if (window_size <= 0) {
return NULL;
}
SlidingWindowMin* swm = (SlidingWindowMin*)malloc(sizeof(SlidingWindowMin));
if (!swm) {
return NULL;
}
swm->data = (int*)malloc((size_t)window_size * sizeof(int));
if (!swm->data) {
free(swm);
return NULL;
}
swm->deq = (int*)malloc((size_t)window_size * sizeof(int));
if (!swm->deq) {
free(swm->data);
free(swm);
return NULL;
}
swm->window_size = window_size;
swm->dq_head = 0;
swm->dq_tail = 0;
swm->deq_count = 0;
swm->cur_pos = 0;
return swm;
}
void swm_destroy(SlidingWindowMin* swm)
{
if (swm) {
free(swm->data);
free(swm->deq);
free(swm);
}
}
void swm_add(SlidingWindowMin* swm, int val)
{
if (!swm) return;
int idx = swm->cur_pos;
int w = swm->window_size;
/* записываем в кольцевой буфер */
swm->data[idx % w] = val;
/* 1. удаляем из начала deque индексы, которые уже вышли за окно */
while (swm->deq_count > 0 && swm->deq[swm->dq_head] <= idx - w) {
swm->dq_head = (swm->dq_head + 1) % w;
swm->deq_count--;
}
/* 2. удаляем из хвоста все элементы, которые хуже текущего */
while (swm->deq_count > 0) {
int last_idx = swm->deq[(swm->dq_tail - 1 + w) % w];
if (swm->data[last_idx % w] < val) {
break;
}
swm->dq_tail = (swm->dq_tail - 1 + w) % w;
swm->deq_count--;
}
/* 3. добавляем текущий индекс */
swm->deq[swm->dq_tail] = idx;
swm->dq_tail = (swm->dq_tail + 1) % w;
swm->deq_count++;
swm->cur_pos++;
}
int swm_get_min(const SlidingWindowMin* swm)
{
if (!swm || swm->deq_count == 0) {
return INT_MAX;
}
int min_idx = swm->deq[swm->dq_head];
return swm->data[min_idx % swm->window_size];
}

41
lib/swm_min.h

@ -0,0 +1,41 @@
/* sliding_window_min.h */
#ifndef SLIDING_WINDOW_MIN_H
#define SLIDING_WINDOW_MIN_H
#include <stddef.h> /* для size_t */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct SlidingWindowMin SlidingWindowMin;
/**
* Создаёт новую структуру скользящего минимума.
* @param window_size размер окна (должен быть > 0)
* @return указатель на структуру или NULL при ошибке выделения памяти
*/
SlidingWindowMin* swm_create(int window_size);
/**
* Уничтожает структуру и освобождает всю динамически выделенную память.
*/
void swm_destroy(SlidingWindowMin* swm);
/**
* Добавляет новое значение в окно.
* После вызова swm_get_min() сразу вернёт минимум последних min(window_size, добавленных) значений.
*/
void swm_add(SlidingWindowMin* swm, int val);
/**
* Возвращает текущий минимум в окне.
* Если окно пустое возвращает INT_MAX.
*/
int swm_get_min(const SlidingWindowMin* swm);
#ifdef __cplusplus
}
#endif
#endif /* SLIDING_WINDOW_MIN_H */
Loading…
Cancel
Save