真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

【C++】STL——list的常用接口-創(chuàng)新互聯(lián)

list的常用接口

在這里插入圖片描述

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名申請(qǐng)、雅安服務(wù)器托管、營銷軟件、網(wǎng)站建設(shè)、迎澤網(wǎng)站維護(hù)、網(wǎng)站推廣。文章目錄
  • list的常用接口
  • 一、list的介紹
  • 二、list的使用
    • 1.list的構(gòu)造
    • 2.迭代器的使用
      • 2.1.begin和end
      • 2.2.rbegin和rend
      • 2.3.范圍for
      • 2.4.迭代器的分類
    • 3.list的元素訪問函數(shù)
      • 3.1.front和back
    • 4.list的容量操作函數(shù)
      • 4.1.empty
      • 4.2.size和max_size
    • 5.list修改的相關(guān)函數(shù)
      • 5.1.push_front和pop_front
      • 5.2.push_back和pop_back
      • 5.3.insert和erase
      • 5.3.clear和resize
      • 5.4.swap
    • 6.list的其他操作函數(shù)
      • 6.1.sort
      • 6.2.splice
      • 6.3.move和move_if
      • 6.4.unique和merge
      • 6.5.reverse
    • 7.list與vector對(duì)比

一、list的介紹
  1. list是可以在常數(shù)范圍內(nèi)在任意位置進(jìn)行插入和刪除的序列式容器,并且該容器可以前后雙向迭代。
  2. list的底層是雙向鏈表結(jié)構(gòu),雙向鏈表中每個(gè)元素存儲(chǔ)在互不相關(guān)的獨(dú)立節(jié)點(diǎn)中,在節(jié)點(diǎn)中通過指針指向其前一個(gè)元素和后一個(gè)元素。
  3. list與forward_list非常相似:最主要的不同在于forward_list是單鏈表,只能朝前迭代,已讓其更簡單高效。
  4. 與其他的序列式容器相比(array,vector,deque),list通常在任意位置進(jìn)行插入、移除元素的執(zhí)行效率更好。
  5. 與其他序列式容器相比,list和forward_list大的缺陷是不支持任意位置的隨機(jī)訪問,比如:要訪問list的第6個(gè)元素,必須從已知的位置(比如頭部或者尾部)迭代到該位置,在這段位置上迭代需要線性的時(shí)間開銷;list還需要一些額外的空間,以保存每個(gè)節(jié)點(diǎn)的相關(guān)聯(lián)信息(對(duì)于存儲(chǔ)類型較小元素的大list來說這可能是一個(gè)重要因素

二、list的使用 1.list的構(gòu)造
構(gòu)造函數(shù)接口說明
list()構(gòu)造空的list
list (size_type n, const value_type& val = value_type())構(gòu)造的list中包含n個(gè)值為val的元素
list (const list& x)拷貝構(gòu)造函數(shù)
list (InputIterator first, InputIterator last)用[first, last)區(qū)間中的元素構(gòu)造list
  • list()
listlt1;
  • list (size_type n, value_type& val = value_type())
listlt2(4, 1);//構(gòu)造4個(gè)值為1的元素
  • list (const list& x)
listlt3(lt2);//用lt2拷貝構(gòu)造lt3
  • list (InputIterator first, InputIterator last)
//1、用l2的[begin(), end())左閉右開的區(qū)間構(gòu)造lt4
listlt4(lt2.begin(), lt2.end());
//2、以數(shù)組為迭代器區(qū)間構(gòu)造lt5
int array[] = {1,2,3,4 };
listlt5(array, array + sizeof(array) / sizeof(int));

2.迭代器的使用
函數(shù)聲明接口說明
begin返回第一個(gè)元素的迭代器
end返回最后一個(gè)元素下一個(gè)位置的迭代器
rbegin返回第一個(gè)元素的reverse_iterator,即end位置
rend返回最后一個(gè)元素下一個(gè)位置的reverse_iterator,即begin位置
2.1.begin和end

begin是返回第一個(gè)元素的迭代器,end是返回最后一個(gè)元素下一個(gè)位置的迭代器。可以通過迭代器進(jìn)行元素訪問:

void list_test1()
{listlt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	list::iterator it = lt.begin();
	while (it != lt.end()) //不能用it< lt.end()
	{cout<< *it<< " ";
		it++;
	}
	cout<< endl;
}
  • 注意:begin與end為正向迭代器,對(duì)迭代器執(zhí)行++操作,迭代器向后移動(dòng)。
2.2.rbegin和rend

和先前學(xué)到的string類似,rbegin的第一個(gè)元素為尾部end位置,rend返回的是begin的位置。

void list_test1()
{listlt(4, 1);
	list::reverse_iterator rit = lt.rbegin();
    //或者用auto自動(dòng)識(shí)別類型:auto rit = lt.rbegin();
	while (rit != lt.rend()) 
	{cout<< *it<< " "; // 1 1 1 1
		it++;
    }
}
  • 注意:rbegin(end)與rend(begin)為反向迭代器,對(duì)迭代器執(zhí)行++操作,迭代器向前移動(dòng)。
2.3.范圍for

范圍for的底層就是迭代器實(shí)現(xiàn)的,利用其也可進(jìn)行元素訪問:

void list_test1()
{listlt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	for(auto e : lt)
   	{cout<< e<< " ";
	}
	cout<< endl;
}
2.4.迭代器的分類
  1. 單向迭代器:只能++,不能–。比如單鏈表、哈希表等。
  2. 雙向迭代器:既能++也能–。比如雙向鏈表。
  3. 隨機(jī)訪問迭代器:既能++、–;又能+、-。比如vector、string。
  4. 迭代器是內(nèi)嵌類型(內(nèi)部類或定義在類里)

3.list的元素訪問函數(shù)
函數(shù)聲明接口聲明
front返回list第一個(gè)節(jié)點(diǎn)中值的引用
back返回list最后一個(gè)節(jié)點(diǎn)中值的引用
3.1.front和back

front返回第一個(gè)元素,back返回最后一個(gè)元素

void list_test2()
{listlt;
	for (int i = 1; i<= 4; i++)
	{lt.push_back(i);//1 2 3 4
	}
	cout<< lt.front()<< endl;//1
	cout<< lt.back()<< endl; //4
}

4.list的容量操作函數(shù)
函數(shù)聲明接口說明
empty檢測list是否為空,是返回true,不是返回false
size返回list中有效節(jié)點(diǎn)的個(gè)數(shù)
max_size返回list中的大數(shù)據(jù)
4.1.empty

empty判斷l(xiāng)ist是否為空

void list_test2()
{listlt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	
    if(lt.empty())
        cout<< "list empty"<< endl;
    lt.pop_back();
    lt.pop_back();
    lt.pop_back();
    lt.pop_back();
    if(lt.empty())
       	cout<< "list empty"<< endl;
}
4.2.size和max_size

size用來獲取list的元素個(gè)數(shù),max_size用來獲取list的大元素個(gè)數(shù)。

void list_test2()
{list lt(5, 1);   
	cout<< lt.size()<< endl;// 5
    cout<< lt.max_size()<< endl; // 返回鏈表長度大值
}

5.list修改的相關(guān)函數(shù)
函數(shù)聲明接口聲明
push_front在list首元素前插入值為val的元素
pop_front刪除list中第一個(gè)元素
push_back在list尾部插入值為val的元素
pop_back刪除list中最后一個(gè)元素
insert在list position 位置中插入值為val的元素
erase刪除list position位置的元素
swap交換兩個(gè)list中的元素
clear清空list中的有效數(shù)據(jù)
resize為list開辟空間同時(shí)進(jìn)行初始化
5.1.push_front和pop_front

push_front即頭插,pop_front即頭刪。

void list_test3()
{listlt;
	lt.push_front(1);
	lt.push_front(2);
	lt.push_front(3);
	lt.push_front(4);

	for (auto e : lt)
	{cout<< e<< " ";
	}
	cout<< endl;

	lt.pop_front();
	lt.pop_front();
    
    for (auto e : lt)
	{cout<< e<< " ";
	}
	cout<< endl;
}
5.2.push_back和pop_back

push_back即尾插,pop_back即尾刪。

void list_test3()
{listlt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	for (auto e : lt)
	{cout<< e<< " ";
	}
	cout<< endl;

	lt.pop_back();
	lt.pop_back();
	lt.pop_back();
	lt.pop_back();
    
    if(lt.empty())
        cout<< "list empty"<< endl;
}
5.3.insert和erase

list中的insert支持下列三種插入方式:

  1. 在指定位置插入一個(gè)值為val的元素
  2. 在指定位置插入n個(gè)值為val的元素
  3. 在指定位置插入一段左閉右開的迭代器區(qū)間
void list_test3()
{listlt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	list::iterator pos = find(lt.begin(), lt.end(), 2);
	//1、在3的位置插入值20
	lt.insert(pos, 20);
	for (auto e : lt)
    {cout<< e<< " ";//1 20 2 3 4
	}
	cout<< endl;

	//2、在3的位置插入3個(gè)30
	pos = find(lt.begin(), lt.end(), 3);
	lt.insert(pos, 3, 30);
	for (auto e : lt)
    {cout<< e<< " ";//1 20 2 30 30 30 3 4
	}		
	cout<< endl;

	//3、在7的位置插入迭代器區(qū)間
	pos = find(lt.begin(), lt.end(), 20);
	listlt2(3, 0);
	lt.insert(pos, lt2.begin(), lt2.end());
	for (auto e : lt)
    {cout<< e<< " ";//1 0 0 0 20 2 30 30 30 3 4
	}
    cout<< endl;
}

erase支持下列兩種刪除方式:

  1. 刪除在指定迭代器位置的元素

  2. 刪除指定迭代器區(qū)間的元素

void list_test3()
{listlt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);
	lt.push_back(6);
	list::iterator pos = find(lt.begin(), lt.end(), 2);
    
	//1、刪除2位置的元素
	lt.erase(pos);
	for (auto e : lt)
    {cout<< e<< " ";//1 3 4 5 6     
	}	
	cout<< endl;
    
	//2、刪除4到list末尾的所有元素
	pos = find(lt.begin(), lt.end(), 4);
	lt.erase(pos, lt.end());
	for (auto e : lt)
    {cout<< e<< " ";//1 3    
	}
}

