深入分析STL标准模板List的使用及事项

来源:互联网 发布:淘宝 买药 编辑:程序博客网 时间:2024/06/05 09:55

一、List介绍:

List是C++STL标准模板库的重要类模板之一,通俗解释可以看做是双向链表。可在常数时间内在任何位置执行插入和删除操作的顺序容器。

相较于vector的连续线性空间,list就显得复杂许多,它的好处是每次插入或删除一个元素,就配置或释放一个元素空间。因此,list对于空间的运用有绝对的精准,一点也不浪费。而且,对于任何位置的元素插入或元素移除,list永远是常数时间。

list不仅是一个双向链表,而且还是一个环状双向链表。另外,还有一个重要性质,插入操作和接合操作都不会造成原有的list迭代器失效,这在vector是不成立的。因为vector的插入操作可能造成记忆体重新配置,导致原有的迭代器全部失效。甚至list的元素删除操作(erase),也只有“指向被删除元素”的那个迭代器失效,其他迭代器不受任何影响。

 

二、List分析:

(1)、List内部成员。

相当于一个链表的节点,可用或添加数据类型。

1. struct __list_node  

2. {  

3.     typedef void* void_pointer;  

4.     void_pointer next;  

5.     void_pointer prev;  

6.     T data;  

7. };  

数据类型可以是intcharfloatstring等,具体视需求而定。

还有重要的内部成员类型是迭代器类型。

template<class T, class Ref, class Ptr>  

struct __list_iterator  

{  

    typedef __list_iterator<T, T&, T*>             iterator;   // STL标准强制要求  

    typedef __list_iterator<T, Ref, Ptr>           self;  

  

    typedef bidirectional_iterator_tag iterator_category;  

    typedef T value_type;  

    typedef Ptr pointer;  

    typedef Ref reference;  

    typedef __list_node<T>* link_type;  

    typedef size_t size_type;  

    typedef ptrdiff_t difference_type;  

  

    link_type node;   //迭代器内部有一个普通指针,指向list的节点

}

通过重载迭代器的前缀、后缀自加自减,赋值符号等,实现迭代器的移动,即可在链表上进行移动的操作。通过迭代器在链表上的移动找寻相应的位置或元素,进行list的操作。

对于list的存储空间分配,内部有专属的空间配置器,每次配一个节点,其操作类似链表:

// 专属之空间配置器,每次配置一个节点大小  

typedef simple_alloc<list_node, Alloc> list_node_allocator;

 

(2)、接口:

从其功能函数分析其接口,以及完成的功能及返回值。

类型1:与list的容量相关的函数

1empty

原型:bool empty ( ) const; 

功能:判断lsit是否为空,即size是否为0

返回值:size0,返回true,否则,返回false

2size

原型:size_type size() const;

功能:返回lsit中元素的个数

返回值:size_type

3Max_size

原型:size_type max_size () const;

功能:返回lsit的最大容量

返回值:

4resize

原型:void resize ( size_type sz, T c = T())

功能:重新分配lsit的大小。如果sz小于目前的size就将多余的值删除;如果sz大于目前的size,就在增加容量,且用c填充。例如:

mylist.resize(5);        //size定为

mylist.resize(8,100);  //size定为8,多出的用100填充 

mylist.resize(12);      //size定为12 

 

类型2:获取元素函数:

1front

原型:      reference front ( ); 

                         const_reference front ( ) const; 

功能:获取第一个元素

返回值:第一个元素的值

2back

原型:reference back ( ); 

const_reference back ( ) const 

功能:获取最后一个元素

返回值:最后一个元素

 

类型3:修改lsit的函数

1assign

原型:void assign ( InputIterator first, InputIterator last ); 

               void assign ( size_type n, const T& u) 

功能:为list重新分配空间并赋值。将[first,last)范围内的值或者nu值的拷贝赋给list

返回值:无

2push_front:从头插入一个元素。pop_front:删除第一个元素

push_back:在尾部插入一个元素。 pop_back:删除最后一个元素

3insert

原型:iterator insert ( iterator position, const T& x ); 

    void insert ( iterator position, size_type n, const T& x ); 

template <class InputIterator> 

    void insert ( iterator position, InputIterator first, InputIterator last ); 

功能:插入元素

insert ( iterator position, const T& x ) :在position位置处插入元素x

insert ( iterator position, size_type n, const T& x ):在position位置处开始插入nx

insert ( iterator position, InputIterator first, InputIterator last ):在position位置处开始插入

