一、定义
后进先出(或先进后出),就像羽毛球筒一样,具有倒序的特征。
二、相关概念
最早进入的元素叫栈底(bottom),最后进入的元素叫栈顶(top)。
出栈(pop):将结点从栈顶删除。
进栈(push):结点在栈顶位置输入。
空栈:栈中结点个数为零。
三、栈的运算
创建一个空的栈creat()
进栈push(x):使x成为栈顶元素
出栈pop():删除栈顶元素并返回其值
读栈顶元素top():返回栈顶元素值,但不删除栈顶元素
判栈是否为空isEmpty:若栈为空,返回ture,否则返回false
四、栈的顺序实现(数组方式)
数组前端作为栈顶
在push新的元素时需要将原来的元素全部往后移,复杂性为O(N),不建议使用。
2.栈顶为数组最后一个元素
五、顺序存储时的操作实现
create():按照用户申请的栈的规模申请一个动态数组,并将其数组地址保存在data中,数组规模保存在maxsize中,并设top_p(表示数组中栈顶元素的下标)的值为-1。
*为什么top_p的值一开始为-1?
因为数组第一个元素下标为0,如果是0的话表示一开始就有一个元素在栈里面了。
push(x):将top_p+1,将x放入top_p指向的位置,但要注意数组已满的情况。
类似的还有pop(返回值并将top_p减1)top(单纯返回值)和isEmpty(根据top_p的值返回true或者false)
六、顺序实现性能分析
所有运算实现的时间复杂度都是O(1)
例外:在栈满的时候进行进栈操作,此时时间复杂度为O(N),我们需要重新进行一个double space的操作,这个时间复杂度就是O(N)。
七、栈的链接实现(指针实现)
—不需要双链表,单链表就可以了
—不需要头结点
对栈来讲,只需要考虑栈顶元素的插入删除。
从栈的基本运算的实现方便性考虑,将单链表的头指针指向栈顶。
八、连接存储时的运算实现
create():将top_p(相当于head头指针)设为空指针
不需要先建立连续的空间,用多少拿多少。
push(x):将x插入到单链表的表头
void push(x){
p=new结点;
p->data=x;
p->next=top_p;
top_p=p;
}
在这个步骤中,我们还是要提前申请一个空间的,因为我们要在这个空间范围内设一个新的结点。
pop():删除栈顶元素
dataType pop(){
p=top_p;//p是一个新建的指针,此时指向栈顶元素
top_p=top_p->next;
x=p->data;
delete p;
return x;
}
top():返回栈顶元素
int top(){return top_p->data;}
isEmpty()
bool isEmpty(){return top_p==-1;}
九、栈的连接存储性能分析
所有操作复杂性均为O(1),不需要去搜索与查找