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

C++用模板实现顺序表和栈

2016-06-11 18:52 337 查看
下面介绍模板类来实现静态顺序表和栈,顺序栈(seqential stack)就是用顺序存储方式存储的栈。在下面顺序栈的类定义中是用数组存储的,用_array[]存储,_size是实际存放的个数,_capacity是最大允许存放元素的个数,变量top表示栈顶部元素的位置。由于栈是后进先出原则,所以可以通过调用顺序表实现进栈和出栈等操作,Container<T>为“容器”,利用模板的模板参数--容器适配器调用顺序表。
下面用模板实现了顺序表的头插、尾插、头删、尾删、请求空间及增删查改等操作。
如下所示:
)
,_size(s._size)
,_capacity(s._size)
{
for (size_t i = 0; i < _size; i++)
{
_array[i] = s._array[i];
}
}
SeqList<T>& operator=(SeqList<T>& s)
{
if (this != &s)
{
swap(_array, s._array);
swap(_size, s._size);
swap(_capacity, s._capacity);
}
return *this;
}
~SeqList()
{
if (_array)
{
delete[] _array;
}
}
public:
void CheckCapacity(size_t n);
void Reserve(size_t n);//请求空间
void PrintSeqList();
void PushBack(const T& x)//尾插
{
CheckCapacity(_size + 1);//检查增加一个后的容量
_array[_size++] = x;
}
void PopBack()//尾删
{
if (_size > 0)
_array[_size--] = '0';
}
void PushFront(const T& x)//头插
{
CheckCapacity(_size + 1);
if (_size > 0)
{
for (size_t i = _size; i > 0; i--)
{
_array[i] = _array[i - 1];
}
}
_array[0] = x;
_size++;
}
void PopFront()//头删
{
if (_size > 0)
{
for (size_t i = 0; i < _size; i++)
{
_array[i] = _array[i + 1];
}
_size--;
}
}
size_t Find(const T& x)//查找x
{
for (size_t i = 0; i < _size; i++)
{
if (x == _array[i])
return i + 1;
}
return -1;
}
void Insert(size_t pos, const T& x)//在pos处添加x
{
assert(pos);
if (pos == _size)
SeqList<T>::PushBack(x);
else
{
CheckCapacity(_size + 1);
for (size_t i = _size; i > pos - 1; i--)
{
_array[i] = _array[i - 1];
}
_size++;
_array[pos - 1] = x;
}
}
void Erase(size_t pos)
{
assert(pos);
if (pos == _size)
SeqList<T>::PopBack();
else
{
for (size_t i = pos - 1; i < _size; i++)
{
_array[i] = _array[i + 1];
}
_size--;
}
}
size_t Size()
{
return _size;
}
T& Top()
{
return _array[_size-1];
}
public:
T* _array;
size_t _size;
size_t _capacity;
};

//类外定义
template<typename T>//模板类的类型是SeqList<T>
void SeqList<T>::CheckCapacity(size_t n)//扩容
{
if (n > _capacity)
{
_capacity = n > 2 * _capacity + 3 ? n : (2 * _capacity + 3);
//_array = (T*)realloc(_array, sizeof(T)*_capacity);
//当T为string等自定义类型时,会发生错误。由于malloc,realloc都没有调用构造函数初始化对象,产生随机值
T*tmp = new T[_capacity];//开辟空间大小为_capacity
if (_array)
{
//memcpy(tmp, _array, sizeof(T)*_size);//vs2008中对于长字符串会析构两次造成崩溃,vs2013中长短字符串在析构时都会崩溃
for (size_t i = 0; i < _size; i++)
{
tmp[i] = _array[i];
}
}
delete[] _array;
_array = tmp;
}
}

template<typename T>
void SeqList<T>::Reserve(size_t n)//请求空间-保存
{
SeqList<T>::CheckCapacity(n);
}