[firstlast)范围内的元素。

返回值:只有第一个函数返回插入的元素所在位置

4erase

原型:iterator erase ( iterator position );

      iterator erase ( iterator first, iterator last );

功能:清除链表中position 处或者[first,last)范围内的元素。会减少listsize值。

返回值:清除的最后一个元素的下一个位置(迭代器)

5swap

原型:void swap ( list<T,Allocator>& lst)

功能:将两个lsit交换

6clear

功能:清空list

 

类型4:操作类的函数

1splice

原型:设list2调用了splice函数

void splice ( iterator position, list<T,Allocator>& x );list x中的所有元素插入到调用该函数的list2position处。List x会被清空。

void splice ( iterator position, list<T,Allocator>& x, iterator i );x中指向i的位置处的元素插入到list2position处。X会将i位置处的值删除。

void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last ); x[first,last)位置处的元素插入到list2position处。

 

功能:Move elements from list to list。将一个lsit中的值移动到另一个list

2remove

原型:void remove ( const T& value );

功能:清除链表中特定的值valuelsitsize会相应减少。

返回值:无

3remove_if

原型:template <class Predicate>

      void remove_if ( Predicate pred );

功能:在满足Predicate pred返回true值时,移除元素。pred可以是一个返回bool类型的函数,还可以是一个重写operator函数的类。    例如:

// a predicate implemented as a function:

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

// a predicate implemented as a class:

class is_odd

{

public:

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

};

返回值:无

4unique

原型:void unique ( ); 

template <class BinaryPredicate>

  void unique ( BinaryPredicate binary_pred );按照规则binary_pred消除重复值。例如:

bool same_integral_part (double first, double second) 

{ return ( int(first)==int(second) ); } 

  

// a binary predicate implemented as a class: 

class is_near 

public: 

  bool operator() (double first, double second) 

  { return (fabs(first-second)<5.0); } 

}; 

调用:mylist.unique (same_integral_part);   

  mylist.unique (is_near());

功能:消除list中的重复元素

返回值:

5merge

原型:void merge ( list<T,Allocator>& x ); 

template <class Compare>

  void merge ( list<T,Allocator>& x, Compare comp );

功能:合并两个已经有序(同时为升序或降序)的list

merge()组合起两个排好序的表。如果一个表未排序,merge()仍然能产生出一个表,其中包含着原来两个表元素的并集。当然,对结果的排序就没有任何保证了。向splice()函数一样,merge()函数也不复制元素。

merge函数的作用是:将两个有序的序列合并为一个有序的序列。函数参数:merge(first1,last1,first2,last2,result,compare);//firs1t为第一个容器的首迭代器,last1为第一个容器的末迭代器,first2为第二个容器的首迭代器,last2为容器的末迭代器,result为存放结果的容器,comapre为比较函数(可略写,默认为合并为一个升序序列)。

返回值:

 

 

三、内存管理方法:

根据双向链表的特性,只需要一个指针即可表示整个环形双向链表。对于空链表的建立,配置一个节点空间,令node指向它,同时另node头尾都指向自己。同时创建值为valuen个节点只需进行插入操作,时间复杂度为O(1)

特别要注意的是内存的释放,函数如下:

1.  ~list()  

2.   {  

3.     // 释放所有结点  // 使用全局函数distance()进行计算, 时间复杂度O(n)  

4.   size_type size() const  

5.   {  

6.     size_type result = 0;  

7.     distance(begin(), end(), result);  

8.     return result;  

9.   }  

10.   clear();  

11.   // 释放头结点  

12.   put_node(node);  

13.   }    

 

1. // 销毁所有结点, 将链表置空  

2. template <class T, class Alloc>  

3. void list<T, Alloc>::clear()  

4. {  

5.   link_type cur = (link_type) node->next;  

6.   while (cur != node)  

7.   {  

8.     link_type tmp = cur;  

9.     cur = (link_type) cur->next;  

10.     destroy_node(tmp);  

11.   }  

12.   // 恢复node原始状态  

13.   node->next = node;  

14.   node->prev = node;  

15. }    

四、封装技巧:

与众多的类模板相同的,使用类的构建,只需要了解函数的内部接口,不关心内部操作的实现。通过代码分析可看出,在list内部有许多的protected类型的数据,如上面所讲述的空间配置器。乃至一些protected类型的函数,这都是为了防止外部的直接访问给内部数据造成的修改。类似下面所举的数据与函数。

1. protected:  

2.     link_type node ;     // 只要一个指针,便可表示整个环状双向链表  

