21. C++ list容器類

list 是順序容器的一種厢呵。list 是一個雙向鏈表从诲。使用 list 需要包含頭文件 list果元。雙向鏈表的每個元素中都有一個指針指向后一個元素,也有一個指針指向前一個元素腾降,如圖1所示拣度。

在 list 容器中,在已經(jīng)定位到要增刪元素的位置的情況下螃壤,增刪元素能在常數(shù)時間內(nèi)完成抗果。如圖2所示,在 ai 和 ai+1 之間插入一個元素奸晴,只需要修改 ai 和 ai+1 中的指針即可冤馏。

圖1 雙向鏈表.jpeg
圖2 在雙向鏈表中插入元素.jpeg

list 容器不支持根據(jù)下標隨機存取元素。

list 的構(gòu)造函數(shù)和許多成員函數(shù)的用法都與 vector 類似蚁滋,此處不再列舉宿接。除了順序容器都有的成員函數(shù)外,list 容器還獨有如表 1 所示的成員函數(shù)(此表不包含全部成員函數(shù)辕录,且有些函數(shù)的參數(shù)較為復(fù)雜睦霎,表中只列出函數(shù)名)。

表1.png

表1中列出的成員函數(shù)有些是重載的走诞,如 unique副女、merge、splice 成員函數(shù)都不止一個蚣旱, 這里不再一一列舉并解釋碑幅。后面對于其他容器以及算法的介紹,對于有重載的情況也不再指出塞绿。要詳細了解 STL沟涨,還需要查閱專門的 STL 手冊,或查看編譯器提供的聯(lián)機幫助异吻。

STL 中的算法 sort 可以用來對 vector 和 deque 排序裹赴,它需要隨機訪問迭代器的支持喜庞。因為 list 不支持隨機訪問迭代器,所以不能用算法 sort 對 list 容器排序棋返。因此延都,list 容器引入了 sort 成員函數(shù)以完成排序。

list 的示例程序如下:

#include <list>  //使用 list 需要包含此頭文件
#include <iostream>
#include <algorithm>  //使用STL中的算法需要包含此頭文件

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 & a);
};

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[5] = { 1, 3, 2, 4, 2 };
    A b[7] = { 10, 30, 20, 30, 30, 40, 40 };

    list<A> lst1(a, a + 5), lst2(b, b + 7);
    lst1.sort();
    Print(lst1.begin(), lst1.end());  //輸出:1 2 2 3 4

    lst1.remove(2);  //刪除所有和A(2)相等的元素
    Print(lst1.begin(), lst1.end());  //輸出:1 3 4

    lst2.pop_front();  //刪除第一個元素
    Print(lst2.begin(), lst2.end());  //輸出:30 20 30 30 40 40

    lst2.unique();  //刪除所有和前一個元素相等的元素
    Print(lst2.begin(), lst2.end());  //輸出:30 20 30 40

    lst2.sort();
    lst1.merge(lst2);  //合并 lst2 到 lst1 并清空 lst2
    Print(lst1.begin(), lst1.end());  //輸出:1 3 4 20 30 30 40
    Print(lst2.begin(), lst2.end());  //lst2是空的睛竣,輸出:空

    lst1.reverse();  //將 lst1 前后顛倒
    Print(lst1.begin(), lst1.end());  //輸出 40 30 30 20 4 3 1

    lst2.insert(lst2.begin(), a + 1, a + 4);  //在 lst2 中插入 3,2,4 三個元素

    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)
    Print(lst1.begin(), lst1.end());  //輸出:40 2 30 30 20 4 3 1
    Print(lst2.begin(), lst2.end());  //輸出:3 4

    return 0;
}

運行結(jié)果.png

應(yīng)用實例:用 list 解決約瑟夫問題。

約瑟夫問題是:有 n 只猴子射沟,按順時針方向圍成一圈選大王(編號為 1~n)殊者,從第 1 號開始報數(shù),一直數(shù)到 m躏惋,數(shù)到 m 的猴子退到圈外幽污,剩下的猴子再接著從 1 開始報數(shù)嚷辅。就這樣簿姨,直到圈內(nèi)只剩下一只猴子時,這個猴子就是猴王簸搞。編程求輸入 n扁位、m 后,輸出最后猴王的編號。

輸入數(shù)據(jù):每行是用空格分開的兩個整數(shù)趁俊,第一個是 n域仇,第二個是 m(0<m, n<=1 000 000)。最后一行是:
0 0
輸出要求:對于每行輸入數(shù)據(jù)(最后一行除外)寺擂,輸出數(shù)據(jù)也是一行暇务,即最后猴王的編號。

輸入樣例:
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) { //報數(shù)
                ++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;
}

erase 成員函數(shù)返回被刪除元素后面那個元素的迭代器挡逼。如果被刪除的是最后一個元素括改,則返回 end()。

這個程序也可以用 vector 實現(xiàn)家坎,但是執(zhí)行速度要慢很多嘱能。因為 vector 的 erase 操作牽涉元素的移動,不能在常數(shù)時間內(nèi)完成虱疏,所花費的時間和容器中的元素個數(shù)有關(guān)惹骂;而 list 的 erase 操作只是修改幾個指針而已,可以在常數(shù)時間內(nèi)完成做瞪。當 n 很大(數(shù)十萬)時对粪,兩種寫法在速度上會有明顯區(qū)別。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市衩侥,隨后出現(xiàn)的幾起案子国旷,更是在濱河造成了極大的恐慌,老刑警劉巖茫死,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跪但,死亡現(xiàn)場離奇詭異,居然都是意外死亡峦萎,警方通過查閱死者的電腦和手機屡久,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爱榔,“玉大人被环,你說我怎么就攤上這事∠暧模” “怎么了筛欢?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長唇聘。 經(jīng)常有香客問我版姑,道長,這世上最難降的妖魔是什么迟郎? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任剥险,我火速辦了婚禮,結(jié)果婚禮上宪肖,老公的妹妹穿的比我還像新娘表制。我一直安慰自己,他們只是感情好控乾,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布么介。 她就那樣靜靜地躺著,像睡著了一般阱持。 火紅的嫁衣襯著肌膚如雪夭拌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天衷咽,我揣著相機與錄音鸽扁,去河邊找鬼。 笑死镶骗,一個胖子當著我的面吹牛桶现,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鼎姊,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼骡和,長吁一口氣:“原來是場噩夢啊……” “哼相赁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起慰于,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤钮科,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后婆赠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绵脯,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年休里,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛆挫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡妙黍,死狀恐怖悴侵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拭嫁,我是刑警寧澤可免,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站噩凹,受9級特大地震影響巴元,放射性物質(zhì)發(fā)生泄漏毡咏。R本人自食惡果不足惜驮宴,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呕缭。 院中可真熱鬧堵泽,春花似錦、人聲如沸恢总。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽片仿。三九已至纹安,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砂豌,已是汗流浹背厢岂。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阳距,地道東北人塔粒。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像筐摘,于是被迫代替她去往敵國和親卒茬。 傳聞我的和親對象是個殘疾皇子船老,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容