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)

率    底層爲連續空間,不容易造成內存碎片,空間利用率                    底層節點動態開闢,小節點容易

                          高,緩存利用率高                                                                         造成內存碎片,空間利用率低,緩存利用率低

器                     原生態指針                                                                            對原生態指針(節點指針)進行封裝

效   在插入元素時,要給所有的迭代器重新賦值,因爲插入                     插入元素不會導致迭代器失效,

                         元素有可能會導致重新擴容,致使原來迭代器失效,刪                     刪除元素時,只會導致當前迭代

                         除時,當前迭代器需要重新賦值否則會失效                                        器失效,其他迭代器不受影響

使 景     需要高效存儲,支持隨機訪問,不關心插入刪除效率                     大量插入和刪除操作,不關心隨機訪問

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