3.     // 分配一个新结点, 注意这里并不进行构造,  

4.     // 构造交给全局的construct, 见<stl_stl_uninitialized.h>  

5.     link_type get_node() { return list_node_allocator::allocate(); }  

6.   

7.     // 释放指定结点, 不进行析构, 析构交给全局的destroy  

8.     void put_node(link_type p) { list_node_allocator::deallocate(p); }  

9.   

10.     // 产生(配置并构造)一个节点, 首先分配内存, 然后进行构造  

11.     // 注: commit or rollback  

12.     link_type create_node(const T& x)  

13.     {  

14.         link_type p = get_node();  

15.         construct(&p->data, x);  

16.         return p;  

17.     }  

18.   

19.     // 析构结点元素, 并释放内存  

20.     void destroy_node(link_type p)  

21.     {  

22.         destroy(&p->data);  

23.         put_node(p);  

24.     } 

 

 

 

五、应用中需要注意的问题与不足:

如在调用erase方法之后使用“++”来获取下一个元素的位置,由于在调用erase方法以后,该元素的位置已经被删除,如果在根据这个旧的位置来获取下一个位置,则会出现异常。

错误样例:

std::list< int> List;

std::list< int>::iterator itList;

for( itList = List.begin(); itList != List.end(); )

{

      if( WillDelete( *itList) )

      {

           itList = List.erase( ++itList);

      }

      else

           itList++;

}

 

正确使用:

std::list< int> List;

std::list< int>::iterator itList;

for( itList = List.begin(); itList != List.end(); )

{

     if( WillDelete( *itList) )

     {

          List.erase( itList++);

     }

     else

          itList++;

}

 

同时,调用需要注意几个问题。

1、静态对象必须在类外初始化。

2、因有在类外初始化的需求,静态对象必须是公有的。

 

linklist<int> list2;

class A

{

public:

    static linklist<int> list;

    void mod()

    {

        list.add(10);

    }

    void print()

    {

        list.print();

    }

 

};

linklist<int> A::list=list2;

int main()

{

    A a;

    a.mod();

    a.print();

    system("pause");

}

 

 

 

 

 

 

 

 

 

 

 

附录:

一、List类模板代码及其解析

template <class T>

struct __list_node

{

typedef void* void_pointer;

void_pointer next;

void_pointer prev;

T data;

};

 

// 不使用默认参数因为有一些编译器不能提供推导能力,

template<class T, class Ref, class Ptr>

struct __list_iterator

{

typedef __list_iterator<T, T&, T*>             iterator;   // STL标准强制要求

typedef __list_iterator<T, Ref, Ptr>           self;

 

typedef bidirectional_iterator_tag iterator_category;

typedef T value_type;

typedef Ptr pointer;

typedef Ref reference;

typedef __list_node<T>* link_type;

typedef size_t size_type;

typedef ptrdiff_t difference_type;

 

link_type node;   //迭代器内部当然要有一个普通指针,指向list的节点

 

__list_iterator(link_type x) : node(x) {}

__list_iterator() {}

__list_iterator(const iterator& x) : node(x.node) {}

 

// STL算法中需要迭代器提供支持

bool operator==(const self& x) const { return node == x.node; }

bool operator!=(const self& x) const { return node != x.node; }

 

// 以下对迭代器取值(dereference,取的是节点的数据值

reference operator*() const { return (*node).data; }

 

// 以下是迭代器的成员存取运算子的标准做法

pointer operator->() const { return &(operator*()); }

 

// 前缀自加,对迭代器累加1,就是前进一个节点

self& operator++()

{

node = (link_type)((*node).next);

return *this;

}

 

// 后缀自加需要先产生自身的一个副本然会再对自身操作最后返回副本

self operator++(int)

{

self tmp = *this;

++*this;

return tmp;

}

 

// 前缀自减

self& operator--()

{

node = (link_type)((*node).prev);

return *this;

}

 

self operator--(int)

{

self tmp = *this;

--*this;

return tmp;

}

};

 

////////////////////////////////////////////////////////////////////////////////

// list不仅是个双向链表而且还是一个环状双向链表

////////////////////////////////////////////////////////////////////////////////

//       end()              头结点             begin()

//         ↓                  ↓                  ↓

//      --------           --------           --------           --------

// ---->| next |---------->| next |---------->| next |---------->| next |------

// |    --------           --------           --------           --------     |

// |  --| prev |<----------| prev |<----------| prev |<----------| prev |<--| |

