1. 程式人生 > >c++ stl list(環狀雙向連結串列)

c++ stl list(環狀雙向連結串列)

1.list

  相較於vector的連續線性空間,list就顯得複雜很多,它的好處是每次插入或刪除一個元素,就配置或釋放一個元素的空間。因此,list對空間的運用有絕對的精確,一點也不浪費。而且,對於任何位置的元素插入和元素移除,list永遠是常數時間。   list的節點結構:
template <class T>
struct __list_node
{
    typedef void* void_pointer;
    void_pointer prev;
    void_pointer next;
    T data;
}
  list的迭代器:
  list不再能夠像vector一樣以普通指標作為迭代器,因為其節點不保證在儲存空間中連續存在。list迭代器必須有能力指向list的節點,並有能力進行正確的遞增、遞減、取值、成員存取等操作。由於STL list是一個雙向連結串列,迭代器必須具備前移、後移的能力,所以list提供的是Bidirectional Iterators。list有一個重要性質:插入操作和結合操作都不會造成原有的list迭代器失效,甚至list的元素刪除操作也只有“指向被刪除元素”的那個迭代器失效,其他迭代器不受任何影響。
  list的資料結構:
  SGI list不僅是一個雙向連結串列,而且還是一個環狀雙向連結串列。所以它只需要一個指標,便可以完整表現整個連結串列:
template <class T,class Alloc = alloc>
class list
{
protected:
    typedef __list_node<T> list_node;
public:
    typedef list_node* link_type;
protected:
    link_type node;
    ...
};
  如果讓指標node指向刻意置於尾端的一個空白節點,node便能符合STL對於“前開後閉”區間的要求,成為last迭代器。

2.函式成員

2.1建構函式:

/// Creates an empty list.
list();
/// Creates a list with n elements, each of which is a copy of T().
list(size_type n);
/// Creates a list with n copies of t.
list(size_type n, const T& t);
/// The copy constructor.
list(const list&);
/// Creates a list with a copy of a range.
template <class InputIterator> list(InputIterator f, InputIterator l);

2.2解構函式:

/// The destructor.
~list();

2.3插入元素:

/// Inserts a new element at the beginning.
void push_front(const T&);
/// Inserts a new element at the end.
void push_back(const T&);
/// Inserts x before pos.
iterator insert(iterator pos, const T& x);
/// Inserts the range [f, l) before pos.
template <class InputIterator> void insert(iterator pos, InputIterator f, InputIterator l);
/// Inserts n copies of x before pos.
void insert(iterator pos, size_type n, const T& x);

2.4刪除元素:

/// Removes the first element.
void pop_front();
/// Removes the last element.
void pop_back();
/// Erases the element at position pos.
iterator erase(iterator pos);
/// Erases the range [first, last)
iterator erase(iterator first, iterator last);
/// 刪除指定數值元素
void remove(const T& value);
/// 移除數值相同的連續元素
void unique();
/// Erases all of the elements.
void clear();

2.5返回元素指標或元素:

/// Returns an iterator pointing to the beginning of the list.
iterator begin();
/// Returns an iterator pointing to the end of the list.
iterator end();
/// Returns a reverse_iterator pointing to the beginning of the reversed list.
reverse_iterator rbegin();
/// Returns a reverse_iterator pointing to the end of the reversed list.
reverse_iterator rend();
/// Returns the first element.
reference front();
/// Returns the last element.
reference back();

2.6其他:

/// Returns the size of the list.
size_type size() const;
/// Returns the largest possible size of the list.
size_type max_size() const;
/// true if the list's size is 0.
bool empty() const;
/// 容器拼接
void splice(iterator pos, list& L);
void splice(iterator pos, list& L, iterator i);
void splice(iterator pos, list& L, iterator f, iterator l);
/// 元素排序
void sort();
/// 容器合併
void merge(list& L);
/// 容器內容逆向重置
void reverse();

3.例項

#include <iostream>
#include <list>
#include <algorithm>

