栈
2016-04-09 14:22
330 查看
栈
栈是限定在表尾进行插入和删除的线性表。
栈为什么用的是线性表而不是链表?
原因:1.操作简单:链表是一种物理地址非连续的、非顺序的存储结构,链表中的逻辑顺序是由链表
中的每个指针指向链接次序实现的,而顺序表是一种类似于数组结构,是一片连续的空间。而栈
需要在表的尾部进行操作,顺序表操作简单于链表。
2.效率高:由于顺序表是一块连续的空间,所以可以一次创建较大的空间,而链表每次都需要
开辟空间。
3.cpu利用率高:顺序表每次可以在缓存器中缓存一片空间,而由于链表不连续所以不能缓 存一片连续的空间。ps: 搜狗百科中提到“CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量 比内存小的多但是交换速度却比内存要快得多。缓存大小是CPU的重要指标之一,而且缓存的 结构和大小对CPU速度的影响非常大,CPU内缓存的运行频率极高,一般是和处理器同频运作, 工作效率远远大于系统内存和硬盘”
#include<iostream> #include<assert.h> using namespace std; template<class T> class Stack { public: Stack() :_data(NULL) , _size(0) , _capacity(0) { _checkCapacity(); } Stack(const Stack<T>&s) :_data(new T[s._size*sizeof(T)]) , _size(s._size) , _capacity(s._size) { for (size_t i = 0; i < _size; i++) { _data[i] = s._data[i]; } } /* 写法一: stack<T>& operator=(const Stack<t>&s) { if (this !=&s) { delete []_data; _data = new t[s._size*sizeof(t)]; _size = s._size; _capacity = s._size; for (size_t i = 0; i < _size; i++) { _data[i] = s._data[i]; } } return *this; } 写法二: Stack<T>& operator=(const Stack<T>&s) { if (this != &s) { 若先delete[]_data再开辟空间,容易出现释放小空间却要创建大空间的现象, 有一定可能会创建空间失败,故先开辟空间,再释放 T *tmp = new T[s._size*sizeof(T)]; for (size_t i = 0; i < s._size; i++) { tmp[i] = s._data[i]; } delete[]_data; _data = tmp; _size = s._size; _capacity = s._size; } return *this; }*/ //现代写法 Stack<T>& operator=(Stack<T>&s) { swap(_data, s._data); //s出域后析构 _size = s._size; _capacity = s._size; return *this; } ~Stack() { if (_data != NULL) { delete _data; } } public: void push(const T& x) { _checkCapacity(); _data[_size++] = x; } void Pop() { assert(_size>0); _size--; } bool Empty() { return _size == 0; } T &Top() { return _data[_size - 1]; } size_t size() { return _size; } protected: void _checkCapacity() { if (_data==NULL) { _capacity = 3; _data = new T[_capacity]; return ; } if (_capacity==_size) { _capacity = _capacity * 2; } T *tmp = new T[_capacity]; for (size_t i = 0; i < _size; i++) { tmp[i] = _data[i]; } delete[]_data; _data = tmp; } private: T* _data; size_t _size; size_t _capacity; }; void test() { Stack<int> s1; s1.push(1); s1.push(1); s1.push(1); s1.push(1); s1.push(1); s1.push(1); s1.push(1); Stack<int>s2(s1); Stack<int>s3; s3 = s2; cout << s3.size(); while (!s3.Empty()) { cout << s3.Top() << " "; s3.Pop(); } } int main() { test(); getchar(); return 0; }
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- C++基于栈实现铁轨问题
- 数据结构之Treap详解
- C语言栈的表示与实现实例详解
- C语言实现颠倒栈的方法
- 算法系列15天速成 第十天 栈
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- 一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Array栈方法和队列方法的特点说明
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture