# 模仿STL的简单Vector类和List类

/* 惠普的STL实现其代码较为复杂，我写了一个Vector类和一个List类，它们分别模仿了vector和list的部分实现。希望能有助于大家初步理解vector和list。由于水平的限制，程序会有缺陷和bug. 欢迎多提宝贵意见! */

/*
* Copyleft 2006 by Wei Songye.
* v1.06.0506
*/

//  Container.h

#ifndef CONTAINER_H_
#define CONTAINER_H_

class Container
{
protected:
virtual void Tidy() = 0;
public:
virtual ~Container() { }
virtual std::size_t Size() const = 0;
virtual bool Empty() const = 0;
virtual void Clear() = 0;
};

#endif /* CONTAINER_H_ */

//  Vector.h

#ifndef VECTOR_H_
#define VECTOR_H_

#include <ostream>
#include "Algorithm.h"
#include "Xutility.h"

template <class T> class Vector;
template <class T> std::ostream& operator<< (std::ostream& os, const Vector<T>& vec);

template<class T>
class Vector : public Container
{   //向量类，顺序存储结构
private:
T* start; // Vector开始的地址
T* finish; // Vector元素序列结束的地址, 注意不是最后一个元素的地址！而是最后一个元素的下一元素的位置
T* endOfStorage;    // Vector所分配空间的结束
void Tidy();
void Destroy(T* first);
void Reserve(size_t count);
void Allocate(std::size_t capacity);
void Construct(int count, const T val);
T* Fill(T* ptr, std::size_t count, const T& val);
public:
typedef T* Iterator;
Vector();
Vector(Vector<T>& vec);
Vector(std::size_t count);
Vector(int count, const T& val);
Vector(T arr[], std::size_t count);
~Vector();
T& Front();
T& Back();
bool Empty() const;
std::size_t Size() const ;
std::size_t Capacity() const;
std::size_t MaxSize() const;
Iterator begin();
Iterator end();
Iterator Erase(Iterator position);
Iterator Erase(Iterator first, Iterator last);
Iterator Insert(Iterator position, const T& val);
Iterator Insert(Iterator first, Iterator last, const T& val);
void Clear();
void Swap(Vector &right);
void InsertN(Iterator position, std::size_t count, const T& val);
void PushBack(const T& val);
T& operator[](std::size_t n);
friend std::ostream& operator<< <T>(std::ostream& os, const Vector<T>& vec);
};

template<class T>
{   //分配容量为capacity的Vector
start = 0;
finish = 0;
endOfStorage = 0;
if (capacity == 0)
{
return false;
}
try
{
T* vec = new T[capacity];
finish = start = vec;
endOfStorage = start + capacity;
}
{
return false;
}
return true;
}

template<class T>
void Vector<T>::Allocate(std::size_t capacity)
{   //重新分配容量为capacity的向量并把原数组的数据复制到新向量中
T* oldStart = start;
T* oldFinish = finish;
std::size_t oldSize = Size();
{
Veiz::Copy(oldStart, oldFinish, start);
finish = start + oldSize;
}
Destroy(oldStart);
}

template<class T>
void Vector<T>::Construct(int count, const T val)
{   //申请容量为count的向量，并用val填充每一个元素
{
finish = Fill(start, count, val);
}
}

template<class T>
T* Vector<T>::Fill(T* ptr, std::size_t count, const T& val)
{   //从ptr开始的count个元素都用val填充
for(std::size_t i = 0; i < count; ++i)
{
*(ptr + i) = val;
}
return (ptr + count);
}

template<class T>
void Vector<T>::Reserve(size_t count)
{   //重新分配向量空间，使其能容纳新插入的count个元素
Allocate((Size()+count) * 3 / 2);
}

template<class T>
void Vector<T>::Tidy()
{ //释放所有空间
if (start != 0)
{
delete[] start;
}
start = 0;
finish = 0;
endOfStorage = 0;
}

template<class T>
void Vector<T>::Destroy(T* first)

delete[] first;
}

template<class T>
Vector<T>::Vector()
{
}

template<class T>
Vector<T>::Vector(Vector<T>& vec)
{
Veiz::Copy(vec.begin(), vec.end(), begin());
finish = endOfStorage;
}