// |  | --------           --------           --------           --------   | |

// |  | | data |           | data |           | data |           | data |   | |

// |  | --------           --------           --------           --------   | |

// |  |                                                                     | |

// |  | --------           --------           --------           --------   | |

// ---|-| next |<----------| next |<----------| next |<----------| next |<--|--

//    | --------           --------           --------           --------   |

//    ->| prev |---------->| prev |---------->| prev |---------->| prev |----

//      --------           --------           --------           --------

//      | data |           | data |           | data |           | data |

//      --------           --------           --------           --------

////////////////////////////////////////////////////////////////////////////////

 

// 默认allocatoralloc, 其具体使用版本请参照<stl_alloc.h>

template <class T, class Alloc = alloc>

class list

{

protected:

typedef void* void_pointer;

typedef __list_node<T> list_node;

 

// 专属之空间配置器,每次配置一个节点大小

typedef simple_alloc<list_node, Alloc> list_node_allocator;

 

public:

typedef T value_type;

typedef value_type* pointer;

typedef value_type& reference;

typedef list_node* link_type;

typedef size_t size_type;

typedef ptrdiff_t difference_type;

 

typedef __list_iterator<T, T&, T*>             iterator;

 

protected:

link_type node ;     // 只要一个指针,便可表示整个环状双向链表

// 分配一个新结点注意这里并不进行构造,

// 构造交给全局的construct, <stl_stl_uninitialized.h>

link_type get_node() { return list_node_allocator::allocate(); }

 

// 释放指定结点不进行析构析构交给全局的destroy

void put_node(link_type p) { list_node_allocator::deallocate(p); }

 

// 产生(配置并构造)一个节点首先分配内存然后进行构造

// : commit or rollback

link_type create_node(const T& x)

{

link_type p = get_node();

construct(&p->data, x);

return p;

}

 

// 析构结点元素并释放内存

void destroy_node(link_type p)

{

destroy(&p->data);

put_node(p);

}

 

protected:

// 用于空链表的建立

void empty_initialize()

{

node = get_node();   // 配置一个节点空间,令node指向它

node->next = node;   // node头尾都指向自己,不设元素值

node->prev = node;

}

 

  // 创建值为valuen个结点的链表

  // : commit or rollback

void fill_initialize(size_type n, const T& value)

{

empty_initialize();

__STL_TRY

{

// 此处插入操作时间复杂度O(1)

insert(begin(), n, value);

}

__STL_UNWIND(clear(); put_node(node));

}

    

 

public:

list() { empty_initialize(); }

 

iterator begin() { return (link_type)((*node).next); }

 

// 链表成环当指所以头节点也就是end

iterator end() { return node; }

 

// 头结点指向自身说明链表中无元素

bool empty() const { return node->next == node; }

 

// 使用全局函数distance()进行计算时间复杂度O(n)

size_type size() const

{

size_type result = 0;

distance(begin(), end(), result);

return result;

}

 

size_type max_size() const { return size_type(-1); }

reference front() { return *begin(); }

reference back() { return *(--end()); }

 

////////////////////////////////////////////////////////////////////////////////

// 在指定位置插入元素

////////////////////////////////////////////////////////////////////////////////

//       insert(iterator position, const T& x)

//                       

//                 create_node(x)

//                 p = get_node();-------->list_node_allocator::allocate();

//                 construct(&p->data, x);

//                       

//            tmp->next = position.node;

//            tmp->prev = position.node->prev;

//            (link_type(position.node->prev))->next = tmp;

//            position.node->prev = tmp;

////////////////////////////////////////////////////////////////////////////////

 

iterator insert(iterator position, const T& x)

{

link_type tmp = create_node(x);   // 产生一个节点

// 调整双向指针,使tmp插入进去

tmp->next = position.node;

tmp->prev = position.node->prev;

(link_type(position.node->prev))->next = tmp;

position.node->prev = tmp;

return tmp;

}

 

  // 指定位置插入n个值为x的元素详细解析见实现部分

  void insert(iterator pos, size_type n, const T& x);

  void insert(iterator pos, int n, const T& x)

  {

  insert(pos, (size_type)n, x);

  }

  void insert(iterator pos, long n, const T& x)

  {

  insert(pos, (size_type)n, x);

  }

 

  // 在链表前端插入结点

  void push_front(const T& x) { insert(begin(), x); }

  // 在链表最后插入结点

  void push_back(const T& x) { insert(end(), x); }

 

  // 移除迭代器position所指节点

