写过了链式栈,我也提到了,有两种写栈的方法,剩下的就是数组栈
数组可用于实现(有界)堆栈,如下所示。第一个元素(通常在零点偏移处)是底部,导致数组[0]成为被推到堆栈上的第一个元素,最后一个元素弹出。程序必须跟踪堆栈的大小(长度),使用一个可变的顶部记录到目前为止推送的项目数,从而指向数组中下一个元素要插入的位置(假设从零开始的索引约定)。因此,堆栈本身可以有效地实现为三元素结构。
我们先看一些书上实现的数组栈:
struct mystack {
int* stackme;//整形指针用来开辟数组
int top;
};
struct mystack* createstack() {
struct mystack* pstack = (struct mystack*)malloc(sizeof(struct mystack));//分配结构体内存
pstack->stackme = (int*)malloc(MAX * sizeof(int));//分配数组内存
pstack->top = -1;//整形元素做下标做指向栈顶的指针,初始化为-1,这样压入元素的时候加一正好指向0
}
初始化我写好了
下面是压入栈元素:
void push(struct mystack* pstack, int data) {
if (pstack->top + 1 == MAX) {
printf("栈满了无法入栈\n");//数组栈是有栈满的情况的
return;
}
pstack->stackme[++pstack->top] = data;//先加下标,对栈顶做改变,自加的下标往上移动实现压栈
}
下面的出栈,很多书和网站上写的都是合二为一,参数传入一个一级指针方便存取
void pop(struct mystack* pstack, int* data) {
if (pstack->top == -1) {
printf("栈为空,无法出栈");
return;
}
*data=pstack->stackme[pstack->top--];//先出后减
}
下面就是我的链式表博客讲到的主程序:(实现一样的功能)
int main() {
struct mystack* s = createstack();
push(s, 2);
push(s, 3);
push(s, 4);
while (s->top != -1) {
int i;
pop(s, &i);
printf("%d\t", i);
}
//问题:转换十进制数2222成二进制数
struct mystack* ss = createstack();
int num = 2222;
while (num) {
push(ss, num % 2);
num /= 2;
}
while (ss->top != -1) {
int i;
pop(ss, &i);
printf("%d", i);
}
}
有时候可以看到,栈满的情况,那是因为MAX的设置,这个栈是有限的,所以有的是容不下的
这上面的当然是不够实用
我来写一个更实用的(实际开发什么的,都还是这个方便)
可以看到这个实现方法还是调用了数组,我们何不必设置个自然数组呢,很明显,自然数组来实现是非常好用的
int main() {
int stack[MAX];
int top = -1;//栈的初始化就完成了
//入栈:
stack[++top] = 2;
stack[++top] = 3;
stack[++top] = 4;
//读取出栈元素
while (top != -1) {
printf("%d\t", stack[top--]);
}
printf("\n");
//问题:转换十进制数2222成二进制
int stack2[MAX];
int top2=-1;
int num = 2222;
while (num) {
stack2[++top2] = num % 2;
num /= 2;
}
while (top2 != -1) {
printf("%d", stack2[top2--]);
}
}
数组栈的删除元素是一种伪删除的方法,它数据还在,但是只是下标移动了
个人觉得,数据结构,不管你实现的方式是什么,只要是这个功能,那就是这个数据结构,只要能运用,那么就是好的数据结构工程师,灵活运用各种数据结构,这才是我们的目标啊,不要死板硬套
OK 栈的东西我写完了,下期带来用栈寻路!