Как двигаться с помощью ->next в блочном списке?

Функция - поиск строчки по её индексу в блочном списке. Указываем индекс блока, индекс строчки. Результат - вывод необходимой строчки. Я не пойму как можно сделать нормальный переход от одного блока к другому, чтобы получить блок, индекс которого был указан пользователем.

const size_t blockSize = 9;

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_custom(blockList* l, record* r, int indexBlock, int indexCell) //добавляет запись в указанную позицию
    {
        if (!l || !r)
            return;

    block* userBlock = l->head;
    block* customBlock = l->head;
    auto temp = userBlock;
    for (size_t i = 0; i < indexBlock; i++)
    {
        for (size_t j = 0; j < indexCell; j++)
        {   
            temp[i].cells[j] = userBlock[i].next->cells[j];
        }
    }
    cout << temp[indexBlock].cells[indexCell].key;
    
    return;
}

Ответы (1 шт):

Автор решения: AR Hovsepyan

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

Сами аргументы функции выбраны нелогичные.

  • Если указатели не должны быть нулевыми, значит они указывают на конкретные объекты,а еще, по вашим намерениям, они не меняют свои значения. Тогда пропадает смысл передать объекты по указателям
  • .Вы определяете const size_t blockSize = 9, значит вы понимаете, что обычно для размера выбирается без знаковый тип size_t. Тогда зачем аргументы функции, переданные как номер позиции, имеют знаковый тип?

Давайте исправим и, с не большими догадками о ваших намерениях, напишем приблизительную реализацию вашей функции:

void blockList_add_custom(blockList& l, const record& r, 
   size_t indexBlock, const size_t indexCell) 
{  
    block* temp = l.head;
    if(temp) { 
        /*считаем блоки, не доходя до последнего
        если это последный блок, проверяем не
        превышало значение indexBlock фактическому
        количеству блоков? Если нет,  тогда добавляем
        в массив записей этого блока переданную в функцию
        запись, при условии, что indexCell < blockSize*/
        while (indexBlock && temp != l.tail) {
            temp = l.head->next;            
            --indexBlock;
        }
        if (indexBlock == 0 && indexCell < blockSize) {
            //только догадываюсь что вы хотите вывести на консоль
            //cout << temp->cells[indexCell].key; решайте сами
            temp->cells[indexCell] = r;            
        }
        else {
            std::cerr << "нет такого блока";            
        } 
        
    }    
}

Хоть и эта функция уже говорит о плохом подходе к выполнению задачи, но все же отражает те намерения, о которых вы спрашивали. И, надеюсь, изучив внимательно, вы поймете как можно сделать нормальный переход от одного блока к другому, чтобы получить блок, по позиции в списке

→ Ссылка