栈的基本算法
一、简单介绍
栈是限定在表尾插入或删除操作的线性表。因此,对栈来说,表尾端有其特殊的含义,成为栈顶(top),相应地,表头端称为栈底(bottom)。
不含元素的空表称为空栈。栈的修改是按照后进先出的原则进行的,因此,栈又称为后进先出的线性表。
二、栈示意图
三、基本操作
1、栈的初始化: InitStack(&S)
2、栈顶元素插入: Push(&S, &e)
3、栈顶元素获取: GetTop(&S, &e)
4、栈顶元素删除: Pop(&S, &e)
5、栈的长度: StackLength(S)
6、栈的判空: StackEmpty(S)
7、栈元素的访问: StackTraverse(S, visit())
8、栈的清空: ClearStack(&S)
9、栈的销毁: DestroyStack(&S)
四、栈顺序存储的实现
//---------- 栈的顺序存储表示 --------- #define STACK_INIT_SIZE 100; //存储空间初始分配量 #define STACKINCREMENT 10; //存储空间分配增量 typedef struct { SElemType *base; //在栈构造之前和销毁之后,base的值为NULL SElemType *top; //栈顶指针 int stacksize; //当前已分配的存储空间,以元素为单位 }SqStack;
//---------- 基本操作的函数原型声明 -------- Status InitStack(SqStack &S); //构造一个空栈S Status DestroyStack(SqStack &S); //销毁栈S,S不再存在 Status ClearStack(SqStack &S); //把S置为空栈 Status StackEmpty(SqStack &S); //若栈S为空栈,则返回TRUE,否则返回FALSE int StackLength(SqStack &S); //返回S的元素个数,即栈的长度 Status GetTop(SqStack &S, SElemType &e); //若栈S不空,则用e返回S的栈顶元素,并返回OK,否则返回ERROR Status Push(SqStack &S, SElemType &e); //插入元素e为新的栈顶元素 Status Pop(SqStack &S, SElemType &e); //若栈S不空,则删除S的栈顶元素e,用e返回其值,返回OK,否则返回ERROR Status StackTraverse(S, visit(SElemType e)); //从栈顶到栈顶依次对每一个元素调用函数visit()。一旦visit()失败,则操作失败
//---------- 基本操作的算法描述 -------- Status InitStack(SqStack &S){ S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)) if(!S.base) exit(OVERFLOW); //存储分配失败 S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK; } Status DestroyStack(SqStack &S){ free(S.base); S.base = NULL; S.top = NULL; S.stacksize = 0; return OK; } Status ClearStack(SqStack &S){ S.top = S.base; return OK; } Status StackEmpty(SqStack &S){ if(S.top == S.base) return TRUE; return FALSE; } int StackLength(SqStack &S){ return S.top - S.base; } Status GetTop(SqStack &S, SElemType &e){ if(S.top == S.base) return ERROR; e = *(S.top - 1); return OK; } Status Push(SqStack &S, SElemType &e){ if(S.top - S.base >= S.stacksize){ //栈满,追加存储空间 S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType)); if(!S.base) exit(OVERFLOW); //存储分配失败 S.top = S.base + S.stacksize; S.stacksize += STACKINCREMENT; } * S.top++ = e; return OK; } Status Pop(SqStack &S, SElemType &e){ if(S.top == S.base) return ERROR; e = * --S.top; return OK; } Status StackTraverse(S, visit()){
SElemType *base2 = S.base; while(S.top > S.base2) visit(*S.base2++); return OK; } Status visit(SElemType e) { printf("%d ", e); return OK; }
五、代码实现
// // main.c // EEs // // Created by 夏远全 on 2019/9/1. // Copyright © 2019 北京一米蓝科技有限公司. All rights reserved. // #include <stdio.h> #include <stdlib.h> #include <sys/malloc.h> #include <string.h> #include <stdio.h> #define STACK_OVERFLOW -1 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int SElemType; typedef int status; typedef struct sqstack { SElemType *base; SElemType *top; int stacksize; }SqStack; status Initstack(SqStack *s); status Destorystack(SqStack *s); status Clearstack(SqStack *s); status StackEmpty(SqStack *s); int StackLength(SqStack *s); status GetTop(SqStack *s, SElemType *e); status Push(SqStack *s, SElemType *e); status Pop(SqStack *s, SElemType *e); status StackTraverse(SqStack *s, status(*visit)(SElemType e)); status visit(SElemType e); int main(int argc, const char * argv[]) { SElemType i; SElemType e = 0; SqStack s; if(Initstack(&s) == OK){ for(i = 1; i <= 20; i++){ Push(&s,&i); } } printf("栈中的元素依次为:"); StackTraverse(&s,visit); Pop(&s, &e); GetTop(&s, &e); StackEmpty(&s); StackLength(&s); Clearstack(&s); StackEmpty(&s); Destorystack(&s); return 0; } status Initstack(SqStack *s) { s->base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!s->base) return STACK_OVERFLOW; s->top = s->base; s->stacksize = STACK_INIT_SIZE; return OK; } status Push(SqStack *s, SElemType *e) { if (s->top - s->base >= s->stacksize) { //栈满 ,追加空间 s->base = (SElemType *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElemType)); if (!s->base) exit(0); s->top = s->base + s->stacksize; // 设置栈顶 s->stacksize = s->stacksize + STACKINCREMENT; // 设置栈的最大容量 } *(s->top) = *e; s->top ++; return OK; } status Pop(SqStack *s, SElemType *e) { if(&s->top == &s->base) return ERROR; s->top --; *e = *(s->top); printf("弹出的栈顶元素 e=%d\n", *e); return OK; } status StackTraverse(SqStack *s, status(*visit)(SElemType e)) { SElemType *base2 = s->base; while(s->top > base2){ visit(*(base2++)); } printf("\n"); return OK; } status visit(SElemType e) { printf("%d ", e); return OK; } status StackEmpty(SqStack *s) { if(s->top == s->base) { printf("栈的状态:栈空\n"); return TRUE; } else{ printf("栈的状态:栈非空\n"); return FALSE; } } int StackLength(SqStack *s) { int len = (int)(s->top - s->base); printf("栈的长度:len=%d\n", len); return 0; } status GetTop(SqStack *s, SElemType *e) { if(&s->top == &s->base) return ERROR; e = (s->top-1); printf("当前栈顶元素:e=%d\n", *e); return OK; } status Clearstack(SqStack *s) { s->top = s->base; return OK; } status Destorystack(SqStack *s) { s->base = s->top = NULL; s->stacksize = 0; free(s->base); printf("栈被销毁:top = %d, base= %d, stacksize = %u\n",s->top,s->base,s->stacksize); return OK; }
六、打印结果
栈中的元素依次为:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 弹出的栈顶元素 e=20 当前栈顶元素:e=19 栈的状态:栈非空 栈的长度:len=19 栈的状态:栈空 栈被销毁:top = 0, base= 0, stacksize = 0 Program ended with exit code: 0
程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!