Шаг 63.
Библиотека Qt.
Списки QList<T>, QLinkedList<T>

    На этом шаге рассмотрим списки QList<T>, QLinkedList<T>.

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

    Списки реализует класс QList<T>. В общем виде данный класс представляет собой массив указателей на элементы (рис. 1).


Рис.1. Структура списка

    Специфические операции для списков приведены в табл. 1.

Таблица 1. Некоторые методы контейнера QList<T>
Метод
Описание
move()
Перемещает элемент с одной позиции на другую
removeFirst()
Удаляет первый элемент списка
removeLast()
Удаляет последний элемент списка
swap()
Меняет местами два элемента на указанных позициях
takeAt()
Возвращает элемент на указанной позиции и удаляет его
takeFirst()
Удаляет первый элемент и возвращает его
takeLast()
Удаляет последний элемент и возвращает его
toSet()
Возвращает контейнер QSet<T> с данными, содержащимися в объекте QList<T>
toStdList()
Возвращает стандартный список STL std::list<T> с элементами, содержащимися в объекте QList<T>
toVector()
Возвращает объект вектора 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>.




Предыдущий шаг Содержание Следующий шаг