栈是一种后进先出(Last in First Out)的数据结构。
由于栈比较好理解,这里只附上用c实现栈的代码。
栈的链式储存
#include <stdio.h>
#include <stdlib.h>
#define SUCCEED 1
#define FAIL 0
#define TestNum 5
typedef int SElemType;
typedef int Status;
//栈的结点结构体
typedef struct StackNode {
SElemType data;
struct StackNode *next;
}StackNode,*LinkStackPtr;
//栈的结构体
typedef struct LinkStack{
LinkStackPtr top;
int count;
}LinkStack;
Status Push(LinkStack *S,SElemType data){
LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));
s->data = data;
s->next = S->top;
S->top = s;
S->count++;
return SUCCEED;
}
Status Pop(LinkStack *S,SElemType *e){
LinkStackPtr tmp;
if(S->count == 0) return FAIL;
*e = S->top->data;
tmp = S->top;
S->top = S->top->next;
S->count--;
free(tmp);
return SUCCEED;
}
int main(){
int i;
LinkStack test;
SElemType data[]={1,2,3,4,5};
SElemType topData;
printf("Push test\n");
for(i = 0 ; i < TestNum ; i++){
Push(&test, data[i]);
}
printf("The Count of this Stack is %d\n",test.count);
printf("Pop test\n");
for(i = 0 ; i < TestNum ; i++){
Pop(&test,&topData);
printf("The top Data is %d\n",topData);
printf("There are %d remain in Stack\n",test.count);
}
return 0;
}
栈的顺序储存
#include <stdio.h>
#include <stdlib.h>
#define SUCCEED 1
#define FAIL 0
#define TestNum 5
#define StackMax 1000 //该栈的最大size
typedef int SElemType;
typedef int Status;
//栈的结点结构体
typedef struct StackNode {
SElemType data;
}StackNode;
//栈的结构体
typedef struct LinkStack{
StackNode *Stack;
int top; //用来保存栈顶的系数
int count; //用来保存栈的大小
}LinkStack;
Status Push(LinkStack *S,SElemType data){
StackNode *stack;
stack = S->Stack;
S->top++; //更新头结点的位置
stack[S->top].data = data;
S->count ++;
return SUCCEED;
}
Status Pop(LinkStack *S,SElemType *e){
if(S->count == 0) return FAIL;
*e = S->Stack[S->top].data; //利用e传回栈顶的数据
S->top--;
S->count--;
return SUCCEED;
}
//初始化栈
Status initStack(LinkStack *S){
S->Stack = (StackNode*)malloc(sizeof(StackNode)*StackMax);
S->top = -1;
S->count = 0;
return SUCCEED;
}
int main(){
int i;
LinkStack test;
SElemType data[]={1,2,3,4,5};
SElemType topData;
initStack(&test); //初始化栈
printf("Push test\n");
for(i = 0 ; i < TestNum ; i++){
Push(&test, data[i]);
}
printf("The Count of this Stack is %d\n",test.count);
printf("Pop test\n");
for(i = 0 ; i < TestNum ; i++){
Pop(&test,&topData);
printf("The top Data is %d\n",topData);
printf("There are %d remain in Stack\n",test.count);
}
return 0;
}
聊聊个人对C语言中串行计算,函数调用,与栈之间的初步理解。
当调用函数时,被调用函数的参数和返回值被储存当前程序的栈区,之后被调用函数再为自身的自动变量和临时变量在栈区上分配空间。当函数调用返回时,在栈区内的参数返回值、自动变量和临时变量等都会被释放。
单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。C语言程序在运行是就是单线程串行计算。当遇到调用其他函数的时候,就会把当前的当前的参数传出去,运行的位置当前参数保存在栈顶,并开辟新的栈区(我是这么理解的)。调用的函数运行完毕,就返回之前的函数,并接着运行下去。
当遇到调用自己的情况(递归),就会将运行的位置和当前参数push进去,传参,当递归结束后一层层pop直到栈底。当递归次数过多就会overflow。