当前位置:   article > 正文

数据结构(栈)_数据结构栈

数据结构栈

目录

栈的定义

 形象比喻

栈的相关术语 

 栈的抽象数据类型(栈Stack的ADT)

顺序栈 

顺序栈类的声明

 顺序栈类成员函数的实现

基本效率分析

顺序栈的应用(小测试)

 main.cpp

共享栈

双共享栈 

链式栈 

 链式栈基本操作分析

链式栈类的声明

链式栈基本操作的实现

小结


栈的定义

如果元素到达线性结构的时间越晚,离开的时间就越早,这种线性结构称为栈(Stack)或堆栈

因为元素之间的关系是由到达、离开的时间决定的,因此栈通常被称为时间有序表。

而到达和离开的含义就是插入和删除操作,因此栈可以看作是插入和删除操作位置受限的线性表。

 形象比喻

 乒乓球盒的进球和出球,它遵循了最后进盒的球反而最先出盒,即所谓的后进先出(LIFO, Last In First Out)或先进后出(FILO, First In Last Out)结构。

 

栈的相关术语 

栈的首部(元素最早到达的部分)称为栈底(bottom) ,栈结构的尾部(元素最晚到达的部分)称为栈顶(top)

为了保证栈的先进后出或后进先出的特点,元素的插入和删除操作都必须在栈顶进行。元素从栈顶删除的行为,称为出栈或者弹栈操作(pop); 元素在栈顶位置插入的行为,称为进栈或者压栈操作(push)。

读取栈顶元素数据值的操作,称为取栈顶内容操作(top)。

当栈中元素个数为零时,称为空栈

 栈的抽象数据类型(栈Stack的ADT)

Data: { xi | xiÎ ElemSet, i=1,2,3,……n, n > 0} 或 Φ; ElemSet为元素集合。

Relation: {<xi,xi+1>|xi,xi+1ÎElemSet, i=1,2,3,……n-1}, x1为栈底,xn为栈顶。

Operations:

操作前提结果
initialize栈初始化为一个空栈。
isEmpty栈Stack空返回true,否则返回false。
isFull栈Stack满返回true,否则返回false。
top栈Stack非空。返回栈顶元素的值,栈顶元素不变。
push栈Stack非满,已知待插入的元素。将该元素压栈,使其成为新的栈顶元素。
pop栈Stack非空。将栈顶元素弹栈,该元素不再成为栈顶元素。
destroy释放栈Stack占用的所有空间。

顺序栈 

 栈的顺序存储即使用连续的空间存储栈中的元素。可以将栈底放在数组的0下标位置,进栈和出栈总是在栈的同一端(栈顶)进行,顺序方式存储的栈称为顺序栈

 

栈空标志:top=-1

栈满标志:top=maxSize-1

bottom对应的永远是0,而top对应的是可变的。

顺序栈类的声明

 顺序栈的描述:数组指针array,数组大小maxSize,栈顶下标Top。

  1. class illegalSize{};
  2. class outOfBound{};
  3.  
  4. template <class elemType>
  5. class seqStack
  6. { private:
  7. elemType *array; //栈存储数组,存放实际的数据元素。
  8. int Top; //栈顶下标。
  9. int maxSize; //栈中最多能存放的元素个数。
  10. void doubleSpace();
  11. public:
  12. seqStack(int initSize = 100); //初始化顺序栈
  13. bool isEmpty () { return ( Top == -1 ); } ; //栈空返回true,否则返回false。
  14. bool isFull () { return (Top == maxSize-1); };//栈满返回true,否则返回false。
  15. elemType top ();// 返回栈顶元素的值,不改变栈顶
  16. void push (const elemType &e );//将元素e压入栈顶,使其成为新的栈顶。
  17. void pop (); //将栈顶元素弹栈。
  18. ~seqStack(){ delete []array;}; //释放栈占用的动态数组
  19. };

 顺序栈类成员函数的实现

  1. template <class elemType>
  2. seqStack<elemType>::seqStack(int initSize)//初始化顺序栈
  3. { array = new elemType[initSize];
  4. if (!array) throw illegalSize();
  5. Top=-1; maxSize=initSize;
  6. }
  7. template <class elemType>
  8. elemType seqStack<elemType>::top ()// 返回栈顶元素的值,不改变栈顶
  9. { if (isEmpty()) throw outOfBound();
  10. return array[Top];
  11. }
  12. template <class elemType>
  13. void seqStack<elemType>::push(const elemType &e )
  14. //将元素e压入栈顶,使其成为新的栈顶元素。
  15. { if (isFull()) doubleSpace();
  16. //栈满时从新分配2倍的空间,并将原空间内容拷入
  17. array[++Top] = e; // 新结点放入新的栈顶位置。
  18. }
  19. template <class elemType>
  20. void seqStack<elemType>::pop()//将栈顶元素弹栈。
  21. { if (Top==-1) throw outOfBound();
  22. Top--;
  23. }

基本效率分析

函数initialize(seqStack)、isEmpty、isFull、top、pop、destroy(~seqStack)的时间复杂度均为O(1)。

push因某时可能扩大空间,造成O(n)时间消耗,但按照“分期付款式”法,分摊到单次的插入操作,时间复杂度仍为O(1)。

顺序栈的应用(小测试)

编写程序从键盘上依次输入一串字符(以回车键结束)。要求将该串字符按照输入顺序的逆序在屏幕上输出。

