列表list
列表的使用
list是一个双向链表,因此它的内存空间是可以不连续的,通过指针来进行数据的访问,这使得list的随机访问效率比较低,因此list没有提供[]运算符的重载。但list可以很好的支持任意地方的插入和删除操作,只需要移动指针即可
列表定义在< list >头文件中
列表类成员函数原型如下:
//----迭代器iterators----
iterator begin(); //返回表头元素为迭代器起始
iterator end(); //返回表尾元素为迭代器结束
reverse_iterator rbegin(); //返回表尾元素为逆向迭代器起始
reverse_iterator rend(); //返回表头元素为逆向迭代器结束
//----容量capacity----
bool empty(); //测试是否为空表
size_type size(); //返回列表长度
size_type max_size(); //返回列表能容纳的最大长度
void resize(size_type sz,T c=T()); //重置列表长度为sz,c填充到扩充元素中
//----元素存取element access----
front(); //返回表头元素
back(); //返回表尾元素
//----列表调节器modifiers----
void assign(size_type n,const T& u); //列表赋n个u值
void push_front(const T& x); //插入一个元素到表头
void pop_front(); //删除表头元素
void push_back(const T& x); //增加一个元素到表尾
void pop_back(); //删除表尾元素
void insert(iterator pos,size_type n,const T& x); //在列表pos处插入n个元素值x,pos从1起
iterator erase(iterator pos); //删除列表指定位置的元素,pos从1起
void swap(list<T,Allocator>& lst); //与列表lst互换元素
void clear(); //清空列表
//----列表运算operations----
void remove(const T& value); //删除列表中值与value相同的所有元素
void remove_if(Predicate pred); //删除列表满足条件的元素
void unique(); //删除列表重复值
void merge(list<T,Allocator>& x); //合并列表x,列表必须有序
void sort(); //列表排序
void sort(Compare comp); //列表按comp关系比较排序
void reverse(); //列表逆序
例:列表应用举例
#include<iostream>
#include<string>
#include<list> //使用列表
using namespace std; //列表定义在std命名空间
int main()
{
int A[]={15,36,7,17};
list<int>::iterator It;
list<int> L1,L2,L3(A,A+4); //L3: 15 36 7 17
for(int i=1;i<=6;i++)
L1.push_back(i); //L1: 1 2 3 4 5 6
for(int i=1;i<=3;i++)
L2.push_back(i*10); //L2: 10 20 30
It=L1.begin(); advance(It,2); //It指向3(第3个元素)
L1.splice(It,L2); //L1: 1 2 10 20 30 3 4 5 6 , L2(empty)
//此时It仍然指向3(第6个元素)
L2.splice(L2.begin(),L1,It); //L1: 1 2 10 20 30 4 5 6 , L2: 3
L1.remove(20); //L1: 1 2 10 30 4 5 6
L1.sort(); //L1: 1 2 4 5 6 10 30
L1.merge(L3); //L1: 1 2 4 5 6 10 15 30 36 7 17
L1.push_front(L2.front()); //L1: 3 1 2 4 5 6 10 15 30 36 7 17
L1.reverse(); //L1: 17 7 36 30 15 10 6 5 4 2 1 3
for(It=L1.begin();It!=L1.end();++It)
cout<<*It<<" ";
return 0;
}
列表的实现细节
列表就是一个双向的链表,其基本功能就包括生成结点,插入结点,删除结点,查找结点等。例如:
list<char> MyList; //声明了list<char>模板类的一个实例
MyList.push_back('a'); //把一个对象放到一个list的后面
MyList.push_front('b'); //把一个对象放到一个list的前面
//使用迭代器查找列表中值为'c'的结点
list<char>::iterator FindIterator;
FindIterator = find(MyList.begin(),MyList.end(),'c');
if(FindIterator==MyList.end())
cout<<"not find the char 'c'!"<<endl;
else
cout<<"*FindIterator<<endl;
例:自定义一个单向链表类模板
#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;
template<class T>
class Node { //结点类
private:
Node<T>*next;
public:
T data;
Node(const T& item,Node<T>* ptrnext=NULL); //构造函数
void InsertAfter(Node<T> *p); //在当前结点之后插入一个结点p
Node<T> *DeleteAfter(); //删除当前结点的后继结点,并返回其地址
Node<T> *NextNode() const; //求下一个结点的地址
};
template<class T>
//功能:构造函数
Node<T>::Node(const T& item,Node<T>* ptrnext) : data(item),next(ptrnext) { }
template<class T>
//功能:求下一个结点的地址
Node<T>*Node<T>::NextNode() const {
return next;
}
template<class T>
//功能:在当前结点之后插入一个结点p
void Node<T>::InsertAfter(Node<T>*p) {
p->next=next; //p结点指针域指向当前结点的后继结点
next=p; //当前结点的指针域指向p结点
}
template<class T>
//功能:删除当前结点的后继结点,并返回其地址
Node<T> *Node<T>::DeleteAfter() {
Node<T> *tempPtr=next; //将欲删除的结点地址存储到tempPtr中
if(next==NULL)
return NULL;
//如果当前结点没有后继结点则返回空
next=tempPtr->next; //使当前结点的指针域指向tempPtr的后继结点
return tempPtr; //返回被删除结点的地址
}
template<class T>
//功能:生成结点函数
Node<T> *GetNode(const T& item,Node<T> *nextPtr=NULL) {
Node<T> *newNode;
newNode=new Node<T>(item,nextPtr);
if(newNode==NULL) {
cout<<"Memory allocation failure!"<<endl;
exit(1);
}
return newNode;
}
template<class T>
//功能:生成链表函数
Node<T> *CreateList(Node<T> *head,int n) {
Node<T> *currPtr,*newNode,data;
currPtr=head=GetNode(0); //创建头结点
for(;n>0;n--) { //创建n个结点链表
cin>>data;
newNode=GetNode(data); //创建新结点
currPtr->next=newNode,currPtr=newNode;
}
currPtr->next=NULL; //尾结点
return head;
}
enum AppendNewLine { //控制输出结点后是否换行
noNewline,addNewline
};
template<class T>
//功能:输出链表函数
void PrintList(Node<T> *head,AppendNewLine addnl=noNewline) {
Node<T> *currPtr=head;
while(currPtr!=NULL) {
if(addnl==addNewline)
cout<<currPtr->data<<endl;
else
cout<<currPtr->data<<" ";
currPtr=currPtr->NextNode();
}
}
template<class T>
//功能:查找结点函数
int FindNode(Node<T> *head,T &item,Node<T> *prevPtr) {
Node<T> *currPtr=head;
prevPtr=NULL;
while(currPtr!=NULL) {
if(currPtr->data=item)
return 1;
prevPtr=currPtr;
currPtr=currPtr->NextNode();
}
return 0;
}