c++容器(list类模板总结)---5

       STL 中的算法 sort 可以用来对 vector 和 deque 排序,它需要随机访问迭代器的支持。因为 list 不支持随机访问迭代器,所以不能用算法 sort 对 list 容器排序。因此,list 容器引入了 sort 成员函数以完成排序。

list排序插入函数的使用

#include <iostream>
#include <stdlib.h>
#include <list>
#include <algorithm>

using namespace std;

class A{
private: int n;

public:
	A(int _n){
		n = _n;
	}
	friend bool operator < (const A &a1, const A &a2);
	friend bool operator ==(const A &a1, const A &a2);
	friend ostream& operator << (ostream& o, const A &a2);
};
bool operator <(const A &a1, const A &a2)
{
	return a1.n < a2.n;
}

bool operator ==(const A &a1, const A &a2)
{
	return a1.n == a2.n;
}
ostream& operator <<(ostream &o, const A &a)
{
	o << a.n;
	return o;
}

template <class T>
void Print(T first, T last)
{
	for (; first != last; ++first)
	{
		cout << *first << " ";
	}
	cout << endl;
}
int main()
{
	A a[] = { 1, 2, 3, 4, 53, 2 };
	A b[] = { 10, 23, 4, 65,23,10,10,10,4,4,7,7,7,87 };
	list<A>lst1(a, a + sizeof(a) / sizeof(a[0]))
		, lst2(b, b + sizeof(b) / sizeof(b[0]));
	lst1.sort();
	cout << "1):"; Print(lst1.begin(),lst1.end()); //从小到大排序后输出

	lst2.sort();
	cout << "2):"; Print(lst2.begin(), lst2.end()); //从小到大排序后输出

	lst2.remove(4); //删除和4相同的元素
	cout << "3):"; Print(lst2.begin(), lst2.end());

	lst2.pop_front(); //删除lst2的第一个元素
	cout << "4):"; Print(lst2.begin(), lst2.end());

	lst2.unique(); //删除所有和前一个元素相等的元素
	cout << "5):"; Print(lst2.begin(),lst2.end());

	lst1.merge(lst2); //合并lst2到lst1并清空lst2
	cout << "6.1):"; Print(lst1.begin(), lst1.end());
	cout << "6.2):"; Print(lst2.begin(), lst2.end());

	lst1.reverse(); //将lst1前后倒置
	cout << "7):"; Print(lst1.begin(), lst1.end());

	lst2.insert(lst2.begin(), a + 1, a + 4);  //在 lst2 中插入 三个元素
	cout << "8)"; Print(lst2.begin(), lst2.end());
	list <A>::iterator p1, p2, p3;
	p1 = find(lst1.begin(), lst1.end(), 30);
	p2 = find(lst2.begin(), lst2.end(), 2);
	p3 = find(lst2.begin(), lst2.end(), 4);
	lst1.splice(p1, lst2, p2, p3);  //将[p2, p3)插入p1之前,并从 lst2 中删除[p2,p3)
	cout << "9)"; Print(lst1.begin(), lst1.end());  
	cout << "10)"; Print(lst2.begin(), lst2.end());  
	system("pause");
	return 0;
}

 

用 list 解决约瑟夫问题。

约瑟夫问题是:有 n 只猴子,按顺时针方向围成一圈选大王(编号为 1~n),从第 1 号开始报数,一直数到 m,数到 m 的猴子退到圈外,剩下的猴子再接着从 1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王。编程求输入 n、m 后,输出最后猴王的编号。

输入数据:每行是用空格分开的两个整数,第一个是 n,第二个是 m(0<m, n<=1 000 000)。最后一行是:
0 0

输出要求:对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号。

输入样例:
6 2
12 4
8 3
0 0

输出样例:
5
1
7
 

#include <list>
#include <iostream>
using namespace std;
int main()
{
    list<int> monkeys;
    int n, m;
    while (true) {
        cin >> n >> m;
        if (n == 0 && m == 0)
            break;
        monkeys.clear();  //清空list容器
        for (int i = 1; i <= n; ++i)  //将猴子的编号放入list
            monkeys.push_back(i);
        list<int>::iterator it = monkeys.begin();
        while (monkeys.size() > 1) { //只要还有不止一只猴子,就要找一只猴子让其出列
            for (int i = 1; i < m; ++i) { //报数
                ++it;
                if (it == monkeys.end())
                    it = monkeys.begin();
            }
            it = monkeys.erase(it); //删除元素后,迭代器失效,
                                    //要重新让迭代器指向被删元素的后面
            if (it == monkeys.end())
                it = monkeys.begin();
        }
        cout << monkeys.front() << endl; //front返回第一个元素的引用
    }
    return 0;
}

 

vector与list 的区别

                                           vector                                                                                         list

构      动态顺序表,一段连续空间                                                               带头结点的双向循环链表

访 问     支持随机访问,访问某个元素效率O(1)                                              不支持随机访问,访问某个元素 效率O(N)

除   任意位置插入和删除效率低,需要搬移元素,

                         时间复杂 度为O(N),插入时有可能需要增容,                               任意位置插入和删除效率高,不需要搬移元素

                         增容:开辟新空 间,拷贝元素,释放旧空间,导致效率更低          时间复杂度O(1)

率    底层为连续空间,不容易造成内存碎片,空间利用率                    底层节点动态开辟,小节点容易

                          高,缓存利用率高                                                                         造成内存碎片,空间利用率低,缓存利用率低

器                     原生态指针                                                                            对原生态指针(节点指针)进行封装

效   在插入元素时,要给所有的迭代器重新赋值,因为插入                     插入元素不会导致迭代器失效,

                         元素有可能会导致重新扩容,致使原来迭代器失效,删                     删除元素时,只会导致当前迭代

                         除时,当前迭代器需要重新赋值否则会失效                                        器失效,其他迭代器不受影响

使 景     需要高效存储,支持随机访问,不关心插入删除效率                     大量插入和删除操作,不关心随机访问

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章