C++库里提供了顺序表和链表的各种方法,虽然说不一定要能模拟出库里面的各种方法,但是会使用也是一种技能。
vector
vector 就相当于是顺序表,但是它属于可动态增容的顺序表,但同时它也相当于一个容器,这个容器里可以装任何你想要装的数据。同时这里不是单单要介绍顺序表,而是顺序表和迭代器合起来使用。
在顺序表中,使用频率较多的函数就只有几个,模拟实现出来也不是很困难。
#include<assert.h>
#include<string>
#include<iostream>
using namespace std;
#include"TypeTraits.h"
//Vector 和List不一样,一个是数组一个是双向带头的循环链表,在引用和指针方面都有差异
template<class T>
class MyVector
{
public :
typedef T* Iterator;
typedef const T* constItrator;
public:
//构造函数只构造_start即可,释放也只释放_start
MyVector() :_start(0), _finish(0), _endofstorage(0)
{
cout << "构造" << endl;
}
void PushBack(const T& x)
{
size_t tmp = Capacity() > 0 ? Capacity() * 2 : 3;
Expand(tmp);
/*(*_finish) = x;
_finish++;*/
Insert(End(), x);
}
void Insert(Iterator pos,const T& x)
{
//因为迭代器会失效,所以需要记录pos这个位置,以免代码崩溃
int gap = pos - _start;
if (_finish == _endofstorage)
{
size_t newCapacity = Capacity() > 0 ? Capacity() * 2 : 3;
Expand(newCapacity);
pos = _start + gap;
}
assert(pos <= _finish);
Iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*(pos) = x;
_finish ++;
}
void Expand(size_t n)
{
size_t size = Size();
size_t capacity = Capacity();
//如果有效数据最后一个等于最后的范围,说明需要开辟空间
if (n >= capacity)
{
T* tmp = new T[n];
if (_start)
{
TypeCopy(tmp, _start, size);
/*for (size_t i = Begin(); i < End(); i++)
{
*tmp = *_start;
tmp++;
_start++;
}*/
}
//释放旧的空间,将 指针再指向新的空间即可
delete[] _start;
_start = tmp;
_finish = _start + size;
_endofstorage = _start + n;
}
}
void Print()
{
for (Iterator it = Begin(); it < End(); it++)
{
cout << (*it) << " " ;
}
cout << endl;
}
size_t Size()
{
return _finish - _start;
}
size_t Capacity()
{
return _endofstorage - _start;
}
//迭代器的函数
Iterator Begin()
{
return _start;
}
Iterator End()
{
return _finish;
}
//后置++
Iterator& operator++()
{
_start++;
return *this;
}
//前置++
Iterator operator++(int)
{
Iterator it = _start;
it++;
return it;
}
bool operator==(const Iterator& v)
{
return (*this) == v;
}
bool operator!=(const Iterator& v)
{
return (*this) != v;
}
private:
Iterator _start;
Iterator _finish;
Iterator _endofstorage;
};
void testVector()
{
MyVector<int> v;
v.PushBack(1);
v.PushBack(2);
v.PushBack(3);
v.PushBack(4);
v.Insert(v.End(), 5);
v.Print();
}
List
C++中,链表的库函数名称叫List,这里的链表指的是带头的双向链表
简单实现常用的方法为以下:
#include<iostream>
using namespace std;
//实现的List是一个带头的双向循环链表
template <class T>
struct __ListNode
{
__ListNode<T>* _prev;
__ListNode<T>* _next;
T _data;
__ListNode(const T& x) :_prev(NULL), _next(NULL), _data(x)
{}
};
//迭代器的实现
template<class T,class Ref,class Ptr>
struct __ListIterator
{
typedef __ListIterator<T, Ref, Ptr> Self;
typedef __ListNode<T> Node;
Node* _node;
__ListIterator(Node* node) :_node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(_node->_data);
}
Self& operator++()
{
_node = _node->_next;
return *this;
}
Self operator++(int)
{
Self tmp(*this);
_node = _node->_next;
return tmp;
}
Self& operator--()
{
_node = _node->_prev;
return *this;
}
Self operator--(int)
{
Self tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator==(const Self& s)
{
return _node == s._node;
}
bool operator!=(const Self& s)
{
return _node != s._node;
}
};
//链表的实现
template<class T>
class List
{
typedef __ListNode<T> Node;
public:
//重命名链表容器普通迭代器
typedef __ListIterator<T, T&, T*> Iterator;
//const迭代器
typedef __ListIterator<T, const T&, const T*> ConstIterator;
Iterator Begin()
{
return Iterator(_head->_next);
}
//返回的是_head,因为最后一个节点也要遍历
Iterator End()
{
return Iterator(_head);
}
ConstIterator Begin() const
{
return ConstIterator(_head->_next);
}
ConstIterator End() const
{
return ConstIterator(_head);
}
List()
:_head(new Node(T()))
{
_head->_prev = _head;
_head->_next = _head;
}
void PushBack(const T& x)
{
Node* newNode = new Node(x);
Node* tail = _head->_prev;
tail->_next = newNode;
newNode->_prev = tail;
_head->_prev = newNode;
newNode->_next = _head;
}
void Pop()
{
Node* tail = _head->_prev;
tail->_prev->_next = _head;
_head->_prev = tail->_prev;
delete tail;
}
//注意迭代器失效的问题
void Insert(Iterator pos, const T& x)
{
Node* newNode = new Node(x);
//由于接收的是个迭代器,所以要取得迭代器指向的节点
Node* cur = pos._node;
//在定义一个NOde型的节点保存pos节点的前一个位子
Node* prev = cur->_prev;
prev->_next = newNode;
newNode->_prev = prev;
cur->_prev = newNode;
newNode->_next = pos;
}
private:
Node* _head;
};
//打印链表里的数据
void Print(const List<int>& l)
{
List<int>::ConstIterator it = l.Begin();
while (it != l.End())
{
cout << (*it) << " ";
++it;
}
cout << endl;
}
void testList()
{
List<int> l;
l.PushBack(1);
l.PushBack(2);
l.PushBack(3);
//l.Pop();
Print(l);
//使用迭代器来操作
List<int>::Iterator it = l.Begin();
while (it != l.End())
{
if ((*it) % 2 != 0)
{
cout << (*it) << endl;
}
++it;
}
}
其实vector ,list都算是stl里面的东西,没有看过原版,也只能照猫画虎的写一点来加深自己对它的理解。STL里面还有几个组件,空间配置器,配接器,算法,以及仿函数,总共有六大组件,剩下的就是上面的容器和迭代器了。
在C++prime里有详细的介绍与使用,在学习C++时参考这个有很大的帮助。