您的位置:首页 > 编程语言 > C语言/C++

C++ STL学习笔记四 list双向链表容器

2010-04-04 15:37 786 查看
/*
*
********************************************
* list双向链表容器的基础说明:
********************************************
*
* list双向链表容器采用双向链表的数据结构来存储元素数据,可以高效查找、插入、删除容器元素
*
* Reversibe Container Back Insertion Sequence Front Insertion Sequence
* 不同于vector,list查找、插入、删除元素的时间复杂度均为O(1)
*
* 使用list必须使用宏语句#include <list>
*
**************************************************************************************
*
* 创建list对象:
* 1.list<int> a;
* 2.list<int> a(10); //具有10个元素的对象a,每个元素默认值为0
* 3.list<char> a(5,'k');
* 4.list<char> b(a); //list<char> c(a.begin(),a.end())
*
**************************************************************************************
*
* 初始化赋值
* void push_back(const T& value)
*
**************************************************************************************
*
* 遍历访问
* iterator begin() //只能使用迭代器的方式进行遍历
* iterator end()
* iterator rbegin(); //反向遍历
* iterator rbegin();
*
**************************************************************************************
*
* 常用函数
*
* bool empty();
*
* void pop_front(); void pop_back();
*
* void push_front(const T&); void push_back(const T&);
* iterator insert(iterator pos,const T&x); //注意它是插入到pos前
*
* iterator erase(iterator pos);
* iterator erase(iterator first,iterator last);
* void clear();
* void remove(const T& value);
*
* void swap() //通过交换头指针来实现元素的交换
* //list内部提供的一个迁移操作
* void transfer(); //transfer(iterator position,iterator first,iterator last)在A链表position位置前插入
* //B链表迭代器区间[first,last)的元素,并将这部分元素从B链表中抹去
* void splice(iterator pos,list& X); //调用transfer函数将一个链表的所有元素全部归并到当前链表,
* //并将链表对象X清空,
* void splice(iterator pos,list& X,iterator i); //将X中迭代器i所指的元素归并到当前链表pos前,并将X中i所指元素抹去
*
* void merge(list&X); //对两个链表进行归并,要求先排序,否则merge没有太大意义
*
* void unique(); //可将连续重复的元素删除,只保留一个
*
*
*
********************************************
* Author: cumirror
* Email: tongjinooo@163.com
********************************************
*
*/

#include <list>
#include <iostream>
#include <string>
using namespace std;

struct student{
char* name;
int age;
char* city;
char* phone;
};

class studentNew{
public:
char name[10];
int age;
char city[10];
char phone[11];
studentNew(){}
studentNew(char* a,int b,char* c,char* d){
strcpy(name,a);
age=b;
strcpy(city,c);
strcpy(phone,d);
}

//为何友元函数在类外定义,出现错误error C2593: 'operator >' is ambiguous
//friend bool operator < (studentNew&a,studentNew& b);
//friend bool operator > (studentNew&a,studentNew& b);
//friend bool operator == (studentNew&a,studentNew& b);

friend bool operator< (studentNew& a,studentNew& b){
return strcmp(a.name,b.name)<0;
}
friend bool operator> (studentNew& a,studentNew& b){
return strcmp(a.name,b.name)>0;
}
friend bool operator== (studentNew& a,studentNew& b){
return strcmp(a.name,b.name)==0;
}

bool operator() (studentNew& a,studentNew& b){
return strcmp(a.name,b.name)==-1;
}
};
/*
bool operator < (studentNew& a,studentNew& b){
return strcmp(a.name,b.name)<0?true:false;
}
bool operator > (studentNew& a,studentNew& b){
return strcmp(a.name,b.name)>0?true:false;
}
bool operator == (studentNew& a,studentNew& b){
return strcmp(a.name,b.name)==0?true:false;
}
*/

int main(){
/* list<int> a;
a.push_back(4);
a.push_back(3);
a.push_back(2);
a.push_back(8);
a.push_back(7);
a.push_back(5);
a.push_back(6);
a.push_back(9);
a.push_back(10);
a.push_back(1);

// list的sort函数实现方法,如下

list<int> carry;
list<int> counter[64];
int fill=0;
while(!a.empty()){
carry.splice(carry.begin(),a,a.begin());
int i=0;
while(i<fill&&!counter[i].empty()){
counter[i].merge(carry);
carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if(i==fill)++fill;
}
for(int i=1;i<fill;++i){
counter[i].merge(counter[i-1]);
a.swap(counter[fill-1]);
}
for(list<int>::iterator j=a.begin();j!=a.end();j++){
cout<<*j<<endl;
}
*/
// 其它函数使用示例,如下:

student s[]={
{"童进",23,"武汉","XXX"},
{"老大",23,"武汉","XXX"},
{"饺子",23,"武汉","XXX"}
};
list<student> classA;
classA.push_back(s[0]);
classA.insert(classA.begin(),s[1]);
classA.push_back(s[3]);
cout<<classA.begin()->name<<endl;
// classA.sort(); //对于自定义结构体,没有重载</>/==这些操作符,故无法排序

// 自己创建一个新类studentNew重载操作符再进行判断
studentNew m1("童进",23,"武汉","XXX");
studentNew m2("老大",23,"武汉","XXX");
studentNew m3("饺子",23,"武汉","XXX");
list<studentNew> classNew;
classNew.push_back(m1);
classNew.push_back(m2);
classNew.push_back(m3);
// 判断友元函数是否起作用
if( m1>m2 ){
cout<<"新类中操作已经重载成功"<<endl;
}
// 运用SGI STL库时
// 用函数对象studentNew,替换了greater<T>
classNew.sort(studentNew());
// 若用VC自带的STL库时,下面这样书写即可实现.至于为何有这样的差异,目前我还不知
// classNew.sort();
for(list<studentNew>::iterator m=classNew.begin();m!=classNew.end();m++){ //通过结果可以看出
cout<<m->name<<endl; //classNew已经进行了重新排列
}

list<string> classB;
classB.push_back("童");
classB.push_back("兰");
classB.push_front("张");
classB.push_back("童");
classB.sort(); //对于string类型,有默认类型的greater<T>
classB.unique(); //剔除重复数据
for(list<string>::iterator k=classB.begin();k!=classB.end();k++){
cout<<*k<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: