Сводка списка C++

искусственный интеллект

содержание

вводить

Общие функции

Пример использования функции

Создайте список и присвойте значение

Пройди и найди

удалить элемент

очистить список

вставить элемент в список

Используйте assign для добавления новых элементов в контейнер

обмен двумя списками

Используйте изменение размера, чтобы изменить размер списка.

Используйте функцию splice для управления списками

удалить повторяющиеся элементы

объединить список

Сортировать

Разница между списком и вектором


вводить

список представляет собой структуру линейного двусвязного списка, его данные состоят из нескольких узлов, каждый узел включает в себяинформационный блок(то есть фактически сохраненные данные),указатель впередиЗадний фланкер. Ему не нужно выделять определенный объем памяти, и его можно масштабировать произвольно, поскольку он хранится в несмежном пространстве памяти, а упорядоченные элементы связаны указателями. Из-за своей структуры производительность случайного поиска по списку очень низкая, потому что он не находит напрямую адрес элемента, как вектор, а должен искать последовательно один за другим с самого начала, так что чем позже целевой элемент , тем короче время его поиска. Время поиска пропорционально позиции целевого элемента. Хотя случайный поиск недостаточно быстр, он может быстро выполнять операции вставки и удаления в любом узле. Поскольку каждый узел списка сохраняет свою позицию в связанном списке, вставка или удаление элемента влияет только на три элемента, в отличие от вектора, который влияет на адреса хранения всех элементов после точки операции.Одним из пунктов является то, что вектор несравним.

https://images2015.cnblogs.com/blog/849009/201602/849009-20160203142350538-1403083351.png

list специальность:

(1) Не используйте непрерывное пространство памяти, чтобы можно было выполнять динамические операции по желанию;
(2) Его можно быстро вставить или удалить в любом месте внутри, и, конечно же, можно выполнять нажатие и выталкивание с обоих концов.
(3) Внутренний произвольный доступ невозможен, то есть оператор [ ] и vector.at() не поддерживаются;
(4) Занимает больше памяти, чем verctor.

Общие функции