template<class T>
Vector<T>::Vector(T arr[], std::size_t count)
{
for(std::size_t i = 0; i < count; ++i)
{
PushBack(arr[i]);
}
}

template<class T>
Vector<T>::Vector(std::size_t count)
{
}

template<class T>
Vector<T>::Vector(int count, const T& val)
{
Construct(count, val);
}

template<class T>
Vector<T>::~Vector()
{
Tidy();
}

template<class T>
T& Vector<T>::Front()
{
return (*begin());
}

template<class T>
T& Vector<T>::Back()
{
return (*(end() - 1));
}

template<class T>
bool Vector<T>::Empty() const
{
if(start == finish)
{
return true;
}
return false;
}

template<class T>
std::size_t Vector<T>::Capacity() const
{   //剩余存储空间
return (endOfStorage - finish);
}

template<class T>
std::size_t Vector<T>::Size() const
{   //实际元素个数
return (finish - start);
}

template<class T>
std::size_t Vector<T>::MaxSize() const
{   //能容纳的元素个数
return (endOfStorage - start);
}

template<class T>
void Vector<T>::PushBack(const T& val)
{
Insert(end(), val);
}

template<class T>
void Vector<T>::Clear()
{ // 清除所有元素
Erase(begin(), end());
}

template<class T>
void Vector<T>::Swap(Vector &right)
{
Swap(start, right.start);
Swap(finish, right.finish);
Swap(endOfStorage, right.endOfStorage);
}

template<class T>
T& Vector<T>::operator[](std::size_t n)
{
return *(begin() + n);
}

template<class T>
typename Vector<T>::Iterator Vector<T>::begin()
{
return (Iterator)start;
}

template<class T>
typename Vector<T>::Iterator Vector<T>::end()
{
return (Iterator)finish;
}

template<class T>
typename Vector<T>::Iterator Vector<T>::Insert(typename Vector<T>::Iterator position, const T& val)
{   // 在position前面插入val
std::size_t off = Size() == 0 ? 0 : position - begin();
InsertN(position, (std::size_t)1, val);
return (begin() + off);
}

template<class T>
void Vector<T>::InsertN(typename Vector<T>::Iterator position, std::size_t count, const T& val)
{ // 在position前面插入count个val
if (position < start || finish < position)
{
throw("Vector insert Iterator outside range");
}
if (count == 0)
{
return;
}
if (MaxSize() - Size() < count)
{
std::size_t relPos = position - start;
Reserve(count);
position = start + relPos; //如果发生扩容，则迭代器不会失效
}
Veiz::CopyBackward(position, finish, finish + count);

Fill(position, count, val);
finish += count;
}

template<class T>
typename Vector<T>::Iterator Vector<T>::Insert(typename Vector<T>::Iterator first, typename Vector<T>::Iterator last, const T& val)
{   //把val插入到[first, last)中对应的项上，假定元素原来按从小到大排列。
if (first < start || finish < last)
{
throw("Vector Insert Iterator outside range");
}
for( ; first != last; ++first)
{
if(val < *first)
{
return (Insert(first, val));
}
}
return (Insert(first, val));
}

template<class T>
typename Vector<T>::Iterator Vector<T>::Erase(typename Vector<T>::Iterator position)
{ // 删除position处的元素
Copy(position + 1, finish, position);
//Destroy(finish - 1, finish);
--finish;
return position;
}
template<class T>
typename Vector<T>::Iterator Vector<T>::Erase(typename Vector<T>::Iterator first, typename Vector<T>::Iterator last)
{
for( ; first != last; ++first)
{
first = Erase(first);
}
return last;
}

template<class T>
std::ostream& operator<< (std::ostream& os, const Vector<T>& vec)
{

for(std::size_t i = 0; i < vec.Size(); ++i)
{
os << *(vec.start + i) << "  ";
}
return os;
}

#endif /* VECTOR_H_ */

//  List.h

#ifndef LIST_H_
#define LIST_H_

#include "Algorithm.h"
#include "Xutility.h"

template <class T> class List;
template <class T> std::ostream& operator<< (std::ostream& os, const List<T>& lst);