  iterator erase(iterator position)

  {

  link_type next_node = link_type(position.node->next);

  link_type prev_node = link_type(position.node->prev);

  prev_node->next = next_node;

  next_node->prev = prev_node;

  destroy_node(position.node);

  return iterator(next_node);

  }

 

  // 擦除一个区间的结点详细解析见实现部分

  iterator erase(iterator first, iterator last);

 

  void resize(size_type new_size, const T& x);

  void resize(size_type new_size) { resize(new_size, T()); }

  void clear();

 

  // 删除链表第一个结点

  void pop_front() { erase(begin()); }

  // 删除链表最后一个结点

  void pop_back()

  {

  iterator tmp = end();

  erase(--tmp);

  }

 

  list(size_type n, const T& value) { fill_initialize(n, value); }

  list(int n, const T& value) { fill_initialize(n, value); }

  list(long n, const T& value) { fill_initialize(n, value); }

 

  ~list()

  {

    // 释放所有结点  // 使用全局函数distance()进行计算时间复杂度O(n)

  size_type size() const

  {

    size_type result = 0;

    distance(begin(), end(), result);

    return result;

  }

  clear();

  // 释放头结点

  put_node(node);

  }

 

  list<T, Alloc>& operator=(const list<T, Alloc>& x);

 

protected:

 

////////////////////////////////////////////////////////////////////////////////

// [first, last)内的所有元素移动到position之前

// 如果last == position, 则相当于链表不变化不进行操作

////////////////////////////////////////////////////////////////////////////////

// 初始状态

//                   first                             last

//                     ↓                                 ↓

//      --------   --------   --------     --------   --------   --------

//      | next |-->| next |-->| next |     | next |-->| next |-->| next |

//  ... --------   --------   -------- ... --------   --------   -------- ...

//      | prev |<--| prev |<--| prev |     | prev |<--| prev |<--| prev |

//      --------   --------   --------     --------   --------   --------

//

//                           position

//                               

//      --------   --------   --------   --------   --------   --------

//      | next |-->| next |-->| next |-->| next |-->| next |-->| next |

//  ... --------   --------   --------   --------   --------   -------- ...

//      | prev |<--| prev |<--| prev |<--| prev |<--| prev |<--| prev |

//      --------   --------   --------   --------   --------   --------

//

// 操作完成后状态

//                           first

//                             |

//               --------------|--------------------------------------

//               | ------------|------------------------------------ |   last

//               | |           ↓                                   | |     

//      -------- | |        --------   --------     --------       | |  --------   --------

//      | next |-- |  ----->| next |-->| next |     | next |-----  | -->| next |-->| next |

//  ... --------   |  |     --------   -------- ... --------    |  |    --------   -------- ...

//      | prev |<---  |  ---| prev |<--| prev |     | prev |<-- |  -----| prev |<--| prev |

//      --------      |  |  --------   --------     --------  | |       --------   --------

//                    |  |                                    | |

//                    |  ------                               | |

//                    ------- |  ------------------------------ |

//                          | |  |                              |

//                          | |  |  -----------------------------

//                          | |  |  |

//                          | |  |  |  position

//                          | |  |  |     

//      --------   -------- | |  |  |  --------   --------   --------   --------

//      | next |-->| next |-- |  |  -->| next |-->| next |-->| next |-->| next |

//  ... --------   --------   |  |     --------   --------   --------   -------- ...

//      | prev |<--| prev |<---  ------| prev |<--| prev |<--| prev |<--| prev |

//      --------   --------            --------   --------   --------   --------

////////////////////////////////////////////////////////////////////////////////

void transfer(iterator position, iterator first, iterator last)

{

if (position != last)   // 如果last == position, 则相当于链表不变化不进行操作

{

(*(link_type((*last.node).prev))).next = position.node;

(*(link_type((*first.node).prev))).next = last.node;

(*(link_type((*position.node).prev))).next = first.node;

link_type tmp = link_type((*position.node).prev);

(*position.node).prev = (*last.node).prev;

(*last.node).prev = (*first.node).prev;

(*first.node).prev = tmp;

}

}

 

public:

// 将链表x移动到position所指位置之前

void splice(iterator position, list& x)

{

if (!x.empty())

transfer(position, x.begin(), x.end());

}

 

// 将链表中i指向的内容移动到position之前

void splice(iterator position, list&, iterator i)

{

iterator j = i;

++j;

if (position == i || position == j) return;

transfer(position, i, j);

}

 

// [first, last}元素移动到position之前

void splice(iterator position, list&, iterator first, iterator last)

{

if (first != last)

transfer(position, first, last);

}

 

void remove(const T& value);

void unique();

void merge(list& x);

void reverse();

void sort();

 

};

 

