栈的实现:顺序栈

栈(stack)是一种很常见的线性结构。它是只允许在一端进行插入和删除操作的线性表,这一端我们称为栈顶。栈的特点常被称为:先进后出(filo-first int last out),或者是后进先出(lifo-last in first out)。这个描述从它的操作特点可以看出,只许在一端进行插入,那么显然,先进的肯定后出。栈的应用,比如系统应用栈来实现递归,图的深度遍历使用了栈,递归要用到栈……。说到它的实现就有两种形式:顺序栈、链栈。其中以顺序栈最为常见。

栈的常见操作:

  1. push() 入栈
  2. pop() 出栈
  3. top() 获取栈顶元素
  4. size() 获取栈的大小
  5. empty() 判断栈是否为空

看下图:

栈的实现:顺序栈_第1张图片

其中 base 是栈底指针,top是栈顶指针,我们会发现,top指向栈中元素的下一个位置。若top为0,则表明栈为空。

在代码中我们用stop(stack top)代替top,因为top指针和top()函数命名有冲突。

说明:

  1. 我们对栈设置一个初始的大小 STACKSIZE。
  2. 当栈满了,我们得扩充大小,每次增加 INCREMENT,并且把原栈中的元素赋值过去。
  3. 常见操作的名称设计参考STL,要想使用STL提供的栈,使用#include
  4. 栈的实现很多,不必要强调标准,根据实际问题特点设计即可。重点是,栈这种数据结构的特点的掌握。
  5. 栈为空时的判断,和栈为满时的判断,是重点。

类定义和类实现

#include
#include
using namespace std;
typedef int ElemType;    //栈中数据类型  
#define STACKSIZE 10     //栈的默认大小  
#define INCREMENT 10     //增量  
//顺序栈定义  
class SqStack    //sequential stack  
{  
private:  
    ElemType *base;    //栈底指针  
    int stop;  //栈顶指针 stack top  
public:  
    SqStack();    //默认构造函数  
    ~SqStack();   //析构函数  
    void clear();  //栈清空  
    void push(ElemType value);   //进栈  
    void pop();    //出栈  
    ElemType top();     //获取栈顶元素  
    int size();     //获取栈的大小  
    bool empty();       //栈是否为空  
    void stackTraverse(void(*)(ElemType));   //遍历栈  
};  
//栈实现  
SqStack::SqStack()   //构造函数,初始化栈,分配默认空间大小  
{  
    /* c的写法 
    base = (ElemType*)malloc(sizeof(ElemType)*STACKSIZE); 
    */  
    base = new ElemType[STACKSIZE];  
    stop = 0;  
}  
SqStack::~SqStack()   //析构函数  
{  
    delete[]base;  
}  
void SqStack::clear()  //栈清空  
{  
    stop = 0;  
}  
void SqStack::push(ElemType value)  
{  
    //入栈前先检查栈是否满了  
    if (stop != 0 && (stop - STACKSIZE) % INCREMENT == 0)   //栈满,则扩大空间  
    {  
        /* c的写法 
        base = (ElemType*)realloc(base, sizeof(stop + INCREMENT)); 
        */  
        ElemType *b = new ElemType[stop + INCREMENT];  
        for (int i = 0; i < stop; i++)  
            b[i] = base[i];  
        delete[]base;  
        base = b;  
    }  
    base[stop++] = value;  
}  
void SqStack::pop()    //出栈  
{  
    //出栈前检查栈是否为空  
    if (empty())  
        return;  
    stop--;  
}  
ElemType SqStack::top()  //获取栈定元素  
{  
    if (stop == 0)  
        return NULL;  
    return base[--stop];  
}  
int SqStack::size()  //获取栈的大小  
{  
    return stop;  
}  
bool SqStack::empty()    //判断栈是否为空  
{  
    return stop == 0;  
}  
void SqStack::stackTraverse(void (*visit)(ElemType item))  
{  
    int p = stop;  
    while (p >= 1)  
    {     
        p--;  
        visit(base[p]);  
    }  
    cout << endl;  
}  
void visit(ElemType item)  
{  
    cout << setw(4)<


主函数

int main()     //主函数
{
	printf("顺序栈的演练\n");
	SqStack stack;
	ElemType value;
	cout << "输入栈中元素,0结束" << endl;
	while (cin >> value && value != 0)
		stack.push(value);
	cout << "栈遍历" << endl;
	stack.stackTraverse(visit);
	cout << "删除栈顶元素" << endl;
	stack.pop();
	cout << "栈遍历" << endl;
	stack.stackTraverse(visit);
	cout << "获取栈顶元素 " << stack.top() << endl;
	cout << "清空栈操作:";
	stack.clear();
	stack.empty() ? cout << "栈空!" <> value && value != 0)
		stack.push(value);
	cout << "栈遍历" << endl;
	stack.stackTraverse(visit);
	system("pause");
	return 0;
}
运行

栈的实现:顺序栈_第2张图片


完整代码下载:栈的实现:顺序栈


尝试:用栈实现进制转换,这个很简单,可以动手试试。参考看一楼。


至于链栈的写法,就和链表差不多了。唯一区别在于:head指针这头是栈顶,有且只能在这头进行插入和删除操作。链表是可以在任何地方进行插入和删除操作的,链栈这里就显得更加easy了。


专栏目录:

  • 数据结构与算法目录
  • c指针


你可能感兴趣的:(数据结构与算法,数据结构与算法)