STL list

std::list 的特点

链表的结构包括:数据域,前驱指针,后继指针。list类的STL实现允许在开头、末尾、中间插入元素,需要的时间固定。

要是用std::stl类,需要包含头文件<list>:

#include <list>

基本的list操作

实例化std::list对象

#include <list>
#include <vector>
#include <iostream>
using namespace std;

template <typename T>
void DisplayContents (const T& container)
{
	for (list<int>::const_iterator element = container.begin();//声明一个指向list元素的迭代器
        element != container.end();
        ++ element )
       cout << *element << ' ';

   cout << endl;
}
int main ()
{
   //using namespace std;

   // instantiate an empty list
   list <int> listIntegers;

   // instantiate a list with 10 integers
   list<int> listWith10Integers(10);

   // instantiate a list with 4 integers, each initialized to 99
   list<int> listWith4IntegerEach99 (4, 99);

   // create an exact copy of an existing list
   list<int> listCopyAnother(listWith4IntegerEach99);

   // a vector with 10 integers, each 2017
   vector<int> vecIntegers(10, 2017);

   // instantiate a list using values from another container
   list<int> listContainsCopyOfAnother(vecIntegers.begin(),
                                       vecIntegers.end());
    DisplayContents(listWith4IntegerEach99);
   return 0;
}

在list开头或末尾插入元素

#include <list>
#include <iostream>
using namespace std;
// for non-C++11 compliant compilers
template <typename T>
void DisplayContents (const T& Input)
{
   for (typename T::const_iterator iElement = Input.begin ()
       ; iElement != Input.end ()
       ; ++ iElement )
       cout << *iElement << ' ';

   cout << endl;
}
/*
支持C++11的编译器可以用这个
template <typename T>
void DisplayContents (const T& container)
{
	for (auto element = container.cbegin();
        element != container.cend();
        ++ element )
       cout << *element << ' ';

   cout << endl;
}
*/
int main ()
{
    std::list <int> linkInts;
   linkInts.push_back (-101);
   linkInts.push_back (42);
   linkInts.push_front (10);
   linkInts.push_front (2011);
   linkInts.push_back (-1);
   linkInts.push_back (9999);

   DisplayContents(linkInts);

   return 0;
}
运行结果

我的编译器,不支持C++11,不能使用列表初始化的方法来个对象初值。

在list中插入元素

#include <list>
#include <iostream>
using namespace std;

template <typename T>
void DisplayContents (const T& container)
{
	for (typename T :: const_iterator element = container.begin();//这种方式一定要用const_iterator类型吗?
         element != container.end();
         ++ element )
       cout << *element << ' ';

   cout << endl;
}

int main ()
{
   list <int> linkInts1;

   // Inserting elements at the beginning...
   linkInts1.insert (linkInts1.begin (), 2);
   linkInts1.insert (linkInts1.begin (), 1);

   // Inserting an element at the end...
   linkInts1.insert (linkInts1.end (), 3);

   cout << "The contents of list 1 after inserting elements:" << endl;
   DisplayContents (linkInts1);

   list <int> linkInts2;

   // Inserting 4 elements of the same value 0...
   linkInts2.insert (linkInts2.begin (), 4, 0);

   cout << "The contents of list 2 after inserting '";
   cout << linkInts2.size () << "' elements of a value:" << endl;
   DisplayContents (linkInts2);

   list <int> linkInts3;

   // Inserting elements from another list at the beginning...
   linkInts3.insert (linkInts3.begin (),
                    linkInts1.begin (), linkInts1.end ());

   cout << "The contents of list 3 after inserting the contents of ";
   cout << "list 1 at the beginning:" << endl;
   DisplayContents (linkInts3);

   // Inserting elements from another list at the end...
   linkInts3.insert (linkInts3.end (),
                  linkInts2.begin (), linkInts2.end ());

   cout << "The contents of list 3 after inserting ";
   cout << "the contents of list 2 at the end:" << endl;
   DisplayContents (linkInts3);

   return 0;
}
运行结果

删除list中的元素

#include <iostream>
using namespace std;

template <typename T>
void DisplayContents(const T& container)
{
   for(typename T:: const_iterator element = container.begin();
       element != container.end();
       ++ element )
     cout << *element << ' ';

   cout << endl;
}