// 销毁所有结点将链表置空

template <class T, class Alloc>

void list<T, Alloc>::clear()

{

  link_type cur = (link_type) node->next;

  while (cur != node)

  {

    link_type tmp = cur;

    cur = (link_type) cur->next;

    destroy_node(tmp);

  }

  // 恢复node原始状态

  node->next = node;

  node->prev = node;

}

 

// 链表赋值操作

// 如果当前容器元素少于x容器则析构多余元素,

// 否则将调用insert插入x中剩余的元素

template <class T, class Alloc>

list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x)

{

  if (this != &x)

  {

    iterator first1 = begin();

    iterator last1 = end();

    const_iterator first2 = x.begin();

    const_iterator last2 = x.end();

    while (first1 != last1 && first2 != last2) *first1++ = *first2++;

    if (first2 == last2)

      erase(first1, last1);

    else

      insert(last1, first2, last2);

  }

  return *this;

}

 

 

// 移除容器内所有的相邻的重复结点

// 时间复杂度O(n)

// 用户自定义数据类型需要提供operator ==()重载

template <class T, class Alloc>

void list<T, Alloc>::unique()

{

  iterator first = begin();

  iterator last = end();

  if (first == last) return;

  iterator next = first;

  while (++next != last)

  {

    if (*first == *next)

      erase(next);

    else

      first = next;

    next = first;

  }

}

 

// 假设当前容器和x都已序保证两容器合并后仍然有序

template <class T, class Alloc>

void list<T, Alloc>::merge(list<T, Alloc>& x)

{

  iterator first1 = begin();

  iterator last1 = end();

  iterator first2 = x.begin();

  iterator last2 = x.end();

 

  // 注意:前提是,两个lists都已经递增排序

  while (first1 != last1 && first2 != last2)

    if (*first2 < *first1)

{

      iterator next = first2;

      transfer(first1, first2, ++next);

      first2 = next;

    }

    else

      ++first1;

  if (first2 != last2)

  transfer(last1, first2, last2);

}

 

 

 

 

二、List使用样例程序:

/* 

 熟悉链表的库函数操作:创建链表,插入元素,删除元素,查找元素,为链表排序 遍历元素 掌握其使用

*/

#include <iostream>

#include <list>      //链表头文件

#include <algorithm> //find函数头文件

using namespace std;

 

int main()

{

    list<int>   L;

    list<int>::iterator it;

 

    //插入元素 输出

    int i=0,n;  //插入数量

    int num;

    cout<<"输入要插入元素的个数:";

    cin>>n;

    cout<<"输入"<<n<<"个元素:"<<endl;

    while (i<n)

    {

        cin>>num;

        L.push_back(num);   //重尾部插入元素 这样可以保证元素的顺序正确

        i++;

    }

    //输出

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

    {

        cout<<*it<<" ";

    }

    cout<<endl;

 

    //查找元素

    int searh;

    cout<<"输入要找的元素:";

    cin>>searh;

    it = find(L.begin(), L.end(), searh);

    if (it!=L.end())

    {

        cout<<searh<<"查找成功"<<endl;

    }

    else

    {

        cout<<"查找失败"<<endl;

    }

 

    //排序

    L.sort();

    //输出

    cout<<"排好序后的元素为:"<<endl;

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

    {

        cout<<*it<<" ";

    }

    cout<<endl;

 

    //删除元素

    int k = 0;

    int de;

    cout<<"输入要删除第几个元素:";

    cin>>de;

    while (k!=de)

    {

        it++;

        k++;

    }

    L.erase(it);   //删除元素  remove函数也行,相同元素一起删除

    cout<<"删除后的元素为:"<<endl;

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

    {

        cout<<*it<<" ";

    }

    cout<<endl;

 

    //插入元素

    int inser,m,h=0;

    cout<<"输入要插入的元素:";

    cin>>inser;

    cout<<"输入要插入的位置:";

    cin>>m;

 

    while (h!=m)

    {

        it++;

        h++;

    }

    //插入元素

    L.insert(it, inser);  //it位置插入num

 

    cout<<"插入后的元素为:"<<endl;

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

    {

        cout<<*it<<" ";

    }

    cout<<endl;

 

    return 0;

}

0 0
原创粉丝点击