1)Stack的通用模板类的定义(模板属于c++多态的一部分,此外还有函数的重载,类的继承,虚函数等等)
//这个文件的名称stack.h
#ifndef STACK_H
#define STACK_H
template<typename valuename>
class Stack{
public:
Stack();
~Stack();
bool isEmpty();
void push(valuename v);
valuename pop();
valuename peek();
int size();
void clear();
private:
void expandCapacity();
valuename *array;
int capacity;
int length;
Stack(const Stack & value) { }
const Stack & operator=(const Stack & rhs) { return *this; }
};
#include "stack.cpp"
#endif // STACK_H
2)stack的指针数组实现方法
//stack.cpp为这个的文件名
#ifdef STACK_H
#include "util.h"
//#include "stack.h"
const int INITAL_SIZE = 9;
template<typename valuename>
Stack<valuename>::Stack(){
capacity = INITAL_SIZE;
array = (valuename *)malloc(capacity * sizeof(valuename));
length = 0;
}
template<typename valuename>
Stack<valuename>::~Stack(){
free(array);
}
template<typename valuename>
void Stack<valuename>::expandCapacity(){
capacity *= 2;
array = (valuename *)realloc(array, capacity);
}
template<typename valuename>
int Stack<valuename>::size(){
return length;
}
template<typename valuename>
void Stack<valuename>::push(valuename v){
if (length == capacity) expandCapacity();
array[length] = v;
length++;
}
template<typename valuename>
valuename Stack<valuename>::pop(){
if (length == 0)
error("there is no element to pop.");
length--;
return array[length];
}
template<typename valuename>
valuename Stack<valuename>::peek(){
if (length == 0)
error("there is no element to pop.");
return array[length - 1];
}
template<typename valuename>
void Stack<valuename>::clear(){
length = 0;
}
#endif
3)stack的链表的实现方法
//另外一种实现办法,文件名为stack.cpp,这个和上一个stack.cpp不可以一起用
//#include "stacklist.h"
#ifdef STACKLIST_H
#include <stdlib.h>
template<typename valuename>
Stacklist<valuename>::Stacklist(){
count = 0;
stack = NULL;
}
template<typename valuename>
Stacklist<valuename>::~Stacklist(){
clear();
}
template<typename valuename>
void Stacklist<valuename>::push(valuename v){
Cell * tem = (Cell *)malloc(sizeof(Cell));
tem->v = v;
tem->link = NULL;
if (count == 0){
stack = tem;
}
else{
Cell * it = stack;
while(stack->link != NULL){ stack = stack->link;}
stack->link = tem;
stack = it;
}
count++;
}
template<typename valuename>
valuename Stacklist<valuename>::pop(){
if (count == 0)
error("there is no element to pop.");
else if(count == 1){
valuename result = stack->v;
free(stack);
stack = NULL;
count--;
return result;
}
else{
Cell* it = stack;
for (int i = 0; i < count - 2; i++){
stack = stack->link;
}
valuename result = stack->link->v;
free(stack->link);
stack->link = NULL;
stack = it;
count--;
return result;
}
}
template<typename valuename>
void Stacklist<valuename>::clear(){
if (stack == NULL)
return;
Cell * tem;
while(stack->link != NULL){
tem = stack->link;
free(stack);
stack = tem;
}
free(stack);
stack = NULL;
count = 0;
}
template<typename valuename>
valuename Stacklist<valuename>::peek(){
if (stack == NULL)
error("there is no element to peek.");
Cell * tem = stack;
while(stack->link != NULL)
stack = stack->link;
valuename result = stack->v;
stack = tem;
return result;
}
template<typename valuename>
int Stacklist<valuename>::size(){
return count;
}
template<typename valuename>
bool Stacklist<valuename>::isEmpty(){
return count == 0;
}
#endif
通过这个模板类的实现,学习了很多东西。比如模板类的声明和实现必须在同一个文件下面。虽然这里表面上看起来是属于不同文件,其实是由于在stack.文件中有#include stack.cpp,这个使得在预编译的时候会是两个文件变成一个。这个stack.cpp中加了一个条件编译是由于有些编译器可能会提前编译源文件。链表实现和指针数组实现各自的优缺点不同,比如在使用指针数组实现push和pop操作比较快,但是这个方法可能会有空间浪费。而链表实现会使得pop和push的时间相对复杂度比较高O(N),但是不存在空闲的空间。