在程序中可以建立一个顺序栈,将输入的字符依次入栈,最后再依次出栈,便能得到逆序结果。 

 main.cpp

  1. #include <iostream>
  2. #include "seqStack.h"
  3. using namespace std;
  4.  int main()
  5. { // 声明一个栈。
  6. seqStack<char> s;
  7. char ctemp;
  8. //从键盘输入若干字符(结束用回车),
  9. //依照输入次序分别进栈
  10. cout<<"Input the elements," <<press enter to an end: ";
  11. ctemp = cin.get();
  12. while ( ctemp!='\n')
  13. { s.push(ctemp); ctemp = cin.get(); }
  14. //将栈中的结点逐个出栈,并输出到屏幕上。
  15. cout<<"output the elements in the stack one by one:";
  16. while (!s.isEmpty())
  17. {
  18. ctemp = s.top();
  19. s.pop();
  20. cout<<ctemp;
  21. cout<<endl;
  22. return 0;
  23. }

共享栈

在实际应用中,有时需要同时使用多个数据类型相同的栈。

栈中的元素个数因进栈、出栈操作动态地变化,所有栈不一定同时达到栈满,有时一些栈满而另一些栈尚余空间。

为了提高空间使用率,可以在同一块连续的空间中设置多个栈。

多个栈间共享空间,这些栈称为“共享栈”

共享栈的特点是每个栈拥有一个连续的小空间, 所有共享栈拥有一个大的连续空间。

 

 top指向实际栈顶的后一个位置

假设有m个栈,第i个栈空的条件:top[i]=bottom[i];

第i个栈栈满条件为:    当i<m-1时,top[i]=bottom[i+1];

                                   当i=m-1时,top[i]=maxSize。

双共享栈 

 可以将两个栈相向设置,即两个栈的栈底分别设置在连续空间的两个端点。

栈空的条件top[i]=bottom[i], i=0或1,两个栈不一定同时为空;

栈满的条件top[0]=top[1],即两个栈当中只剩下一个空位置的时候栈满,两个栈必定同时栈满。

链式栈 

 用不连续的空间和附加指针来存储元素及元素间的关系。

栈顶指针top指向处于栈顶的结点,即单链表中的首结点。

 

 链式栈基本操作分析

进栈操作push的实现,按照以下操作顺序:

1)申请新的结点空间,data字段为进栈元素值,next字段指向首结点。

2)栈顶指向新结点。

出栈操作pop的实现,按照以下操作顺序:

1)   记住栈顶结点的地址。

2)将原栈顶的直接后继设为新的栈顶。

3)释放原来栈顶结点空间。

链式栈类的声明

  1. class outOfBound{};
  2. template <class elemType>
  3. class linkStack;
  4. template <class elemType>
  5. class Node
  6. { friend class linkStack<elemType>;
  7. private:
  8. elemType data;
  9. Node *next;
  10. public:
  11. Node(){next = NULL;}
  12. Node(const elemType &x, Node *p=NULL)
  13. { data = x; next = p; }
  14. };
  15. template <class elemType>
  16. class linkStack
  17. {
  18. private:
  19. Node<elemType> *Top;
  20. public:
  21. linkStack(){ Top = NULL; }; //初始化栈,使其为空栈
  22. bool isEmpty(){ return (Top==NULL); }; //栈为空返回true,否则返回false。
  23. bool isFull(){ return false; }; //栈满true,否则false。结点空间不连续,故总能满足
  24. elemType top();
  25. void push(const elemType &e);
  26. void pop();
  27. ~linkStack();
  28. };

链式栈基本操作的实现

  1. template <class elemType>
  2. elemType linkStack<elemType>::top()
  3. {
  4. if (!Top) throw outOfBound();//栈空
  5. return Top->data;
  6. }
  7.  
  8. template <class elemType>
  9. void linkStack<elemType>::push(const elemType &e)
  10. { Top = new Node<elemType>(e, Top); }
  11. template <class elemType>
  12. void linkStack<elemType>::pop()
  13. {
  14. Node<elemType> *tmp;
  15. if (!Top) throw outOfBound();//栈空
  16.  
  17. tmp = Top; //用tmp记住原栈顶结点空间,用于弹栈后的空间释放
  18. Top = Top->next; //实际将栈顶结点弹出栈
  19.  
  20. delete tmp;//释放原栈顶结点空间
  21. }
  22. template <class elemType>
  23. linkStack<elemType>::~linkStack()
  24. {
  25. Node<elemType> *tmp;
  26. while (Top)
  27. {
  28. tmp = Top;
  29. Top=Top->next;
  30. delete tmp;
  31. }
  32. }
函数将 栈中的所有结点清除 空间回收, 时间 复杂度为 O(n )
构造 函数、 isEmpty isFull top push pop 的时间复杂 度均 O(1)

小结

Ø 栈虽然只是在线性表操作基础上限制了插入、删除的位置,使得插入、删除操作只能在表的同一个端点进行,可以看作是一种操作受限的线性表
Ø 栈在 计算机系统中是 一种非常重要的数据结构。 除了介绍 的符号匹配、表达式计算,系统在函数调用、递归中都是以栈结构为基础
Ø 有着非常独特的一组常见操作:进栈、出栈、求栈顶元素、判栈空、判栈满等
Ø 物理实现上虽然可以有顺序和链式两种存储方式,鉴于其操作都在一端进行,顺序存储是栈最常使用的存储方式
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/589336
推荐阅读
相关标签
  

闽ICP备14008679号