注意:這里的find使用的是算法庫里面的,list并未提供find算法。

5.3.clear和resize

clear用來清空list中的有效數(shù)據(jù)。

void list_test4()
{listlt(5, -1);
	for (auto e : lt)
    {cout<< e<< " ";//-1 -1 -1 -1 -1
	}
	cout<< endl;
	lt.clear();
	for (auto e : lt)
    {cout<< e<< " ";//空        
    }
}

resize擴(kuò)容并初始化分為兩種:

如果 n 小于當(dāng)前容器大小,則內(nèi)容將減少到其前n個(gè)元素,刪除超出的元素(并銷毀它們)。

如果 n 大于當(dāng)前容器大小,則通過在末尾插入所需數(shù)量的元素來擴(kuò)展內(nèi)容,以達(dá)到n的大小。如果指定了 val,則新元素將初始化為 val ,否則,它們將被值初始化為0 或者 匿名對(duì)象。

void list_test4()
{listlt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);
	lt.push_back(6);
    resize(5);
    for(auto e : ch)
    {cout<< e<< " "; // 1 2 3 4 5
    }
    cout<< endl;
    
    resize(8, 10);
    for(auto e : ch)
    {cout<< e<< " "; // 1 2 3 4 5 10 10 10
    }
    cout<< endl;
    
    resize(10);
    for(auto e : ch)
    {cout<< e<< " "; // 1 2 3 4 5 10 10 10 0 0
    }
    cout<< endl;
}
5.4.swap

