目录
一 知识点总结
二 list的基本使用
1.list遍历方式
2.list排序(不推荐)
3.list数据操作
三 list 模拟实现
1 List.h
2 List.cpp
1.原生指针可以当做天然迭代器使用。其实vector/string 的迭代器就是原生指针。但是,如list物理空间不连续的容器,使用原生指针就已经无法完成迭代器的功能了,所以就需要用迭代器去封装list的节点指针node*,重载这个类的* ++ 等运算符,去模拟指针的访问行为。
2.迭代器的作用:可以让我们不用在意容器的底层结构到底是数组、链表、树型结构等等,封装隐藏了底层的细节,让我们可以用简单统一的方式去访问修改容器。
3.常见容器的的迭代器分为三种:①单向(++) forwora_list ②双向:(++/--) list ③随机:(++/--/+/-)vector/string
4.算法实现的函数模板,理论而言,是通用的,传什么容器的迭代器都可以,但是算法中可能用不同的迭代器操作,具体就要看传的迭代器是否支持,也就是说,还是有要求。
5.list 节点的指针原生行为不满足迭代器定义。通过类去封装节点的指针,重载运算法来控制。
//list遍历方式 迭代器 范围for
//g++ test_list1.cpp -std=C++11
//打印list
void print(const list& lt)
{
auto it = lt.begin();
//list::const_iterator it = lt.begin();
while (it != lt.end())
{
cout << *it << " ";
it++;
}
cout << endl;
}
//通用的容器打印函数。
template
void PrintContainer(const Con& c)
{
typename Con::const_iterator it = c.begin();
while (it != c.end())
{
cout << *it << " ";
it++;
}
cout << endl;
}
void test_list1()
{
list lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
print(lt1);
int a[] = { 1,5,8,9 };
list lt2(a,a+4);
print(lt2);
}
//list排序
void sort_test()
{
int a[] = { 9,5,8,9 };
list lt1(a, a + 4);
print(lt1);
vector v1(a, a + 4);
// < 升序 默认
// > 降序
sort(v1.begin(), v1.end());//升序
//sort(v1.begin(), v1.end(), greater());//降序
//sort的底层使用的是快速排序,快速排序要求容器迭代器必须是随机迭代器。
//比如:快排要三数取中优化,不支持随机访问,效率就不够了。
//sort(lt1.begin(), lt1.end());//不支持
//不建议用,效率低。
//lt1.sort(); //默认升序
lt1.sort(greater()); //降序
print(lt1);
}
//数据操作
void test_list2()
{
list lt1 = { 1,2,3,50,50,50,49,50,50,50 };
//cout << lt1.max_size();
PrintContainer(lt1);
//lt1.assign(2, 10);//assign 将list中数据覆盖清除
//PrintContainer(lt1);
//vector的insert 会导致pos失效,但是list不会。
list::iterator pos = find(lt1.begin(), lt1.end(), 50);
lt1.insert(pos, 1000);
lt1.insert(pos, 9999);
PrintContainer(lt1);
//erase会导致list的pos失效
lt1.erase(pos);
PrintContainer(lt1);
lt1.remove(1000);//找到就删除
PrintContainer(lt1);
lt1.remove(100000); //没找到就不做处理
PrintContainer(lt1);
//去重复
lt1.unique();
PrintContainer(lt1);
//配合排序,才能真正去重
lt1.sort();//归并,一般情况下,不建议使用链表排序,效率不高。
lt1.unique();
PrintContainer(lt1);
//逆置
lt1.reverse();
PrintContainer(lt1);
}
#pragma once
#include
#include
#include
using namespace std;
namespace zsd
{
//结点
template
struct _list_node
{
T _val;
_list_node* _next;
_list_node* _prev;
_list_node(const T& val=T())
:_val(val)
,_prev(nullptr)
,_next(nullptr)
{}
};
//迭代器
// typedef _list_iterartor iterator;
// typedef _list_iterartor const_iterator;
template
struct _list_iterator
{
typedef _list_node node;
typedef _list_iterator self;
node* _pnode;
_list_iterator(node* pnode)
:_pnode(pnode)
{}
// 拷贝构造、operator=、析构我们不写,编译器默认生成就可以用
Ref operator*()
{
return _pnode->_val;
}
Ptr operator->()
{
return &_pnode->_val;
}
bool operator!=(const self& s) const
{
return _pnode != s._pnode;
}
bool operator==(const self& s) const
{
return _pnode == s._pnode;
}
//++it
self& operator++()
{
_pnode = _pnode->_next;
return *this;
}
//it++
self operator++(int)
{
self tmp(*this);
_pnode = _pnode->_next;
return tmp; //返回操作前的
}
//--it
self& operator--()
{
_pnode = _pnode->_prev;
return *this;
}
//it--
self operator--(int)
{
self tmp(*this);
_pnode = _pnode->_prev;
return tmp;
}
};
//链表
template
class list
{
typedef _list_node node;
public:
typedef _list_iterator iterator;
typedef _list_iterator const_iterator;
iterator begin()
{
return iterator(_head->_next);
}
const_iterator begin() const
{
return const_iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
const_iterator end() const
{
return const_iterator(_head);
}
list()
{
//_head = new node(T()); //构造一个匿名对象 T(),也可以在_list_node的构造函数传参数时赋缺省值
_head = new node;
_head->_next = _head;
_head->_prev = _head;
}
//copy(lt)
list(const list& lt)
{
_head = new node;
_head->_next = _head;
_head->_prev = _head;
for (const auto& e : lt)
{
push_back(e);
}
}
//copy= lt1
list& operator = (list lt)
{
swap(_head, lt._head);
return *this;
}
void insert(iterator pos, const T& x)//在指定位置前插入数据
{
assert(pos._pnode);
node* cur = pos._pnode;
node* prev = cur->_prev;
node* newnode = new node(x);
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = cur;
cur->_prev = newnode;
}
iterator erase(iterator pos) //删除指定位置节点
{
assert(pos._pnode);
assert(pos != end());
node* prev = pos._pnode->_prev;
node* next = pos._pnode->_next;
delete pos._pnode;
prev->_next = next;
next->_prev = prev;
return iterator(next);
}
void push_back(const T& x)//尾插
{
//node* newnode = new node(x);
//node* tail = _head->_prev;
//tail->_next = newnode;
//newnode->_prev = tail;
//newnode->_next = _head;
//_head->_prev = newnode;
insert(end(),x);
}
void push_front(const T& x)//头插
{
insert(begin(), x);
}
void pop_back()//尾删
{
erase(--end());
}
void pop_front()//头删
{
insert(begin());
}
bool empty()//是否为空
{
return begin() == end();
}
size_t size() //O(N)
{
size_t sz=0;
iterator it = begin();
while (it != end())
{
++sz;
++it;
}
}
void clear() //删除链表
{
iterator it = begin();
while (it != end())
{
erase(it++);
}
}
~list()
{
clear();
delete _head;
_head = nullptr;
}
private:
node* _head;
};
void PrintList(const list& lt)
{
list::const_iterator it = lt.begin();
while (it != lt.end())
{
// *it += 1;
cout << *it << " ";
++it;
}
cout << endl;
}
//测试1
void TestList1()
{
list lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_front(1);
lt.push_front(1);
lt.push_front(1);
lt.push_front(1);
PrintList(lt);
list::iterator it = lt.begin();
while (it != lt.end())
{
*it += 10;
cout << *it << " ";
++it;
}
cout << endl;
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
}
//测试2
void TestList2()
{
list lt;
lt.push_back(1);
lt.push_back(2);
lt.push_front(100);
lt.push_front(100);
PrintList(lt);
list lt1(lt);
lt1.push_back(1000);
PrintList(lt1);
lt.clear();
PrintList(lt);
}
}
#include"List.h"
int main()
{
//zsd::TestList1();
zsd::TestList2();
return 0;
}