1. 程式人生 > >list雙向連結串列容器

list雙向連結串列容器

list容器實現了雙向連結串列的資料結構,資料元素是通過連結串列指標串聯成邏輯意義上的線性表,因此對連結串列的任一位置的元素進行插入、刪除和查詢都是極快的。

list每個節點有三個域:前驅元素指標域、資料域、後繼元素指標域,list的頭結點的前驅元素指標域儲存的是連結串列中尾元素的首指標,而list的尾節點的後繼元素指標域則儲存了頭結點的首指標,這樣構成了一個雙向迴圈連結串列。

由於list物件節點並不要求在一段連續的記憶體中,所以對於迭代器,只能通過“++"和”--“的操作將迭代器移動到後繼/前驅節點元素處。而不能對迭代器進行+n或者-n操作,這點是與vector等不同的地方。

使用list需要包含標頭檔案:#include<list>

建立list物件

(1)建立空連結串列

list<int> l;

(2)建立具有n個元素的連結串列

list<int> l(10);

(3)建立具有初值的n個元素的連結串列

list<int> l(10,5);

元素插入和遍歷

使用push_back()方法往尾部插入新元素,push_front()方法往首部插入新元素,insert()方法往迭代器位置插入新元素,連結串列自動擴張。

注意,迭代器只能採用"++"或者“--”操作,不能進行+n或者-n操作,因為各節點之間在物理上並不是順序儲存的,並且指向連結串列元素的迭代器之間也沒有大小關係。

#include<list>
#include<iostream>
using namespace std;
int main()
{
	list<int> l;
	l.push_back(2);
	l.push_back(3);
	l.push_back(5);
	
	l.push_front(1);
	
	list<int>::iterator it = l.begin();
	it++;
	l.insert(++it,20);
	//迭代器之間沒有大小關係,所以使用不等號
	for(it=l.begin();it!=l.end();it++)
	{
		cout<<*it<<" ";
	}
	return 0;
}
輸出結果:

1 2 20 3 5

反向遍歷

採用反向迭代器reverse_iterator對連結串列進行反向遍歷,使用方法和deque反向遍歷的方法一樣

#include<list>
#include<iostream>
using namespace std;
int main()
{
	list<int> l;
	for(int i=1;i<10;i++)
	l.push_back(i);
	
	list<int>::reverse_iterator rit;
	for(rit=l.rbegin();rit!=l.rend();rit++)
	{
		cout<<*rit<<" ";
	}
	return 0;
}
輸出結果:9 8 7 6 5 4 3 2 1

元素刪除

(1)使用remove()方法刪除連結串列中的一個值,所有元素值等於該值的元素都會被刪除。

(2)使用pop_front()方法刪除連結串列首元素,使用pop_back()方法刪除連結串列尾元素。

(3)使用erase()方法刪除迭代器位置上的元素

(4)使用clear()方法清空連結串列

#include<list>
#include<iostream>
using namespace std;
void Show(list<int> &l)
{
	list<int>::iterator it;
	for(it=l.begin();it!=l.end();it++)
		cout<<*it<<" ";
	cout<<endl;
}
int main()
{
	list<int> l;
	list<int>::iterator it;

	for(int i=1;i<10;i++)
	l.push_back(i);
	Show(l);
	
	l.pop_back();
	l.pop_front();
	Show(l);
	
	it = l.begin();
	l.insert(++it,5);
	l.insert(++it,5);
	Show(l);
	
	l.remove(5);
	Show(l);
	
	l.erase(it);
	Show(l);
	
	l.clear();
	cout<<l.size()<<endl;
	
	return 0;
}

輸出結果:

1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8
2 5 3 5 4 5 6 7 8
2 3 4 6 7 8
2 3 6 7 8
0

元素查詢

採用find()查詢演算法可以在連結串列中查詢元素,如果找到該元素,則返回的是該元素迭代器的位置,如果找不到則返回end()迭代器的位置。

find()演算法需要宣告標頭檔案包含:#include<algorithm>

#include<list>
#include<algorithm>
#include<iostream>
using namespace std;
void Show(list<int> &l)
{
	list<int>::iterator it;
	for(it=l.begin();it!=l.end();it++)
		cout<<*it<<" ";
	cout<<endl;
}
int main()
{
	list<int> l;
	list<int>::iterator it;

	for(int i=1;i<10;i++)
	{
		l.push_back(i);
	}
	Show(l);
	
	it = find(l.begin(),l.end(),5);
	if(it!=l.end())
		cout<<"find 5"<<endl;
	else
		cout<<"not find 5"<<endl;
	
	it = find(l.begin(),l.end(),10);
	if(it!=l.end())
		cout<<"find 10"<<endl;
	else
		cout<<"not find 10"<<endl;
	
	return 0;
}

輸出結果:

1 2 3 4 5 6 7 8 9
find 5
not find 10

元素排序

使用sort()方法對元素進行排序,預設情況先,sort函式中沒有引數,為升序排序,我們可以通過建構函式comp作為sort方法的引數,實現升序排序。

#include<list>
#include<iostream>
using namespace std;
void Show(list<int> &l)
{
	list<int>::iterator it;
	for(it=l.begin();it!=l.end();it++)
		cout<<*it<<" ";
	cout<<endl;
}
bool comp(int a,int b)
{
	return a>b;
}
int main()
{
	list<int> l;
	list<int>::iterator it;

	for(int i=10;i>0;i--)
	{
		l.push_back(i);
	}
	Show(l);
	//升序排序 
	l.sort();
	Show(l);
	//降序排序 
	l.sort(comp);
	Show(l);
	
	return 0;
}


剔除重複的元素

使用unique()方法可以提出連續重複元素,只保留一個。

注意remove()方法和unique方法的區別,remove是刪除list中所有元素為該值得節點,而unique是對於連續重複節點,只保留一個。

#include<list>
#include<iostream>
using namespace std;
void Show(list<int> &l)
{
	list<int>::iterator it;
	for(it=l.begin();it!=l.end();it++)
		cout<<*it<<" ";
	cout<<endl;
}
int main()
{
	list<int> l;
	list<int>::iterator it;

	for(int i=5;i>0;i--)
	{
		l.push_back(i);
	}
	Show(l);

	l.push_front(1);
	l.push_front(1);
	l.push_front(1);
	Show(l);
	
	l.unique();
	Show(l);
	
	return 0;
}
輸出結果:

5 4 3 2 1
1 1 1 5 4 3 2 1
1 5 4 3 2 1