栈(stack)是一种以后进先出为顺序对对象进行添加或者删除的数据结构,是一种只允许在一端进行插入删除的线性表。可以把栈想象成桌子上的一堆书,可以在这堆书的顶部放上一本书就是入栈,或者把这堆书最顶部的一本书拿走就是出栈,但是你不能直接抽出来书堆中间的书,只能对书堆顶部一本书操作。
1、栈的数组实现
栈的数组实现相比链表容易多了,起码没有指向指针的指针了,实现起来压栈(入栈)无非是将新元素增加到栈顶,而弹栈(出栈)就是将栈顶的元素移除。那么我们需要一个数组来表示栈,还需要一个变量表示当前栈顶的位置。
可以给出栈的结构体
typedef struct STACK_KWEN{
int top; //栈顶指针
int *data; //存储空间
int capacity; //表示栈中最大存储长度
}STACK_KWEN;
有了结构体下一步就是初始化栈了,在初始化之前要进行一个有必要的判断,设置的长度是否超过了最大长度,以及小于等于0的长度等等。初始化栈主要就是:给结构体中的data分配指定长度的空间,初始化栈顶指针为-1,表示当前是一个空栈。
boolean initializeStack(STACK_KWEN **stackHead, int capacity) {
if(NULL == stackHead || capacity > MAX_SIZE || capacity <= 0 || NULL != *stackHead) {
return false;
}
*stackHead = (STACK_KWEN *)calloc(sizeof(STACK_KWEN), 1);
(*stackHead)->capacity = capacity;
(*stackHead)->top = -1;
(*stackHead)->data = (int *)calloc(sizeof(int), capacity);
if(NULL == (*stackHead)->data) { //表示没有分配到空间
free(*stackHead);
return false;
}
return true;
}
栈的销毁。由于栈里面真正存放数组部分是动态申请的,完了必须要手动释放掉,否则会造成野指针、内存泄漏的现象。没有什么逻辑可言,释放空间指针置为空即可。
void destoryStack(STACK_KWEN **stackHead) {
if(NULL == stackHead || NULL == *stackHead) {
return;
}
free((*stackHead)->data);
free(*stackHead);
*stackHead = NULL;
}
2、入栈
入栈前要判断栈是否满了,满了就不能再入栈了。
没满的话可以正常入栈入栈的时候应该先把栈顶指针往上移动一个单位,这里就是前置的++,再进行数组赋值。
boolean push(STACK_KWEN *stackHead, const int push_data) {
if(NULL == stackHead || isStackFull(stackHead)) {
//如果栈满 则返回 此时不能入栈
return false;
}
stackHead->data[++stackHead->top] = push_data;
return true;
}
3、出栈
出栈前则要判断栈是否空,栈都空了还拿什么出栈。
出栈的时候要先得到出栈的元素再往下移动栈顶指针,所以这里下标是后置--运算。
int pop(STACK_KWEN *stackHead) {
if(isStackEmpty(stackHead) || NULL == stackHead) {
return ERROR;
}
return stackHead->data[stackHead->top--];
}
在java中栈的数据结构还提供了一个方法peek( ),peek的意思是偷看,这个方法的功能是查看栈顶的元素,元素并不出栈,不移动栈顶指针。
简而言之就是查看当前栈顶的元素,前提这不是一个空栈,直接获得栈顶下标的数组元素即可。
const int readTop(STACK_KWEN *stackHead) {
if(isStackEmpty(stackHead) || NULL == stackHead) {
return ERROR;
}
return stackHead->data[stackHead->top];
}
所有的代码
#include<stdio.h>
#include<malloc.h>
#define MAX_SIZE 1000
typedef unsigned char boolean;
#define true 1
#define false 0
typedef struct STACK_KWEN{
int top; //栈顶指针
int *data; //存储空间
int capacity; //表示栈中最大存储长度
}STACK_KWEN;
boolean initializeStack(STACK_KWEN **stackHead, int capacity);
boolean push(STACK_KWEN *stackHead, const int push_data);
int pop(STACK_KWEN *stackHead);
void destoryStack(STACK_KWEN **stackHead);
boolean isStackFull(STACK_KWEN *stackHead);
boolean isStackEmpty(ST