int main()
{
	std::list <int> linkInts;
	linkInts.push_back(4);
    linkInts.push_back(3);
	linkInts.push_back(5);
	linkInts.push_back(-1);
	linkInts.push_back(2017);


   // Store an iterator obtained in using insert()
   //查找函数返回的也是一个迭代器,该迭代器指向新插入的元素
   list<int>::iterator iValue2 = linkInts.insert(linkInts.begin(), 2);//声明一个指向list元素的迭代器

   cout << "Initial contents of the list:" << endl;
   DisplayContents(linkInts);

   cout << "After erasing element '"<< *iValue2 << "':" << endl;
   linkInts.erase(iValue2);//此时迭代器指向的是list头部的元素“2”
   DisplayContents(linkInts);

   linkInts.erase(linkInts.begin(), linkInts.end());//可以删除两个迭代器之间的所有元素
   cout << "Number of elements after erasing range: ";
   cout << linkInts.size() << endl;//求元素的大小

   linkInts.clear();

   return 0;
}
运行结果

对list中的元素进行反转和排序

使用list::reverse()反转元素的排列顺序

#include <list>
#include <iostream>
using namespace std;

template <typename T>
void DisplayContents(const T& container)
{
	for (typename T::const_iterator element = container.begin();
         element != container.end();
         ++ element )
     cout << *element << ' ';

   cout << endl;
}

int main()
{
   std::list <int> linkInts;
   linkInts.push_back(0);
   linkInts.push_back(1);
   linkInts.push_back(2);
   linkInts.push_back(3);
   linkInts.push_back(4);
   linkInts.push_back(5);


   cout << "Initial contents of the list:" << endl;
   DisplayContents(linkInts);

   linkInts.reverse();

   cout << "Contents of the list after using reverse():" << endl;
   DisplayContents(linkInts);

   return 0;
}
运行结果

reverse()只是反转list中元素的排列顺序。它是一个没有参数的简单函数,确保指向元素的迭代器在反转后仍有效——如果程序员保存了该迭代器。

对元素进行排序

#include <list>
#include <iostream>
using namespace std;

bool SortPredicate_Descending (const int& lsh, const int& rsh) //二元谓词函数
{
   // define criteria for list::sort: return true for desired order
   return (lsh > rsh);
}

template <typename T>
void DisplayContents (const T& container)
{
   for (list<int>::const_iterator element = container.begin();
        element != container.end();
        ++ element )
      cout << *element << ' ';

   cout << endl;
}

int main ()
{
   list <int> linkInts;
   linkInts.push_back(0);
   linkInts.push_back(-1);
   linkInts.push_back(2011);
   linkInts.push_back(444);
   linkInts.push_back(-5);
   cout << "Initial contents of the list are - " << endl;
   DisplayContents (linkInts);

   linkInts.sort ();

   cout << "Order after sort():" << endl;
   DisplayContents (linkInts);

   linkInts.sort (SortPredicate_Descending);
   cout << "Order after sort() with a predicate:" << endl;
   DisplayContents (linkInts);

   return 0;
}
运行结果

list默认的排序是升序的,可用二元谓语动词来设置排序的规则。

对包含对象的list进行排序以及删除其中的元素

#include <list>
#include <string>
#include <iostream>
using namespace std;
//这是一个循环输出的函数
template <typename T>
void displayAsContents (const T& container)
{
   for (typename T::const_iterator element = container.begin();
         element != container.end();
         ++ element )
     cout << *element << endl;

   cout << endl;
}
//定义了一个结构体(也属于类类型)
struct ContactItem
{
   string name;
   string phone;
   string displayAs;
   //结构体的构造函数
   ContactItem (const string& conName, const string & conNum)
   {
      name = conName;
      phone = conNum;
      displayAs = (name + ": " + phone);
   }

   // used by list::remove() given contact list item
   bool operator == (const ContactItem& itemToCompare) const
   {
      return (itemToCompare.name == this->name);
   }

   // used by list::sort() without parameters
   bool operator < (const ContactItem& itemToCompare) const
   {
      return (this->name < itemToCompare.name);
   }

   // Used in displayAsContents via cout
   operator const char*() const
   {
     return displayAs.c_str();
   }
};

bool SortOnphoneNumber (const ContactItem& item1,
                           const ContactItem& item2)
{
   return (item1.phone < item2.phone);
}

