抵制转载并改了作者名的流氓行为,博客地址:http://www.cnblogs.com/wolfred7464/。
书接上文,继续线性表。这次写一下栈和队列的简单实现和部分应用。队列的应用比较简单一些,就像现实中排队一样一样的,就不做过多赘述,主要说一下循环队列的实现,即重用已出队的空间。栈的实现也很简单,这里主要说一下栈的2种常见应用——括号匹配,算数表达式求值。
好了,先说栈吧。栈是一个后进先出的结构,只要保证后进先出,怎么实现都可以,关于代码没太多可说的,下面是一个简单的实现,简单是因为没考虑过多错误处理和动态增长。因为代码量少,所以函数的声明和定义写到一块了:
1 template <typename T> 2 class Stack { 3 private: 4 int sp; 5 T* _stack; 6 public: 7 Stack(int cap = 1024) { 8 sp = 0; 9 _stack = new T[cap]; 10 } 11 ~Stack() { 12 delete[] _stack; 13 } 14 void push(const T& x) { 15 _stack[sp++] = x; 16 } 17 void pop() { 18 sp--; 19 } 20 const T& top() { 21 return _stack[sp-1]; 22 } 23 void clear() { 24 sp = 0; 25 } 26 inline int size() { 27 return sp; 28 } 29 };
利用后进先出的特点,可以利用栈做到函数的递归调用,线程切换等,不过这是操作系统考虑的问题了。这里说一下2个简单的应用。
先说括号匹配,括号匹配就是给出一个字符串,判断字符串中的括号是否是匹配的,例如"sin(a+b)"是匹配的,但是"哈哈:)"就是不匹配的。利用栈,我们把暂时未匹配的前半边括号入栈,当读取到后半边括号且能与栈顶的前半边匹配时,栈顶弹出,完成一个匹配。最好如果栈空,则是匹配的,反之不匹配。代码很简单:
1 bool brace_match(const char* str) { 2 Stack<char> s; 3 for(int i = 0; str[i] != '