template <class T>
class List : public Container
{   //  带头结点的双向循环链表
private:
std::size_t length;
struct listNode
{
listNode* next;
listNode* prev;
T val;
};
listNode* node;
void Construct(std::size_t count);
void Tidy();
public:
List();
List(const std::size_t& count);
List(T arr[], const std::size_t& count);
~List();
class Iterator;
void Sort();
void Clear();
void Reverse();
void PopBack();
void PopFront();
void PushBack(const T& val);
void PushFront(const T& val);
void Merge(List<T>& x);
void Swap(List<T>& right);
bool Empty() const;
const T& Front();
const T& Back();
std::size_t Size() const;
Iterator begin() const;
Iterator end() const;
Iterator Erase(Iterator position);
Iterator Insert(Iterator position, const T& val);
Iterator Insert(Iterator first, Iterator last, const T& val);
void Splice(Iterator position, List<T>& right);
void Splice(Iterator position, List<T>& right, Iterator first);
void Splice(Iterator position, List<T>& right, Iterator first, Iterator last);
friend std::ostream& operator<< <T>(std::ostream& os, const List<T>& lst);
};

template <class T>
class List<T>::Iterator
{
public:
listNode* node;
Iterator(listNode* n) : node(n){}
Iterator(){}
T& operator* () const;
Iterator& operator++ ();
Iterator operator++ (int);
Iterator& operator-- ();
Iterator operator-- (int);
bool operator==(const Iterator& right) const;
bool operator!=(const Iterator& right) const;
};

template <class T>
List<T>::List()
{
}
template <class T>
List<T>::List(const std::size_t& count)
{
Construct(count);
}

template <class T>
List<T>::List(T arr[], const std::size_t& count)
{
for(std::size_t i = 0; i < count; ++i)
{
PushBack(arr[i]);
}
length = count;
}

template <class T>
{
node = new listNode;
node->next = node;
node->prev = node;
length = 0;
}
template <class T>
void List<T>::Construct(std::size_t count)
{
if(count < 1)
{
return;
}
typename List<T>::listNode* nodes = new typename List<T>::listNode[count];
if(count > 1)
{
for(std::size_t i = 0; i < count - 1; ++i)
{
nodes[i].next = &nodes[i+1];
nodes[i+1].prev = &nodes[i];
}
}
nodes[0].prev = node;
nodes[count-1].next = node;
node->prev = &nodes[count-1];
node->next = &nodes[0];
length = count;
}
template <class T>
List<T>::~List()
{
Tidy();
}
template <class T>
void List<T>::Tidy()
{
delete[] node;
node = 0;
}
template <class T>
std::size_t List<T>::Size() const
{
return length;
}

template <class T>
typename List<T>::Iterator List<T>::begin() const
{
return (Iterator)(node->next);
}

template <class T>
typename List<T>::Iterator List<T>::end() const
{
return (Iterator)node;
}

template <class T>
typename List<T>::Iterator
List<T>::Insert(typename List<T>::Iterator position, const T& val)
{
listNode* tempNode = new listNode;
tempNode->val = val;
tempNode->next = position.node;
tempNode->prev = position.node->prev;
tempNode->prev->next = tempNode;
(*position.node).prev = tempNode;
++length;
return tempNode;
}
template<class T>
typename List<T>::Iterator List<T>::Insert(typename List<T>::Iterator first, typename List<T>::Iterator last, const T& val)
{   //把val插入到[first, last)中对应的项上，假定元素原来按从小到大排列。
for( ; first != last; ++first)
{
if(val < *first)
{
return (Insert(first, val));
}
}
return (Insert(first, val));
}

template <class T>
void List<T>::PushFront(const T& val)
{
Insert(begin(), val);
}

template <class T>
void List<T>::PushBack(const T& val)
{
Insert(end(), val);
}

template <class T>
typename List<T>::Iterator List<T>::Erase(typename List<T>::Iterator position)
{
position.node->prev->next = position.node->next;
position.node->next->prev = position.node->prev;
delete position.node;
--length;
return position;
}

template <class T>
void List<T>::PopFront()
{
Erase(begin());
}

template <class T>
void List<T>::PopBack()
{
Iterator iter = end();
Erase(--iter);
}