Конструктор списка и деструктор
list<Elem> c создает пустой список без элементов в нем
list<Elem> c1(c2) Сделать еще одну копию списка того же типа (копируются все элементы)
list<Elem> c(n) Используйте конструктор элемента по умолчанию для создания списка размера n
list<Elem> c(n,elem) Создайте список размера n, каждое значение элемента равно elem
list<Elem> c(beg, end) Создайте список с интервалом [beg, end) в качестве начального значения элемента
c.~list<Elem>()         Уничтожить все элементы и освободить память
Неизменяемые операции над списками
size() Возвращает размер контейнера
empty()    Определить, пуст ли контейнер, эквивалентно size()==0, но может быть быстрее
max_size() Возвращает самый большой элемент, который может хранить контейнер
reserve() Если мощности недостаточно, увеличьте ее.
c1 == c2 Определить, равен ли c1 c2
c1 != c2 Определить, не равен ли c1 c2
c1 < c2 Определить, меньше ли c1, чем c2
c1 > c2 Определить, больше ли c1, чем c2
c1 <= c2   Определить, меньше ли c1, чем c2, или равно ему.
c1 >= c2   Определить, является ли c1 больше или равным c2
Операция присваивания списку
c1 = c2      Присвоить все элементы c2 элементу c1
assign(n, elem) Скопируйте n elem, скопируйте в c
assign(beg, end)      Присвойте элементам в диапазоне [beg;end) значение c
c1.swap(c2) Поменяйте местами элементы c1 и c2
swap(c1,c2) Как и выше, это глобальная функция
доступ к элементам
front         Возвращает первый элемент, не проверяя, существует ли этот элемент или нет.
back Возвращает последний элемент, не проверяя, существует ли этот элемент или нет.
Функции, связанные с итератором
begin() Возвращает двунаправленный итератор, указывающий на первый элемент
end() Возвращает двунаправленный итератор, указывающий на следующую позицию последнего элемента
rbegin()    Возвращает обратный итератор, указывающий на первый элемент обратной итерации.
end() Возвращает обратный итератор, указывающий на следующую позицию последнего элемента обратной итерации.
список функций вставки и удаления операций  
insert(pos, elem) Вставьте копию элемента в позицию, на которую указывает позиция итератора, и верните позицию нового элемента.
insert(pos,n,elem) Вставьте n копий элемента в позицию pos, без возвращаемого значения
insert(pos,beg,end) Вставьте копию всех элементов интервала [beg,end) в позицию pos без возвращаемого значения.
push_back(elem) Добавьте копию elem в хвост
pop_back() удалить последний элемент, без возвращаемого значения
push_front()     Добавьте копию elem в голову
pop_front()       удалить первый элемент, но не возвращать
remove(val) удалить все элементы, значение которых равно val
remove_if() Удалить из связанного списка все элементы, удовлетворяющие условию
erase(pos) Удалить элемент в позиции pos и вернуть позицию следующего элемента
erase(beg, end) Удалить все элементы в интервале [beg, end) и вернуть позицию следующего элемента
resize(num) Измените количество элементов на num (если size() станет больше, все дополнительные новые элементы должны быть завершены с помощью конструктора по умолчанию)
resize(num,elem)    Измените количество элементов на num (если size() становится больше, все новые элементы являются копиями elem)
clear()       Удалить все элементы, очистить контейнер
Примечания: вставка и удаление элементов сделает недействительными итераторы каждого элемента после «точки действия».Если произойдет перераспределение памяти, все итераторы в контейнере будут недействительными.
Специальные операции изменчивости для списков
unique() Если есть несколько соседних элементов с одинаковым значением, повторяющиеся элементы удаляются, оставляя
unique(op)        Если есть несколько смежных элементов, все делают результат op() истинным, затем удаляют повторяющийся элемент, оставляя только один.
c1.splice(pos, c2) Переместите все элементы в c2 в c1, прежде чем позиция итератора
c1.splice(pos, c2, c2pos)      Переместите элемент, на который указывает c2pos в c2, в позицию, на которую указывает pos в c1 (c1, c2 могут быть одинаковыми)
c1.splice(поз., c2, c2beg, c2end) Перед интервалом [C2BEG, C2END) передается на все элементы в POS C1 в C2 (C1, C2 может быть одинаковым)
sort() Сортировать все элементы с оператором
sort(op) Отсортируйте все элементы, используя op() в качестве ориентира
c1.merge(c2)   Предполагая, что оба контейнера c1 и c2 содержат отсортированные (одинакового порядка) элементы, перенесите все элементы c2 в c1 и убедитесь, что объединенный список по-прежнему отсортирован.
c1.merge(c2, op) Предполагая, что контейнеры c1 и c2 содержат упорядоченные (с одинаковой сортировкой) элементы в соответствии с принципом op(), перенесите все элементы из c2 в c1 и убедитесь, что объединенный список по-прежнему упорядочен в соответствии с принципом op(). 
reverse() Перевернуть все элементы

Пример использования функции

Создайте список и присвойте значение

#include <iostream>

#include <list>

using namespace std;

int main() {

//Первый, через конструктор

    int myints[] = { 44,77,22,11,12 };

    list<int> mylist1(myints, myints + 5);

list mylist2(2, 100);// 2 элемента со значением 100

//Второй, используйте push_back или push_front

    for (int i = 1; i <= 5; ++i) mylist1.push_back(i);

    mylist2.push_front(20);

    mylist2.push_front(30);

//Третий, используйте assign

    list<int> first;

    list<int> second;

First.assign(7, 10);// Добавляем 7 значений от 10 до 10

second.assign(first.begin(), first.end()); // копируем первое во второе

    int myints1[] = { 32, 8, 4 };

first.assign(myints1, myints1 + 3);// добавить содержимое массива myints в первый

    return 0;

}

Пройди и найди

#include <iostream>

#include <list>

using namespace std;

