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不僅是一個雙向連結串列,而且還是一個環狀雙向連結串列。所以它只需要一個指標,便可以完整表現整個連結串列:
如果讓指標node指向刻意置於尾端的一個空白節點,node便能符合STL對於“前開後閉”區間的要求,成為last迭代器。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; ... };
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++stl的list(雙向連結串列)
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