На этом шаге рассмотрим списки 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>.