swap用于交換兩個(gè)list的內(nèi)容。

void list_test4()
{listlt1(5, 1);
	listlt2(3, 2);
	lt2.swap(lt1);
	for (auto e : lt1)
	 {cout<< e<< " "; //2 2 2   
	 }
	cout<< endl;

	for (auto d : lt2)
 	{cout<< d<< " "; //1 1 1 1 1     
 	}
}
6.list的其他操作函數(shù)
函數(shù)聲明接口說明
sort對(duì)list進(jìn)行排序
unique刪除list中的重復(fù)元素
splice將元素從一個(gè)list剪切到另一個(gè)list
move刪除具有特定值的元素
move_if刪除滿足條件的元素
merge合并排序list
reverse反轉(zhuǎn)list元素的順序
6.1.sort

list中的sort函數(shù)默認(rèn)排升序。

void list_test5()
{listlt;
	lt.push_back(2);
	lt.push_back(23);
	lt.push_back(6);
	lt.push_back(14);
	lt.push_back(10);
	lt.push_back(100);

	lt.remove(100);
	for (auto e : lt)
	{cout<< e<< " ";
	}
	cout<< endl;
	// list 雙向循環(huán)鏈表提供
	lt.sort();
	// algorithm 算法庫提供
	//sort(lt.begin(), lt.end()); 報(bào)錯(cuò)
	for (auto e : lt)
	{cout<< e<< " ";
	}
	cout<< endl;

	//迭代器功能分類
	// 1.單向 ++
	// 2.雙向 --
	// 3.隨機(jī) ++ -- + - ——>vector、string
}