int main ()
{
   list <ContactItem> contacts;
   contacts.push_back(ContactItem("Jack Welsch", "+1 7889879879"));
   contacts.push_back(ContactItem("Bill Gates", "+1 97 789787998"));
   contacts.push_back(ContactItem("Angi Merkel", "+49 234565466"));
   contacts.push_back(ContactItem("Vlad Putin", "+7 66454564797"));
   contacts.push_back(ContactItem("Ben Affleck", "+1 745641314"));
   contacts.push_back(ContactItem("Dan Craig", "+44 123641976"));

   cout << "List in initial order: " << endl;
   displayAsContents(contacts);

   contacts.sort();
   cout << "Sorting in alphabetical order via operator<:" << endl;
   displayAsContents(contacts);

   contacts.sort(SortOnphoneNumber);
   cout << "Sorting in order of phone numbers via predicate:" << endl;
   displayAsContents(contacts);

   cout << "After erasing Putin from the list: " << endl;
   contacts.remove(ContactItem("Vlad Putin", ""));//这里能够用得上结构体重载的“==”吗?
   displayAsContents(contacts);

   return 0;
}
运行结果

remove()和sort()都是有对应的谓词函数的,如果容器中装的是类的对象,则需要在相应的类中重载“==”和“<”号。

### C++ STL List 使用与实现 #### 定义与基本特性 `std::list` 是双向链表容器,允许高效的插入和删除操作。不同于 `vector` 或者 `deque` 这样的连续内存存储结构,`list` 的元素分布在不同的位置上,通过指针相互链接[^1]。 ```cpp #include &lt;iostream&gt; #include &lt;list&gt; int main() { std::list&lt;int&gt; myList; // 插入元素到列表中 myList.push_back(10); myList.push_front(20); // 输出列表中的第一个和最后一个元素 std::cout &lt;&lt; &quot;Front element: &quot; &lt;&lt; myList.front() &lt;&lt; &quot;\n&quot;; std::cout &lt;&lt; &quot;Back element: &quot; &lt;&lt; myList.back() &lt;&lt; &quot;\n&quot;; return 0; } ``` #### 基本操作函数 - **push_back**: 向列表尾部添加新元素。 - **push_front**: 向列表头部添加新元素。 - **pop_back**: 移除列表尾部的元素。 - **pop_front**: 移除列表头部的元素。 - **insert**: 在指定迭代器前插入新的元素或范围内的多个元素。 - **erase**: 删除由给定迭代器指向的一个元素或是两个迭代器之间的所有元素。 #### 高效的操作特点 由于内部采用的是双向循环链表形式,因此对于频繁发生的增删动作来说效率很高;但是访问特定索引处的数据则相对较慢,因为这需要遍历整个链条来定位目标节点的位置。 #### 实现细节探讨 在实际应用当中,为了提高性能并减少碎片化现象的发生,某些库可能会对标准模板库(`STL`)里的`list`做出改进优化措施。例如,在游戏开发领域广泛使用的`EASTL`(Electronic Arts Standard Template Library),就针对原生`STL`进行了扩展增强处理[^2]。 #### 示例程序展示 下面给出一段简单的例子用于说明如何创建一个整数类型的`list`对象,并对其进行一些基础性的读写操作: ```cpp #include &lt;iostream&gt; #include &lt;list&gt; void printList(const std::list&lt;int&gt;&amp; l) { for (auto it = l.begin(); it != l.end(); ++it) std::cout &lt;&lt; *it &lt;&lt; &#39; &#39;; std::cout &lt;&lt; &#39;\n&#39;; } int main(){ std::list&lt;int&gt; numbers; // 添加几个数值进入列表 numbers.push_back(789); numbers.push_front(456); numbers.push_back(123); // 打印当前列表状态 printList(numbers); // 对列表执行排序算法 numbers.sort(); printList(numbers); // 清空列表之前先打印其大小 std::cout &lt;&lt; &quot;Size before clear(): &quot; &lt;&lt; numbers.size() &lt;&lt; &quot;\n&quot;; numbers.clear(); // 检查清空后的列表是否为空 if (numbers.empty()) std::cout &lt;&lt; &quot;The list is now empty.\n&quot;; return 0; } ``` 此代码片段展示了如何向`list`中加入数据项、调用成员方法获取前后端元素以及利用内置工具完成升序排列等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值