int main()
{
    typedef std::list<int> ILIST;

    /// 1.例項物件
    ILIST first;                                // empty
    ILIST second(5);                            // 0 0 0 0 0
    ILIST third(5,10);                          // 10 10 10 10 10
    ILIST fourth(third);                        // 10 10 10 10 10
    ILIST fifth(third.begin(),third.end());     // 10 10 10 10 10

    /// 2.插入元素
    ILIST::iterator ilitr;
    ILIST ilist;
    /// 2.1尾部插入元素
    ilist.push_back(1);
    ilist.push_back(2);
    ilist.push_back(3);                         // 1 2 3
    /// 2.2頭部插入元素
    ilist.push_front(8);
    ilist.push_front(16);                       // 16 8 1 2 3
    /// 2.3指定位置插入元素
    ilitr = find(ilist.begin(),ilist.end(),1);
    if(ilitr != ilist.end())
        ilist.insert(ilitr,4);                  // 16 8 4 1 2 3

    /// 3.刪除元素
    /// 3.1刪除尾部元素
    ilist.pop_front();                          // 8 4 1 2 3
    /// 3.2刪除頭部元素
    ilist.pop_back();                           // 8 4 1 2
    /// 3.3刪除指定位置元素
    ilitr = find(ilist.begin(),ilist.end(),1);
    if(ilitr != ilist.end())
        ilist.erase(ilitr);                     // 8 4 2
    /// 3.4刪除指定數值元素
    ilist.remove(8);                            // 4 2
    /// 3.5移除數值相同的連續元素
    ilist.push_back(3);
    ilist.push_back(3);
    ilist.push_back(4);                         // 4 2 3 3 4
    ilist.unique();                             // 4 2 3 4
    /// 3.6清空所有元素
    ilist.clear();                              // empty

    /// 4.訪問元素
    ilist.push_back(1);
    ilist.push_back(2);
    ilist.push_back(4);
    /// 4.1訪問頭部元素
    ilist.front();                              // 1
    /// 4.2訪問尾部元素
    ilist.back();                               // 4

    /// 5.其他
    /// 5.1容器尺寸
    ilist.size();                               // 3
    /// 5.2容器最大尺寸
    ilist.max_size();                           // 768614336404564650
    /// 5.3容器是否為空
    ilist.empty();                              // 0
    /// 5.4容器拼接
    ILIST oilist;
    oilist.push_back(3);
    ilitr = find(ilist.begin(),ilist.end(),4);
    ilist.splice(ilitr,oilist);                 // 1 2 3 4
    /// 5.5容器合併
    oilist.push_back(12);
    oilist.push_back(6);
    oilist.push_back(9);
    oilist.sort();
    /// 兩個lists的內容都必須先經過遞增排序
    ilist.merge(oilist);                        // 1 2 3 4 6 9 12
    /// 5.6容器內容逆向重置
    ilist.reverse();                            // 12 9 6 4 3 2 1

    return 0;
}

4.參考文獻

  本文內容摘錄於《STL原始碼剖析》

相關推薦

c++ stl list環狀雙向連結串列

1.list   相較於vector的連續線性空間,list就顯得複雜很多,它的好處是每次插入或刪除一個元素,就配置或釋放一個元素的空間。因此,list對空間的運用有絕對的精確,一點也不浪費。而且,對於任何位置的元素插入和元素移除,list永遠是常數時間。   list的節

一步一步寫演算法雙向連結串列

【 宣告:版權所有,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】     前面的部落格我們介紹了單向連結串列。那麼我們今天介紹的雙向連結串列,顧名思義,就是資料本身具備了左邊和右邊的雙向指標。雙向連結串列相比較單向連結串列,主要有下

佇列的C語言實現通過核心連結串列

0. 環境說明 本文的實驗環境是: win7作業系統+Keil 5 IDE. 非常適合嵌入式軟體開發 1. 打造自己的“list.h” 在微控制器程式開發中,有時候會用到佇列。能否設計一個通用的佇列呢?我想,可以把核心連結串列用起來。 以下程式碼是我

c++stllist雙向連結串列

1.list初始化: (1)list<int>  t;  //沒有任何元素 (2)list<int>  t(10);  //建立有10個元素的連結串列 (3)lis

Objective-C之Autorelease Pool底層實現原理記錄雙向連結串列以及在Runloop中是如何參與進去的

最近需要重新整理知識點備用,把一些重要的原理都搞了一遍 前言 int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, a

資料結構與演算法JavaScript描述讀書筆記js實現連結串列-雙向連結串列

雙向連結串列 雙向連結串列的 remove() 方法比單向連結串列的效率更高,因為不需要再查詢前驅節點了 //建立建構函式建立節點 function Node(element){ this.element = element; this.next = null; th

約瑟夫環,魯智深吃饅頭之類的問題總結c++不用迴圈連結串列

