堆栈也是一种线性表,一种操作受限的线性表,只能在栈顶插入/删除数据元素。数据的存储结构是逻辑结构用计算机语言的实现。顺序栈应用举例:利用顺序栈的基本操作,将元素A、B、C、D、E、F依次进栈,然后将F和E出栈,再将G和H进栈,最后将元素全部出栈,并依次输出出栈元素
我们来了解一下函数入栈,和出栈 流程图: 上面流程中有个问题,栈上的数据,是由main(主调函数)释放,还是由func函数(被调函数)管理释放?。 我们可以先看一下释放流程 从上面图来看释放流程从下往上释放。 函数调用惯例 调用惯例的什么意思呢?我们函数中定义的函数参数列表是在栈中先创建a前面的,还是先创建后面的...
void pop(stack *s,int *e)//出栈 { if(s->base == s->top)//如果出栈完则报错 printf("ERROR!\n"); else { s->top --; *e = *s->top; s->len--; } } 出栈的时候首先检查栈是否为空,如果为空则报错。如果不为空,则将栈顶指针减一(栈顶指针我这里是指向待入栈的空间,所以出栈的时...
int data ; struct Node * pNext; }*PNODE ,NODE ; typedef struct stack { PNODE pTop; PNODE pBottom; }*PSTACK ,STACK; void init(PSTACK pS); void push(PSTACK pS,int val); void show(PSTACK pS); bool is_empty(PSTACK pS); bool pop(PSTACK pS,int * pVal); void clear(PSTACK pS); ...
函数使用默认的调用惯例 cdecl,即参数从右到左入栈,由调用方负责将参数出栈。函数的进栈出栈过程如下图所示: 2|0函数进栈分析 步骤①到⑥是函数进栈过程: main() 是主函数,也需要进栈,如步骤①所示。 在步骤②中,执行语句func(90, 26);,先将实参 90、26 压入栈中,再将返回地址压入栈中,这些工作都由...
2- 出栈 出栈的方法跟我之前说的差不多,只不过出栈代码上需要做判断。int StackPop(struct Stack *stack,int *data){ struct List *tmp = NULL; if(IsStackEmpty(stack)) return -1; tmp = stack->head->next; *data = tmp->data; stack->head->next = tmp->next; stack->size--; free(tmp)...
在main 函数中,首先通过调用 initStack 初始化了一个栈 stack,然后通过调用 push 将元素压入栈中,再通过调用 printStack 打印栈中的元素。接着,通过调用 pop 函数将栈顶元素出栈,并打印出栈的元素值。最后,通过调用 peek 函数获取栈顶元素值,并打印栈顶元素。
//出栈 void Pop_SeqStack(SeqStack* stack); // 判断是否为空 int IsEmpty(SeqStack* stack); //返回栈中元素个数 int Size_SeqStack(SeqStack* stack); //清空栈 void Clear_SeqStack(SeqStack* stack); // 销毁栈 void Free_SeqStack(SeqStack* stack); ...
今天介绍的环境是VS2019,如果有朋友电脑上有安装VS2013、VS2010甚至是VC6.0的话,能够更加容易学习和观察函数栈帧的创建与销毁这一过程。 在不同的编译器下,这个过程会略有差异,具体的细节是取决于编译器的实现。我们只需要通过这一篇内容学习到这个过程实现的逻辑就OK了。接下来我们就开始进入正题吧!
1.2.6 出栈 出栈就太简单了。 我们只需要让top--就行了,以后再插入新数据的时候,会覆盖掉原来的值,不会产生任何影响。 当然,这里要注意进行一个判断assert(!StackEmpty(ps));(这个函数我们马上就会实现,栈为空返回真,不空返回假),如果栈为空,就不能再出栈元素了。