一、栈及顺序栈
1、栈
栈是限定仅在表尾进行插入和删除操作的线性表。因此,对于栈来说,表尾端具有特殊意义,称为栈顶,相应地,表头端称为栈底。不含元素的空表称为空栈。特点:后进先出。
2、顺序栈
顺序栈,即栈的顺序存取结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置。
二、顺序栈的基本操作
//创建空栈
sepstack_t *stack_create(void);
//判断是否为空栈
int stack_isempty(sepstack_t*S);
//清除栈内元素
void stack_clear(sepstack_t*S);
//判断栈是否需要扩容
int stack_isfull(sepstack_t*S);
//数据入栈
int stack_push(sepstack_t*S,data_t value);
//数据出栈
data_t stack_pop(sepstack_t*S);
//返回栈顶元素
data_t stack_top(sepstack_t*S);
//销毁栈
void stack_free(sepstack_t*S);
三、具体实现
1、创建空栈
因为栈在使用过程中所需最大空间的大小很难估计,因此,一般来说,初始化空栈时不应限定栈的最大容量。合理做法是:先为栈分配一个基础容量,然后在使用过程中,当栈的空间不够使用时再逐段扩大。
栈的数据类型:
#define Maxlen 100 //初始栈的最大值
#define Addsize 10 //每次扩容的量
typedef int data_t;
typedef struct {
data_t *data;
int maxlen;//当前栈的容量
int top;//栈顶
}sepstack_t;
初始化空栈:
sepstack_t *stack_create(void ){
sepstack_t *S;
S= malloc(sizeof(sepstack_t));
if(!S){
printf("malloc failed\n");
return NULL;
}
S->maxlen=Maxlen;
S->data= malloc(Maxlen* sizeof(data_t));
if(!S->data){
printf("malloc failed\n");
return NULL;
}
S->top=-1;
return S;
}
虚拟指针top指向栈顶元素的位置,栈中没有元素时,top等于-1.
2,判断是否为空栈
int stack_isempty(sepstack_t*S){
if(S->top==-1){
return 1;
}
return 0;
}
当top等于-1时,代表栈内无元素,即空栈。
3,清除栈内元素
void stack_clear(sepstack_t*S){
S->top=-1;
}
由于栈只在栈顶进行插入和删除操作,top指向栈顶元素,当top为-1时,代表栈内无元素。
4,判断栈是否需要扩容
int stack_isfull(sepstack_t*S){
if(S->top==S->maxlen-1){
data_t* p= realloc(S->data,(S->maxlen+Addsize)* sizeof(data_t));
if(p){
S->data=p;
S->maxlen+=Addsize;
printf("99");
}
}
return 0;
}
由于在C语言中,数组下标是从0开始的,当栈顶元素的位置下标top等于最大容量-1时,意味着当前栈已经满了,需要扩容,使用realloc函数。
5,数据入栈
int stack_push(sepstack_t*S,data_t value){
stack_isfull(S);
S->top=S->top+1;
S->data[S->top]=value;
return 1;
}
先判断当前栈是否已满,在进行数据入栈操作,避免越界。
6,数据出栈
data_t stack_pop(sepstack_t*S){
data_t tmp;
if(stack_isempty(S)){
printf("stack is empty\n");
return -1;
}
tmp=S->data[S->top];
S->top=S->top-1;
return tmp;
}
当栈内有数据时,才能出栈,所以要先判断是否为空栈。
7,返回栈顶元素
data_t stack_top(sepstack_t*S){
if(stack_isempty(S)){
printf("stack is empty\n");
return -1;
}
return S->data[S->top];
}
8,销毁栈
void stack_free(sepstack_t*S){
free(S->data);
S->data=NULL;
free(S);
S=NULL;
}
因为栈是动态开辟的内存,所以要进行free操作。free时要先释放动态开辟的数组,在释放结构体,一级一级的释放。