今天看見這一類的題,覺得用迴圈連結串列太麻煩了,就想用某一種方法來代替迴圈連結串列,總結如下。 大致題意 n 個人圍城一圈,從第一個人開始順序編號為1到n。從第1個人從1開始報數,數到3的人出圈。再由下一個人從1開始報數,數到3的人出圈,如此迴圈數下去,直到最後一個人出圈。(題意都差不多

手寫LinkedList雙向連結串列

手寫LinkedList(雙向連結串列) 系統jdk裡的LinkedList是由一個個節點連線起來的,節點就相當於一個物件,裡面有資料域和指標域,資料域是存放資料用的,指標域就是指向下一個節點 從而相連線的 這裡是一個節點 那麼連結串列裡是什麼樣子的呢

劍指offer題解二叉樹與雙向連結串列

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。   解題思路   中序遍歷搜尋二叉樹,用pre儲存中序遍歷的前一個節點,cur為當前節點,然後使pre->right=cu

LeetCode:234. Palindrome Linked List判斷一個連結串列是不是迴文連結串列

Given a singly linked list, determine if it is a palindrome. Example 1: Input: 1->2 Output: false Example 2: Input: 1->2->2->1 Out

[LintCode] Linked List Cycle帶環連結串列

描述 給定一個連結串列,判斷它是否有環。 樣例 給出 -21->10->4->5, tail connects to node index 1,返回 true。 這裡解釋下,題目的意思,在英文原題中,tail connects

矩陣加法基於十字連結串列C語言程式碼實現

矩陣之間能夠進行加法運算的前提條件是:各矩陣的行數和列數必須相等。 在行數和列數都相等的情況下,矩陣相加的結果就是矩陣中對應位置的值相加所組成的矩陣,例如: 圖1 矩陣相加 十字連結串列法 之前所介紹的都是採用順序儲存結構儲存三元組,在類似於矩陣的加法運算中,矩陣中的資料元素變化較大(這裡的變化主

ALDS1_3_C-list的使用-雙向連結串列

挑戰程式設計競賽 上的題 list的練習題; 有一個地方卡了,在用迭代器找的時候,如果不用break就卡了。。 樣例都過不了。。其實我感覺都差不多。 因為list是雙向連結串列,不停止就沒完沒了

線性表陣列、單鏈表、靜態連結串列、迴圈連結串列雙向連結串列

線性表的定義 線性表(List):零個或多個數據元素的有限序列。 有幾個地方需要強調: 首先它是一個序列,也就是說元素之間是有順序的,若元素存在多個,則第一個元素無前驅,最後一個元素無後繼,其他每個元素都有且只有一個前驅和後繼。 然後線性表強調的是有限的。 最

資料結構——線性表 順序表、單鏈表、靜態連結串列、迴圈連結串列雙向連結串列

提示:以下內容不適合零基礎人員,僅供筆者複習之用。 一、線性結構的基本特徵: 1.集合中必存在唯一的一個“第一元素”; 2.集合中必存在唯一的一個 “最後元素”; 3.除最後元素在外,均有 唯一的後繼; 4.除第一元素之外,均有 唯一的前驅。 如:j

leetcode83. Remove Duplicates from Sorted List刪除有序連結串列中的重複項

題目要求 給定一個排好順序的連結串列,刪除連結串列中的重複項。 例子 Example 1: Input: 1->1->2 Output: 1->2 Example 2: Input: 1->1->2->3-&g

C 資料結構迴圈連結串列帶環連結串列基本操作

經典迴圈連結串列之約瑟夫問題:標號從1到n的n個人圍成一個圈,從1開始計數到m的人退出圈子,然後從退出的下一個人開始接著從1計數,數到m的人後繼續退出,最後只剩下一個人,求剩下人的編號。這便是約瑟夫問題的模型。 經典迴圈連結串列之魔術師發牌問題:魔術師手中有A、2、3……J

c語言實現二叉樹二叉連結串列非遞迴後序遍歷

演算法思想 因為後序遍歷是先訪問左子樹,再訪問右子樹,最後訪問根節點。當用棧實現遍歷時,必須分清返回根節點時,是從左子樹返回的還是從右子樹返回的。所以使用輔助指標r指向最近已訪問的結點。當然也可以在節點中增加一個標誌域,記錄是否已被訪問。 #include<iost

leetCode 83.Remove Duplicates from Sorted List刪除排序連結串列的重複 解題思路和方法

Given a sorted linked list, delete all duplicates such that each element appear only once. For example, Given 1->1->2, return 1-&

HDU 4286 Data Handler 雙向連結串列

                                                 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) P