template<typename T>
void SeqList<T>::PrintSeqList()//打印顺序表
{
if (_size <= 0)
{
cout << ]顺序栈的实现进栈、出栈、判空、栈顶及栈中元素个数等操作
//C++栈的实现(模板)
//模板参数--实现容器适配器
//template<class T,class Container>//此写法对于Stack<int,SeqList<char>>s;易造成数据丢失
//template<class T,class Container=SeqList<T>>
//模板的模板参数--容器适配器
template<class T, template<class> class Container = SeqList>//template<class T, template<class T> class Container = SeqList>
class Stack
{
public:
void Push(const T& x)
{
_con.PushBack(x);
}
void Pop()
{
_con.PopBack();
}
bool Empty()
{
return _con.Size() == 0;
}
size_t Size()
{
return _con.Size();
}
T& Top()//栈顶
{
return _con.Top();
}
void PrintStack()
{
_con.PrintSeqList();
}
protected:
//Container _con;
Container<T> _con;
};
顺序表及顺序栈的测试用例如下:

#include<iostream>
using namespace std;

#include"SeqList.h"

void Test1()
{//尾插尾删,赋值,构造
SeqList<int> s1;
s1.PushBack(1);
s1.PushBack(2);
s1.PushBack(3);
s1.PushBack(4);
s1.PrintSeqList();

SeqList<string> s2;
//cout << sizeof(string) << endl;//28
s2.PushBack("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
s2.PushBack("sssss");
s2.PushBack("fffff");
s2.PushBack("ggggg");
s2.PrintSeqList();

//s2.PopBack();
//s2.PopBack();
//s2.PrintSeqList();
//s2.PopBack();
//s2.PopBack();
//s2.PopBack();
//s2.PrintSeqList();

SeqList<string> s3(s2);
s3.PrintSeqList();
SeqList<string> s4;
s4 = s2;
s4.PrintSeqList();

s2.Reserve(1000);//请求空间保存
cout << s2._capacity << endl;
}

void Test2()
{//头插头删
SeqList<int> s1;
s1.PushFront(1);
s1.PushFront(2);
s1.PushFront(3);
s1.PushFront(4);
s1.PrintSeqList();

SeqList<string> s2;
s2.PushFront("xxxxxx");
s2.PushFront("yyyyyy");
s2.PushFront("zzzzzz");
s2.PushFront("gggggg");
s2.PrintSeqList();

s2.PopFront();
s2.PopFront();
s2.PrintSeqList();
s2.PopFront();
s2.PopFront();
s2.PopFront();
s2.PrintSeqList();

}

void Test3()
{//头插头删
SeqList<int> s1;
s1.PushBack(1);
s1.PushBack(2);
s1.PushBack(3);
s1.PushBack(4);
s1.PrintSeqList();

SeqList<string> s2;
s2.PushBack("xxxxxx");
s2.PushBack("gggggg");
s2.PushBack("zzzzzz");
s2.PushBack("ffffff");
s2.PrintSeqList();

cout << s2.Find("gggggg") << endl;
s2.Insert(2, "yyyyyy");
s2.PrintSeqList();
s2.Erase(3);
s2.PrintSeqList();
}
void Test4()
{//顺序栈
//Stack<int, SeqList<int>>s1;
//Stack<int>s2;
//Stack<int> s1;
//s1.Push(0);
//s1.Push(1);
//s1.Push(2);
//s1.Push(3);
Stack<string> s1;
s1.Push("xxxxxx");
s1.Push("yyyyyy");
s1.Push("zzzzzz");
s1.Push("gggggg");

cout << s1.Empty() << endl;
cout << "size->" << s1.Size() << endl;
string top = s1.Top();
cout << "top->" << top << endl;
//访问栈中元素
while (!s1.Empty())
{
cout << s1.Top() << "-";
s1.Pop();
}
cout << endl;
s1.Pop();
s1.PrintStack();
s1.Pop();
s1.Pop();
s1.PrintStack();
}
本文出自 “Scen” 博客,请务必保留此出处http://10741357.blog.51cto.com/10731357/1751038
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: