На этом шаге рассмотрим списки QList<T>, QLinkedList<T>.
Cписок — это структура данных, представляющая собой упорядоченный набор связанных друг с другом элементов. Преимущество списков перед векторами и очередями состоит в том, что вставка и удаление элементов в любой позиции происходит эффективнее, т. к. для выполнения этих операций изменяется только минимальное количество указателей, исключение составляет только вставка элемента в центр списка. Но есть и недостаток — списки плохо приспособлены для поиска определенного элемента по индексу, и для этой цели лучше использовать вектор.
Списки реализует класс QList<T>. В общем виде данный класс представляет собой массив указателей на элементы (рис. 1).

Рис.1. Структура списка
Специфические операции для списков приведены в табл. 1.
| Перемещает элемент с одной позиции на другую | |
| Удаляет первый элемент списка | |
| Удаляет последний элемент списка | |
| Меняет местами два элемента на указанных позициях | |
| Возвращает элемент на указанной позиции и удаляет его | |
| Удаляет первый элемент и возвращает его | |
| Удаляет последний элемент и возвращает его | |
| Возвращает контейнер QSet<T> с данными, содержащимися в объекте QList<T> | |
| Возвращает стандартный список STL std::list<T> с элементами, содержащимися в объекте QList<T> | |
| Возвращает объект вектора QVector<T> с элементами, содержащимися в объекте QList<T> |
Если вы не собираетесь изменять значения элементов, то, из соображений эффективности, не рекомендуется использовать оператор индексации []. Вместо этого лучше будет воспользоваться методом at(), т. к. этот метод возвращает константную ссылку на элемент.
Одна из самых распространенных операций — обход списка для последовательного получения значений каждого элемента списка. Например:
QList<int> list;
for(int i=1;i<=5;i++)list << i*i;
QList<int>::iterator it = list.begin();
while (it != list.end())
{
qDebug() << "Элемент:" << *it;
++it;
}На консоли будет отображено следующее (рис. 2):

Рис.2. Результат выполнения программы
Файлы приложения можно взять здесь.
В классе QList<T> не достаточно эффективно работает вставка элементов, поэтому если вы работаете с большими списками и/или вам часто требуется вставлять элементы, то эффективнее будет использовать двусвязные списки QLinkedList<T>. Хотя этот контейнер расходует больше памяти, чем QList<T>, как это видно из его структуры (рис. 3), зато операции вставки и удаления сводятся к переопределению четырех указателей, независимо от позиции удаляемого или вставляемого элемента.
В этом классе не определены операции для индексного доступа "[]" и at().

Рис.3. Структура двусвязного списка
На следующем шаге рассмотрим стек QStack<T>.