template <class T>
void List<T>::Clear()
{
if (Empty())
{
return;
}

listNode* pNext;
listNode* pNode = node->next;
for (; pNode != node; pNode = pNext)
{
pNext = pNode->next;
delete pNode;
}
node->next = node;
node->prev = node;
}

template <class T>
void List<T>::Reverse()
{
typename List<T>::Iterator first = begin();
typename List<T>::Iterator next = 0;
for( ; first != end(); )
{
next = first.node->next;
Veiz::Swap(first.node->next, first.node->prev);
first = next;
}
Veiz::Swap(first.node->next, first.node->prev);
}

template <class T>
bool List<T>::Empty() const
{
return (begin() == end());
}

template <class T>
const T& List<T>::Front()

return (*begin());
}

template <class T>
const T& List<T>::Back()

return (*(--end()));
}

template <class T>
void List<T>::Merge(List<T>& right)
{
Iterator first1 = begin();
Iterator last1 = end();
Iterator first2 = right.begin();
Iterator last2 = right.end();
while(first1 != last1 && first2 != last2)
{
if(*first2 < *first1)
{
Iterator next = first2;
++next;
Splice(first1, right, first2, next);
first2 = next;
}
else
{
++first1;
}
}
if(first2 != last2)
{
Splice(last1, right, first2, last2);
}
this->length += right.length;
right.length = 0;
}

template <class T>
void List<T>::Sort()
{   //二路归并排序
if(Size() < 2)
{
return;
}
std::size_t lengthBak = length;
List<T> carry;
List<T> counter[64];
int fill = 0;
while(!Empty())
{
Iterator cur = begin();
carry.Splice(carry.begin(), *this, cur, ++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]);
}
Swap(counter[fill-1]);
length = lengthBak;
}

template <class T>
void List<T>::Swap(List<T>& right)
{
Veiz::Swap(node, right.node);
Veiz::Swap(length, right.length);
}

template <class T>
void List<T>::Splice(typename List<T>::Iterator position, List<T>& right)
{
Splice(position, right, right.begin(), right.end());
}

template <class T>
void List<T>::Splice(typename List<T>::Iterator position, List<T>& right, typename List<T>::Iterator first)
{
Splice(position, right, first, right.end());
}

template <class T>
void List<T>::Splice(typename List<T>::Iterator position,
List<T>& right,
typename List<T>::Iterator first,
typename List<T>::Iterator last)
{   //把right中[first, last)转移到position的前面
if(!right.Empty())
{
(*position.node).prev->next = first.node;
(*first.node).prev->next = last.node;
(*last.node).prev->next = (position.node);
listNode* tempNodePtr = (*first.node).prev;
(*first.node).prev = (*position.node).prev;
(*position.node).prev = (*last.node).prev;
(*last.node).prev = tempNodePtr;
}
}

template <class T>
std::ostream& operator<< (std::ostream& os, const List<T>& lst)
{
typename List<T>::Iterator first = (typename List<T>::Iterator)(lst.node->next);
const typename List<T>::Iterator last = (typename List<T>::Iterator)(lst.node);
for( ; first != last; ++first)
{
os << *first << "  ";
}
return os;
}

template <class T>
T& List<T>::Iterator::operator* () const
{
return node->val;
}

template <class T>
typename List<T>::Iterator& List<T>::Iterator::operator++ ()
{
node = node->next;
return *this;
}

template <class T>
typename List<T>::Iterator List<T>::Iterator::operator++ (int)
{
Iterator iter = *this;
++ *this;
return iter;
}

template <class T>
typename List<T>::Iterator& List<T>::Iterator::operator-- ()
{
node = node->prev;
return *this;
}

template <class T>
typename List<T>::Iterator List<T>::Iterator::operator-- (int)
{
Iterator iter = *this;
-- *this;
return iter;
}

template <class T>
bool List<T>::Iterator::operator==(const typename List<T>::Iterator& right) const
{
return (node == right.node);
}

template <class T>
bool List<T>::Iterator::operator!=(const typename List<T>::Iterator& right) const
{
return (node != right.node);
}

#endif /* LIST_H_ */

//  Algorithm.h

#ifndef ALGORITHM_H_
#define ALGORITHM_H_

#include "Xutility.h"