int main() {

//Первый, через конструктор

    int myints[] = { 44,77,22,11,12};

    list<int> myList(myints, myints + 5);

    cout << "mylist contains:";

//переход

    for (list<int>::iterator it = myList.begin(); it != myList.end(); ++it)

    {

        cout << " " << *it;

    }

    cout << "\n";

//найти

    for (list<int>::iterator it = myList.begin(); it != myList.end(); ++it)

    {

        if (*it == 22)

        {

cout

        }

    }

    cout << "\n";

// добавить

    for (int i = 1; i <= 5; ++i)

        myList.push_back(i);

// обход в обратном порядке

    for (list<int>::reverse_iterator rit = myList.rbegin(); rit != myList.rend(); ++rit)

          cout << ' ' << *rit;

    return 0;

}

удалить элемент

 

// создаем экземпляр и назначаем

#include <iostream>

#include <list>

using namespace std;

bool single_digit(const int& value) { return (value < 20); }

struct is_odd {

//оператор перегрузки()

    bool operator() (const int& value) { return (value % 2) == 1; }

};

int main() {

//Первый, через конструктор

    int myints[] = { 44,77,22,11,12 };

    list<int> myList(myints, myints + 5);

    cout << "mylist contains:";

//переход

    for (list<int>::iterator it = myList.begin(); it != myList.end(); ++it)

    {

        cout << " " << *it;

    }

    cout << "\n";

//удаляем и удаляем_если удаляем элементы

    myList.remove(22);

    myList.remove_if(single_digit);

    myList.remove_if(is_odd());

//переход

    for (list<int>::iterator it = myList.begin(); it != myList.end(); it++)

    {

        cout << " " << *it;

    }

    cout << "\n";

// добавить

    myList.push_back(22);

    for (list<int>::iterator it = myList.begin(); it != myList.end(); it++) {

        cout << " " << *it;

    }

    cout << "\n";

// Проходим и удаляем, это неправильный способ написания.

    /*for (auto it = myList.begin(); it != myList.end(); it++)

    {

        if (*it == 11) {

             myList.erase(it);

        }

    }*/

//Первый способ записи

    for (auto it = myList.begin(); it != myList.end();)

    {

        if (*it == 22) {

            myList.erase(it++);

        }

        else

        {

            cout << " " << *it;

            it++;

        }

    }

//Второй способ записи

    for (auto it = myList.begin(); it != myList.end();)

    {

        if (*it == 22) {

            it=myList.erase(it);

        }

        else

        {

            cout << " " << *it;

            it++;

        }

    }

    return 0;

}

очистить список

#include <iostream>

#include <list>

using namespace std;

