Блочный список C++ Правильный алгоритм вставки
Программа использует блоки для хранение массива данных.Но теперь уже надо сделать функцию, которая бы вставляла строчку в указанное место, как с add_begin, только пользователь вводит индекс записи. Например: 12. Т.е теперь не в head->cells[0], а на 12 позицию. Блоки у нас по 5, значит создаём переменную с нашим index_block = index(вводимый юзером) / blockSize = 12 / 5 = 2. -> нам нужен второй блок [0, 1, ->2, ...] И, уже найдя этот второй блок, ищём нужную ячейку: 12%5 = 2. По итогу, нам нужно положить его в index_block->cells[2]. Я правильно понимаю или можно как-нибудь попроще это сделать?
Структуры данных:
struct record //запись с данными
{
float key; //ключ
vector<int> intData; //должен быть массивом
vector<char> charData; // должен быть массивом
float floatData; //инфа
};
struct block //блок
{
size_t cnt; //кол-во записей в блоке
record cells[blockSize]; //ячейки блока
block* prev = nullptr; //предыдущий элемент
block* next = nullptr; //следующий элемент
};
struct blockList //список блоков
{
block* head = nullptr; //указатель на голову списка
block* tail = nullptr; //указатель на хвост списка
};
Функция добавления в начало:
void blockList_add_begin(blockList* l, record* r) //добавляет запись в начало списка
{
if (!l || !r)
return;
//Если список пуст (указатель на голову == nullptr)
if (!l->head) {
//Создаем новый блок c этой записью и задаем head
l->head = new block{ 1, *r };
//выходим
return;
}
//Если сюда попали, значит список не пуст
//Если блок в начале (head) может вместить данные
if (l->head->cnt < blockSize)
{
//сдвигаем блоки на 1, освобождая 0 место
for (size_t i = l->head->cnt; i > 0; i--)
{
l->head->cells[i] = l->head->cells[i - 1];
}
//на освободившееся записываем данные
l->head->cells[0] = *r;
//увеличиваем счетчик записей
l->head->cnt++;
//выходим
return;
}
else if (l->head->next->cnt < blockSize)
{
for (int i = l->head->next->cnt; i > 0; i--)
{
l->head->next->cells[i] = l->head->next->cells[i - 1]; //сдвигаем содержимое след. блока на 1 вправо
}
l->head->next->cells[0] = l->head->cells[blockSize - 1]; // помещаем в нулевую позицию последний элемент текущего блока
l->head->next->cnt++; //увеличиваем счетчик следующего блока
for (int j = l->head->next->cnt; j > 0; j--)
{
l->head->cells[j] = l->head->cells[j - 1]; //сдвигаем содержимое текущего блока на 1 вправо
}
l->head->cells[0] = *r;
return;
}
else
{
//Если сюда попали, значит список не пуст и нет мест в head
//создаем новый блок с записью
block* p = new block{ 1, *r };
//связываем блоки
p->next = l->head;
l->head = p;
return;
}
}