namespace Veiz{

template <class Iterator>
void Sort(Iterator first, Iterator last)
{   //对first到last-1之间的项进行从小到大的排序。这里选用插入排序。
InsertionSort(first, last);
}

template <class RandomAccessIterator>
void InsertionSort(RandomAccessIterator first, RandomAccessIterator last)
{   //对first到last-1之间的项插入排序。算法时间复杂度为O(n^2).last指容器最后一个元素的下一位置
if(first == last)
{
return;
}
for(RandomAccessIterator i = first + 1; i != last; ++i)
{
Insert(first, i, first);  //把i插入到first到i-1之间对应的位置
}
}

template <class RandomAccessIterator, class T>
void Insert(RandomAccessIterator first, RandomAccessIterator last, T*)
{   //把last插入到first到last-1之间对应的位置
T value = *last;  //将last保存在局部变量value中
if(value < *first)
{
CopyBackward(first, last, last+1); //把first到last之间的项向后复制到first+1到last之间
*first = value;
}
else
{
UnguardedInsert(last, value);
}
}

template <class RandomAccessIterator, class T>
void UnguardedInsert(RandomAccessIterator last, const T& value)
{   //把value插入到last-1向上对应的位置
RandomAccessIterator next = last;
--next;
while(value < *next)
{
*last = *next;
last = next--;
}
*last = value;
}

template<class InputIterator, class T>
InputIterator Find(InputIterator first, InputIterator last, const T& value)
{   //返回区间[first, last)中第一个"元素值等于value"的元素位置。如果没有找到匹配元素，返回last。
for(; first != last; ++first)
{
if(*first == value)
{
break;
}
}
return first;
}

template<class InputIterator, class T>
std::size_t Count(InputIterator first, InputIterator last, const T& value)
{   //计算区间[first, last)中元素值等于value的元素个数
std::size_t cnt = 0;
for(; first != last; ++first)
{
if(*first == value)
{
++cnt;
}
}
return cnt;
}

template<class T> inline
void Swap(T& left, T& right)
{
T tmp = left;
left = right;
right = tmp;
}

template<class Iterator1, class Iterator2> inline
void IterSwap(Iterator1 left, Iterator2 right)
{
Swap(*left, *right);
}

template<class RandomAccessIterator> inline
void Reverse(RandomAccessIterator first, RandomAccessIterator last)
{ // 反转位于区间 [first, last)内的元素
for (; first < last; ++first)
{
IterSwap(first, --last);
}
}

//  Merge()
//  将已序的源区间[first1, last1)和[first2, last2)内的元素合并，得到"以dest开始"的目标区间,
//  使得"以dest起始的目标区间"内含两个源区间内的所有元素。
//  目标区间内的所有元素都按顺序排列。
//  返回值是目标区间内“最后一个被复制元素”的下一位置。
//  源区间没有任何变化。
//  调用者应当确保两个源区间一开始都排序。
//  调用者必须确保目标区间足够大。
//  目标区间和源区间不得重复。
//  List(链式存储结构)应使用其成员函数List<T>::Merge()来合并
template<class InputIterator1, class InputIterator2, class OutputIterator>
inline OutputIterator
Merge(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator dest)
{ // 合并两个区间，元素从大到小排列
for (; first1 != last1 && first2 != last2; ++dest)
{
if (*first2 < *first1)
{
*dest = *first2;
++first2;
}
else
{
*dest = *first1;
++first1;
}
}
dest = UncheckedCopy(first1, last1, dest); // 把余下的元素附加在后面
return (UncheckedCopy(first2, last2, dest));
}

//  SetUnion()
//  将已序的源区间[first1, last1)和[first2, last2)内的元素合并，得到"以dest开始"的目标区间。
//  这个区间内的元素要不来自第一源区间，要不来自第二源区间，或是同时来自两个区间。
//  目标区间内的所有元素都按顺序排列，同时出现于两个源区间内的元素，在并集区间中将只出现一次。
//  不过如果原来的某个元区间内本来就存在重复元素，则目标区间内也会有重复元素——重复的个数是两个源区间内重复元素的较大值。
//  返回值是目标区间内“最后一个被复制元素”的下一位置。
template<class InputIterator1, class InputIterator2, class OutputIterator>
inline OutputIterator
SetUnion(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator dest)
{   //并
for (; first1 != last1 && first2 != last2; ++dest)
{
if (*first1 < *first2)
{
*dest = *first1;
++first1;
}
else
{
if (*first2 < *first1)
{
*dest = *first2;
++first2;
}
else  //  *first1 == *first2
{
*dest = *first1;
++first1;
++first2;
}
}
}
dest = UncheckedCopy(first1, last1, dest);
return (UncheckedCopy(first2, last2, dest));
}

//  SetIntersection()
//  将已序的源区间[first1, last1)和[first2, last2)内的元素合并，得到"以dest开始"的目标区间。
//  这个区间内的元素不但存在于第一源区间，也存在于第二源区间。
//  如果原来的某个元区间内本来就存在重复元素，则目标区间内也会有重复元素——重复的个数是两个源区间内重复元素的较小值。
//  返回值是目标区间内“最后一个被复制元素”的下一位置。
template<class InputIterator1, class InputIterator2, class OutputIterator>
inline OutputIterator
SetIntersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator dest)
{   //交
for (; first1 != last1 && first2 != last2; )
if (*first1 < *first2)
{
++first1;
}
else
{
if (*first2 < *first1)
{
++first2;
}
else  //  *first1 == *first2
{
*dest = *first1;
++dest;
++first1;
++first2;
}
}
return dest;
}