int main() {

    list<int> mylist;

    list<int>::iterator it;

    mylist.push_back(10);

    mylist.push_back(20);

    mylist.push_back(30);

    cout << "mylist contains:";

    for (it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    mylist.clear();

    mylist.push_back(2121);

    mylist.push_back(3232);

    cout << "mylist contains:";

    for (it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    return 0;

}

вставить элемент в список

#include <iostream>

#include <list>

#include <vector>

using namespace std;

int main() {

    list<int> mylist;

    list<int>::iterator it;

// инициализируем

    for (int i = 1; i <= 5; ++i) mylist.push_back(i); // 1 2 3 4 5

    it = mylist.begin();

++it; // итератор it теперь указывает на число 2 ^

// Вставляем элемент 10 в позицию, на которую указывает i0t

    mylist.insert(it, 10);  // 1 10 2 3 4 5

// "it" по-прежнему указывает на число 2 ^

// Вставляем два элемента 20 в позицию, на которую он указывает

    mylist.insert(it, 2, 20); // 1 10 20 20 2 3 4 5

--it; // теперь он указывает на число 20 ^

vector myvector(2, 30); //Создаем векторный контейнер и инициализируем его, чтобы он содержал 2 элемента со значением 30

// Вставляем значение векторного контейнера в список

    mylist.insert(it, myvector.begin(), myvector.end());

    // 1 10 20 30 30 20 2 3 4 5

// он по-прежнему указывает на число 20 // ^

    cout << "mylist contains:";

    for (it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    return 0;

}

Используйте assign для добавления новых элементов в контейнер

#include <iostream>

#include <list>

using namespace std;

int main() {

    list<int> first;

    list<int> second;

first.assign(7, 10);//Добавить 7 элементов со значением 10 к первому

second.assign(first.begin(), first.end()); // копируем первое во второе

    int myints[] = { 22, 33, 44 };

first.assign(myints, myints + 3);// добавить содержимое массива myints в первый

    cout << "Size of first: " << int(first.size()) << '\n';

    cout << "Size of second: " << int(second.size()) << '\n';

    return 0;

}

обмен двумя списками

// swap lists

#include <iostream>

#include <list>

using namespace std;

int main() {

list first(3, 100); // три элемента со значением 100

Список Second (5, 200); // Пять значений 200 элементов

    first.swap(second);

    cout << "first contains:";

    for (list<int>::iterator it = first.begin(); it != first.end(); it++)

        cout << ' ' << *it;

    cout << '\n';

    cout << "second contains:";

    for (list<int>::iterator it = second.begin(); it != second.end(); it++)

        cout << ' ' << *it;

    cout << '\n';

    return 0;

}

Используйте изменение размера, чтобы изменить размер списка.

// resizing list

#include <iostream>

#include <list>

using namespace std;

int main() {

    list<int> mylist;

// инициализируем

for (int i = 1; i

mylist.resize(5);//длина списка становится равной 5, а элементы: 0 1 2 3 4

mylist.resize(8, 100);//Длина списка становится равной 8, часть, превышающая 5, становится равной 100, а элементы: 0 1 2 3 4 100 100 100

mylist.resize(12);//Длина списка становится 12, части, превышающей 5, присваивается значение по умолчанию 0, а элементы: 0 1 2 3 4 100 100 100 0 0 0 0

    cout << "mylist contains:";

    for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    return 0;

}

Используйте функцию splice для управления списками

// splicing lists

#include <iostream>

#include <list>

using namespace std;

int main() {

    list<int> mylist1, mylist2;

    list<int>::iterator it;

// инициализируем

    for (int i = 1; i <= 10; ++i)

        mylist1.push_back(i);      // mylist1: 1 2 3 4 5 6 7 8 9

    for (int i = 1; i <= 3; ++i)

        mylist2.push_back(i * 10);   // mylist2: 10 20 30

    it = mylist1.begin();

++it; // указывает на число 2

    mylist1.splice(it, mylist2); // mylist1: 1 10 20 30 2 3 4

                                  // mylist2 (empty)

// "it" по-прежнему указывает на номер 2

    mylist2.splice(mylist2.begin(), mylist1, it);

    // mylist1: 1 10 20 30 3 4

    // mylist2: 2

// "это" в настоящее время недействительно

    it = mylist1.begin();

advance(it, 3); // "it" указывает на число 30

    mylist1.splice(mylist1.begin(), mylist1, it, mylist1.end());

    // mylist1: 30 3 4 1 10 20

    cout << "mylist1 contains:";

    for (it = mylist1.begin(); it != mylist1.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    cout << "mylist2 contains:";

    for (it = mylist2.begin(); it != mylist2.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    return 0;

}

 

удалить повторяющиеся элементы

// list::unique

#include <iostream>

#include <cmath>

#include <list>

using namespace std;

// a binary predicate implemented as a function:

bool same_integral_part(double first, double second) { return (int(first) == int(second)); }

 

// a binary predicate implemented as a class:

struct is_near {

    bool operator() (double first, double second) { return (fabs(first - second) < 5.0); }

};

 

int main() {

    double mydoubles[] = { 12.15, 2.72, 73.0, 12.77, 3.14,

                       12.77, 73.35, 72.25, 15.3, 72.25 };

    list<double> mylist(mydoubles, mydoubles + 10);

    cout << "mylist contains:";

    for (list<double>::iterator it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    mylist.unique();

    cout << "mylist contains:";

    for (list<double>::iterator it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    mylist.sort();             //  2.72,  3.14, 12.15, 12.77, 12.77,

                             // 15.3,  72.25, 72.25, 73.0,  73.35

    mylist.unique();           //  2.72,  3.14, 12.15, 12.77

                             // 15.3,  72.25, 73.0,  73.35

    cout << "mylist contains:";

    for (list<double>::iterator it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    mylist.unique(same_integral_part);  //  2.72,  3.14, 12.15                                 // 15.3,  72.25, 73.0

    cout << "mylist contains:";

    for (list<double>::iterator it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    mylist.unique(is_near());           //  2.72, 12.15, 72.25

    cout << "mylist contains:";

    for (list<double>::iterator it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    return 0;

}

объединить список

#include <iostream>

#include <list>

using namespace std;

bool mycomparison(double first, double second) { return ((first) < (second)); }

int main() {

    list<double> first, second;

 

    first.push_back(3.1);

    first.push_back(2.2);

    first.push_back(2.9);

 

    second.push_back(3.7);

    second.push_back(7.1);

    second.push_back(1.4);

 

    first.sort();

    second.sort();

 

    first.merge(second);

    cout << "first contains:";

    for (list<double>::iterator it = first.begin(); it != first.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

// (секунда теперь пуста)

    second.push_back(1.1);

    second.push_back(2.1);

    second.push_back(2.5);

   

    first.merge(second, mycomparison);

    cout << "first contains:";

    for (list<double>::iterator it = first.begin(); it != first.end(); it++)

        cout << ' ' << *it;

    cout << '\n';

    return 0;

}

Сортировать

// list::sort

#include <iostream>

#include <list>

#include <string>

#include <cctype>

using namespace std;

// comparison, not case sensitive.

bool compare_nocase(const string& first, const string& second) {

    unsigned int i = 0;

    while ((i < first.length()) && (i < second.length())) {

// Преобразование заглавных букв в строчные

        if (tolower(first[i]) < tolower(second[i])) return true;

        else if (tolower(first[i]) > tolower(second[i])) return false;

        ++i;

    }

    return (first.length() < second.length());

}

 

int main() {

    list<string> mylist;

    list<string>::iterator it;

    mylist.push_back("one");

    mylist.push_back("two");

    mylist.push_back("Three");

    mylist.push_back("Four");

    mylist.push_back("Five");

    mylist.push_back("Six");

    mylist.sort();

    cout << "mylist contains:";

    for (it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    mylist.sort(compare_nocase);

    cout << "mylist contains:";

    for (it = mylist.begin(); it != mylist.end(); ++it)

        cout << ' ' << *it;

    cout << '\n';

    return 0;

}

Разница между списком и вектором

  1. vector структура данных
    Подобно массиву, вектор имеет непрерывное пространство памяти с одним и тем же начальным адресом.
    Следовательно, произвольный доступ может выполняться эффективно, а временная сложность составляет O(1);
    Однако, поскольку пространство памяти является непрерывным, при вставке и удалении операций это приведет к копированию блока памяти, а временная сложность равна o (n).
    Кроме того, когда места в памяти в массиве недостаточно, будет запрошено новое место в памяти и будет выполнено копирование памяти.

Вектор имеет непрерывное пространство памяти и может очень хорошо поддерживать произвольный доступ.
Итак, vector::iterator поддерживает "+", "+=", "

  1. list структура данных
    Список реализуется двусвязным списком, поэтому пространство памяти является прерывистым.
    Доступ к данным возможен только через указатели, поэтому произвольный доступ к списку очень неэффективен, а временная сложность равна o(n);
    Однако благодаря характеристикам связанных списков вставка и удаление могут выполняться эффективно.

Объем памяти списка может быть прерывистым, произвольный доступ не поддерживается,
Поэтому list::iterator не поддерживает "+", "+=", "

И vector::iterator, и list::iterator перегружают оператор "++".

Короче говоря, если вам нужен эффективный произвольный доступ и вас не волнует эффективность вставки и удаления, используйте вектор;
Если вам нужно много вставок и удалений и вам не нужен произвольный доступ, вы должны использовать список.

Ссылаться на:

1,woo woo woo.cn blog on.com/I am 0816/afraid/65…