通常来说,决定采用何种方式来检索数据是非常重要的,这样便于以后对数据检索时,数据会按照何种的方式顺序输出。栈是用于检索数据的一种常用方式。
栈的一种显著的特征就是它按照后进先出(LIFO)的方式存储和删除数据元素。这就是说,最后一个存入栈中的元素将会被第一个删除。我们可以看下图的表示;
栈的实现方法有2种,一种是顺序栈,一种是链式栈;
下面先介绍下顺序栈的定义和实现(以前写过的代码):
#define N 8 typedef int datatype; typedef struct { datatype data[N]; int top; } seqstack; seqstack *CreateSeqstack() { seqstack *s; s = (seqstack *)malloc(sizeof(seqstack)); s->top = -1; return s; } int EmptySeqstack(seqstack *s) { return (-1 == s->top); } int FullSeqstack(seqstack *s) { return (N-1 == s->top); } void ClearSeqstack(seqstack *s) { s->top = -1; } void PushSeqstack(seqstack *s, datatype x) { s->data[++s->top] = x; return; } datatype PopSeqstack(seqstack *s) { return s->data[s->top--]; } datatype GetTop(seqstack *s) { return s->data[s->top]; } int main() { int i; seqstack *s; s = CreateSeqstack(); for (i=1; i<=10; i++) { if ( ! FullSeqstack(s) ) PushSeqstack(s, i); else printf("stack is full\n"); } while ( ! EmptySeqstack(s) ) { printf("%d ", PopSeqstack(s)); } printf("\n"); return 0; }
链式栈的定义和实现:
前面已经对单链表的实现进行分析过程可以参照博客中单链表部分,栈的结构体的定义和链表是一样的,在初始化和销毁可以直接调用单链表的实现方法。这种方法是栈具有多态性。多态是面向对象的一种特性,她允许某种类型的对象或者变量在使用时用其他的类型的对象进行代理。这就说,除了使用栈本身的操作完,还可以使用链表的操作。这是因为栈本身就是一种链表,它和链表有相同的特性,很多时候可以像链表一样使用它。
下面是链式栈的定义和实现的过程,
/*stack.h*/
#ifndef STACK_H
#define STACK_H
#include <stdlib.h>
#include "list.h"
typedef List Stack;
#define stack_init list_init
#define stack_destroy list_destory
int stack_push(Stack *stack, const void *data);
int stack_pop(Stack *stack,void *data);
#define stack_peek(stack) ((stack)->head == NULL ? NULL:(stack)->head->data)
#define stack_size list_size
#endif
/*stack.c*/ #include <stblib.h> #include "../include/list.h" #include "../include/stack.h" /*stack_push */ int stack_push(Stack * stack, const void * data) { return list_ins_next(stack, NULL, const void * data) } /*stack_pop*/ int stack_pop(Stack * stack, void * data) { return list_rem_next(stack, NULL, void * data) }