注意:

list單獨(dú)提供排序是因?yàn)樗荒苡盟惴◣熘械呐判颉?/font>算法庫中的排序是一個(gè)快排,需要滿足三數(shù)取中以及傳遞隨機(jī)訪問迭代器,list并不能滿足,所以不適用。而list自己提供的排序的底層是歸并排序,但是它本身提供的排序比較慢,如果數(shù)據(jù)量較小,那效率還可以,但是如果數(shù)據(jù)量很大,我們寧愿把list中的數(shù)據(jù)尾插到vector中使用算法庫中的快排,再拷貝回list中,也不會(huì)使用自身的歸并排序。

測試一:vector使用算法庫中的sortVSlist自身的sort

// N個(gè)數(shù)據(jù)需要排序,vector+ 算法sort  list+ sort
void test_op1()
{srand((unsigned int)time(0));
	const int N = 1000000;
	vectorv;
	v.reserve(N);
	listlt1;

	for (int i = 0; i< N; ++i)
	{auto e = rand();
		v.push_back(e);
		lt1.push_back(e);
	}

	int begin1 = clock();
	sort(v.begin(), v.end());
	int end1 = clock();

	int begin2 = clock();
	//sort(lt2.begin(), lt2.end());
	lt1.sort();
	int end2 = clock();

	printf("vector sort:%d\n", end1 - begin1);
	printf("list sort:%d\n", end2 - begin2);
}

測試二:list先把數(shù)據(jù)拷貝到vector,再排序,排序完成后,再將數(shù)據(jù)拷貝回list所用時(shí)間VSlist使用自身的sort所用時(shí)間

void test_op2()
{srand((unsigned int)time(0));
	const int N = 10000000;
	vectorv;
	v.reserve(N);

	listlt1;
	listlt2;
	for (int i = 0; i< N; ++i)
	{auto e = rand();
		//v.push_back(e);
		lt1.push_back(e);
		//lt2.push_back(e);
	}

	// 拷貝到vector排序,排完以后再拷貝回來
	int begin1 = clock();
	for (auto e : lt1)
	{v.push_back(e);
	}
	sort(v.begin(), v.end());
	size_t i = 0;
	for (auto& e : lt1)
	{//e = v[i++];
		lt2.push_back(e);
	}
	int end1 = clock();

	int begin2 = clock();
	//sort(lt2.begin(), lt2.end());
	lt1.sort();
	int end2 = clock();

	printf("vector sort:%d\n", end1 - begin1);
	printf("list sort:%d\n", end2 - begin2);
}

image-20221214154254163

6.2.splice

splice將元素從一個(gè)list剪切到另一個(gè)list,被剪切的list沒有元素了。

void list_test6()
{listlt1;
	lt1.push_back(10);
	lt1.push_back(20);
	lt1.push_back(30);

	listlt2;
	lt2.push_back(1);
	lt2.push_back(2);
	lt2.push_back(3);
	lt2.push_back(4);

	auto it = lt2.begin();
	++it; // 迭代器下標(biāo)為2
	lt2.splice(it, lt1); // 把lt1的元素轉(zhuǎn)移到lt2迭代器下標(biāo)為2的位置
	for (auto e : lt2)
	{cout<< e<< " "; // 1 10 20 30 2 3 4
	}
	cout<< endl;
    for(auto e : lt1)
    {cout<< e<< " "; // 空
    }
}
6.3.move和move_if

move作用是從容器中刪除所有與 val 相等的元素。這將調(diào)用這些對(duì)象的析構(gòu)函數(shù),并通過刪除的元素?cái)?shù)來減小容器大小。

void list_test6()
{listlt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);
	lt1.push_back(4);
    lt1.push_back(2);
    
	lt1.move(2);
    for(auto e : lt1)
    {cout<< e<< " "; // 1 3 4
    }
    cout<< endl;
}

