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 << ]顺序栈的实现进栈、出栈、判空、栈顶及栈中元素个数等操作本文出自 “Scen” 博客,请务必保留此出处http://10741357.blog.51cto.com/10731357/1751038//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();
}
相关文章推荐
- C++用模板实现双链表和队列
- 【C++】智能指针shared_ptr 定位删除器(仿函数)
- 浅析c++异常
- C++之虚继承
- C语言 在屏幕上输出菱形图案
- C语言 求出100~999之间的所有“水仙花数”并输出
- C语言:编写strcpy函数
- C语言打印100 ——200之间的素数
- C语言判断1000—2000年之间的闰年
- C语言中不允许创建临时变量,交换两个数的内容
- C语言中写一个函数返回参数二进制中 1 的个数
- C语言求两个数中最大公约数
- 第14周项目3--数组类模板
- T2:滑雪(cowski.pas/c/cpp)
- notepad++搭建C语言环境(Dev c++)
- C语言动态和静态内存分配
- C语言结构体
- 如何用C语言编写PHP扩展的详解
- C++分配/释放动态内存
- C++中多线程与Singleton的那些事儿