//  SetDifference()
//  将已序的源区间[first1, last1)和[first2, last2)内的元素合并，得到"以dest开始"的目标区间。
//  这个区间内的元素只存在于第一源区间，不存在于第二源区间。
//  目标区间内的所有元素都按顺序排列。
//  如果原来的某个元区间内本来就存在重复元素，则目标区间内也会有重复元素，
//  重复的个数是第一源区间内重复的个数键区第二元区间内相应的重复个数。目标区间内的对应重复个数将会是零。
//  返回值是目标区间内“最后一个被复制元素”的下一位置。
template<class InputIterator1, class InputIterator2, class OutputIterator>
inline OutputIterator
SetDifference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator dest)
{   //差
for ( ; first1 != last1 && first2 != last2; )
{
if (*first1 < *first2)
{
*dest = *first1;
++dest;
++first1;
}
else
{
if(*first2 < *first1)
{
++first2;
}
else  //  *first1 == *first2
{
++first1;
++first2;
}
}
}
return UncheckedCopy(first1, last1, dest);
}

template<class Iterator, class T>
bool Search(Iterator first, Iterator last, const T& val)
{   //判别成员
for( ; first != last; ++first)
{
if(*first == val)
{
return true;
}
}
return false;
}

}

#endif /* ALGORITHM_H_ */

//  Xutility.h

#ifndef XUTILITY_H_
#define XUTILITY_H_

namespace Veiz{

template<class InputIterator, class OutputIterator> inline
OutputIterator
UncheckedCopy(InputIterator first,
InputIterator last,
OutputIterator dest)
{ // 把 [_First, _Last) 复制到 [_Dest, ...)
for (; first != last; ++dest, ++first)
{
*dest = *first;
}
return dest;
}

template<class BidirectionalIterator> inline
BidirectionalIterator
UncheckedCopyBackward(BidirectionalIterator first,
BidirectionalIterator last,
BidirectionalIterator dest)
{ // 把 [_First, _Last) 复制到 [..., dest)
while (first != last)
{
*--dest = *--last;
}
return dest;
}

template<class InputIterator, class OutputIterator>
OutputIterator
Copy(InputIterator first,
InputIterator last,
OutputIterator dest)
{
return UncheckedCopy<InputIterator, OutputIterator>(first, last, dest);
}
template<class BidirectionalIterator> inline
BidirectionalIterator
CopyBackward(BidirectionalIterator first,
BidirectionalIterator last,
BidirectionalIterator dest)
{
return UncheckedCopyBackward<BidirectionalIterator>(first, last, dest);
}

}

#endif /* XUTILITY_H_ */

#### c++ stl list实现简单的学生信息管理系统

2012年12月19日 1.02MB 下载

05-15 2298

11-01 923

11-18 1910

08-12 4439

01-05 1048

08-29 956

08-01 3076

01-13 743

#### STL范例大全（C++)

2010年07月19日 198KB 下载