move_if作用是移除滿足條件的元素。這將調(diào)用這些對(duì)象的析構(gòu)函數(shù),并通過刪除的元素?cái)?shù)來減小容器大小。

// 是否為偶數(shù)
bool is_even(const int& value)
{return (value % 2) == 0;
}
// 是否為奇數(shù)
struct is_odd {bool operator() (const int& value)
  {  return (value % 2) == 1;
  }
};

int main ()
{int arr[]= {15,36,7,17,20,39,4,1};
  	listlt1 (arr, arr+8);  // 15 36 7 17 20 39 4 1
    
  	lt1.remove_if (is_even);    
    
 	for(auto e : lt1)
    {cout<< e<< " "; // 15 36 7 17 39 1
    }
    cout<< endl;
    
  	lt1.remove_if (is_odd());  
    for(auto e : lt1)
    {cout<< e<< " "; // 空
    }
    cout<< endl; 
 	return 0;
}
6.4.unique和merge

unique是刪除list中的重復(fù)元素。

void list_test5()
{listlt;
 listlt;
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(6);
	lt.push_back(23);
	lt.push_back(10);
	lt.push_back(3);
 lt.push_back(10);
	lt.sort();
	lt.unique();
	for (auto e : lt)
 {cout<< e<< " ";//2 3 6 10 23
 }
}
  • 注意:要想對(duì)list進(jìn)行真正的去重,必須先排序。

merge的作用是合并兩個(gè)鏈表,并且這兩個(gè)鏈表必須是有序的。

void list_test6()
{listlt1;
	lt1.push_back(10);
	lt1.push_back(30);
	lt1.push_back(20);

	listlt2;
	lt2.push_back(3);
	lt2.push_back(2);
	lt2.push_back(1);
	lt2.push_back(4);

 lt1.sort();
 lt2.sort();
 lt1.merge(lt2);

 for(auto e : lt1)
 { cout<< e<< " "; // 1 2 3 4 10 20 30 
	}
 cout<< endl;
6.5.reverse

reverse的作用是反轉(zhuǎn)list中元素的順序。

void list_test6()
{listlt1;
    for(int i = 1; i<= 5; i++)
    {lt1.push_back(i);
	}
    reverse(lt1);
    for(auto e : lt1)
    {cout<< e<< " "; // 5 4 3 2 1
	}
    cout<< endl;
}

7.list與vector對(duì)比
vectorlist
底層結(jié)構(gòu)動(dòng)態(tài)順序表,一段連續(xù)空間帶頭結(jié)點(diǎn)的雙向循環(huán)鏈表
隨機(jī)訪問支持隨機(jī)訪問,訪問某個(gè)元素效率O(1)不支持隨機(jī)訪問,訪問某個(gè)元素效率O(N)
插入和刪除任意位置插入和刪除效率低,需要搬移元素,時(shí)間復(fù)雜度為O(N),插入時(shí)有可能需要增容,增容:開辟新空間,拷貝元素,釋放舊空間,導(dǎo)致效率更低任意位置插入和刪除效率高,不需要搬移元素,時(shí)間復(fù)雜度為O(1)
空間利用率底層為連續(xù)空間,不容易造成內(nèi)存碎片,空間利用率高,緩存利用率高底層節(jié)點(diǎn)動(dòng)態(tài)開辟,小節(jié)點(diǎn)容易造成內(nèi)存碎片,空間利用率低,緩存利用率低
迭代器原生態(tài)指針對(duì)原生態(tài)指針(節(jié)點(diǎn)指針)進(jìn)行封裝
迭代器失效在插入元素時(shí),要給所有的迭代器重新賦值,因?yàn)椴迦朐赜锌赡軙?huì)導(dǎo)致重新擴(kuò)容,致使原來迭代器失效,刪除時(shí),當(dāng)前迭代器需要重新賦值否則會(huì)失效插入元素不會(huì)導(dǎo)致迭代器失效,刪除元素時(shí),只會(huì)導(dǎo)致當(dāng)前迭代器失效,其他迭代器不受影響
使用場景需要高效存儲(chǔ),支持隨機(jī)訪問,不關(guān)心插入刪除效率大量插入和刪除操作,不關(guān)心隨機(jī)訪問

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


分享文章:【C++】STL——list的常用接口-創(chuàng)新互聯(lián)
文章來源:http://weahome.cn/article/csgdde.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部