C++ STL——list



注:原創不易,轉載請務必注明原作者和出處,感謝支持!

注:內容來自某培訓課程,不一定完全正確!

一 list容器

鏈表list是一種物理存儲單元上非連續,非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。(熟悉的鏈表的味道)

list特性總結:
(1) 采用動態存儲分配,不會造成內存浪費和溢出
(2)鏈表執行插入和刪除十分方便,修改指針即可,不需要移動大量元素
(3)鏈表靈活,但是空間和時間額外耗費比較大

如圖所示,C++中list實際上更像是雙向鏈表。它所支持的常用操作也在圖中列出。

鏈表和數組有什么區別?
(1)數組必須事先定義固定長度(元素個數),不能適應數據動態地增減的情況。當數據增加時,可能超出原先定義的元素個數;當數據減少時,造成內存浪費。
(2)鏈表動態地進行存儲分配,可以適應數據動態地增減的情況,且可以方便地插入,刪除數據元素。在數組中插入,刪除數據項時,需要移動其它數據項。

1.1 list常用API

構造函數

list<T> lst;			// 對象的默認構造形式
list(beg, end);			// 將[beg, end)區間中的元素拷貝給本身
list(n, elem);			// 將n個elem元素拷貝給本身
list(const list &lst);	// 拷貝構造函數

插入和刪除

push_back(elem);		// 尾部插入元素
pop_back();				// 尾部刪除元素
push_front();			// 首部插入元素
pop_front();			// 首部刪除元素

insert(pos, elem);		// 在pos位置插入elem元素,返回數據的位置
insert(pos, n, elem);	// 在pos位置插入n個elem元素,無返回值
insert(pos, beg, end);	// 在pos位置插入區間[beg, end)的元素,無返回值

clear();				// 清空容器
erase(beg, end);		// 刪除[beg, end)區間內的數據
erase(pos);				// 刪除pos位置的數據,返回下一個數據的位置
remove(elem);			// 刪除容器中所有與elem匹配的元素

大小操作

size();					// 返回容器中元素個數
empty();				// 判斷容器是否為空
resize(num);			// 重新指定容器的長度為num,若容器變長,則以默認值填充。如果容器變短,則超出容器長度元素將被刪除
resize(num, elem);		// 重新指定容器長度為num,elem為填充的默認值

賦值操作

assign(beg, end);		// 將[beg, end)區間中的數據拷貝賦值給本身
assign(n, elem);		// 將n個elem拷貝賦值給本身
// 重載等號運算符
list &operator=(const list &lst);
swap(lst);				// 將lst與本身的元素互換

數據存取

front();		// 返回第一個元素
back();			// 返回最后一個元素

逆序和排序

reverse();		// 反轉鏈表
sort();			// 排序

1.2 list應用案例

void printList(list<int> &l)
{
	for (list<int>::iterator it = l.begin(); it != l.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}

// 初始化
void Test1()
{
	list<int> lst1;
	list<int> lst2(10, 10);
	list<int> lst3(lst2.begin(), lst2.end());
	list<int> lst4(lst3);

	printList(lst4);
}


// 插入和刪除
void Test2()
{
	list<int> lst;
	lst.push_back(100);
	lst.push_front(200);

	lst.insert(lst.begin(), 500);
	lst.insert(lst.end(), -100);

	list<int>::iterator pos = lst.begin();
	pos++;
	pos++;
	// 在lst.begin() + 2的位置前插入2個10
	lst.insert(pos, 2, 10);
	printList(lst);

	pos = lst.begin();
	int arr[] = { 1, 2, 3, 4, 5 };
	pos++; pos++; pos++; pos++;
	lst.insert(pos, arr, arr + sizeof(arr) / sizeof(int));
	printList(lst);

	// 刪除
	lst.pop_back();
	lst.pop_front();
	printList(lst);

	lst.remove(10);
	printList(lst);

	lst.erase(lst.begin(), lst.end());
	if (lst.empty())
	{
		cout << "list is empty !" << endl;
	}
}

// 賦值
void Test3()
{
	list<int> l;
	l.assign(10, 10);

	list<int> l2;
	l2 = l;
	printList(l2);
}

// 從大到小排序
bool cmp(int a, int b)
{
	return a > b;
}

// 逆序和排序
void Test4()
{
	int arr[] = { 1, 4, 9, 5, 8, 2, 7 };
	list<int> l(arr, arr + sizeof(arr) / sizeof(int));
	printList(l);

	l.reverse();
	printList(l);

	// 這里的sort()是list的成員函數不是alogrithm里的算法
	l.sort(cmp);
	printList(l);
}

注意:算法algorithm頭文件中的sort()算法只支持可隨機訪問的容器,而list是不支持隨機訪問的,所以list自己提供了sort()成員方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM