一步一步复习数据结构和算法基础-栈的简单应用(1)

来源:互联网 发布:关系数据库的基本结构 编辑:程序博客网 时间:2024/05/22 01:29

  栈的特点之一是FILO(先进后出),基于这个特点在这里给出栈的部分基础应用:

1:括号匹配;

  所谓的括号匹配就是一个表达式中包括变量、常量、操作符、圆括号,圆括号可以嵌套, 编写程序判断表达式中的括号是否正确匹配。输入任意一个表达式,判断其中括号是否匹配。

  利用栈的特性可以很简单的解决这个问题,对于一个表达式从第一个字符开始处理,如果遇到左括号就入站,如果遇到右括号就与栈顶元素匹配,如果右括号与栈顶元素无法匹配那么程序可以终止。因为很显然这个表达式的括号不匹配。而且程序的开始和结束时,括号匹配的表达式所对应的栈是空的。

例如《《(》》》

还有《《《》》

下面给出函数代码:

void Match(SqStack *s){char ch;while((ch = getchar()) != '\n'){switch (ch){case '(': Push(s,ch);break;case '<': Push(s,ch);break;case '[': Push(s,ch);break;case '{': Push(s,ch);break;case ')': if(GetTop(s) == '('){Pop(s);break;}  else{printf("括号不匹配.\n");return;}case '>': if(GetTop(s) == '<'){Pop(s);break;}  else  {printf("括号不匹配.\n");return;}case ']': if(GetTop(s) == '['){Pop(s);break;}  else  {printf("括号不匹配。\n");return;}case '}': if(GetTop(s) == '{'){Pop(s);break;}  else  {printf("括号不匹配。\n");return;}}}if (IsEmpty(s))printf("括号不匹配。\n");elseprintf("括号匹配.\n");}


这个函数可以处理的括号有四种< ( [ {}])>

里面有关于栈的函数在前面已经写过,这里还是把程序的完整代码贴出来好一些:

#include <stdio.h>#include <stdlib.h>#define STACK_INIT_SIZE 100//栈空间的初始分配量#define STACKINCREMENT 10//存储空间的分配增量typedef char SElemType;typedef struct{SElemType *base;//在构造栈之前和销毁栈之后,base的数值为NULLSElemType *top;//栈顶指针int stacksize;//显示栈当前的容量}SqStack;//创建一个空栈int InitStack(SqStack *s);//销毁栈int DestroyStack(SqStack *s);//清空栈int ClearStack(SqStack *s);//判断栈是否为空栈int StackEmpty(SqStack *s);//计算栈的长度int StackLength(SqStack *s);//获取栈顶元素int GetTop(SqStack *s);//将一个元素推入站内int Push(SqStack *s,SElemType data);//将一个元素退出栈int Pop(SqStack *s);//对于栈内的每一个元素调用函数int StackTraverse(SqStack *s);int InitStack(SqStack *s){s->base = (SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE);//为栈分配基础空间if(!s->base)exit(1);//分配失败的话就退出s->top = s->base;//栈顶指针指向栈底s->stacksize = STACK_INIT_SIZE;//初始化栈的大小return 1;}int Push(SqStack *s,SElemType data){if(s->top-s->base >= s->stacksize)//如果栈的空间不够再增加{s->base = (SElemType *)realloc(s->base,(s->stacksize + STACKINCREMENT)*sizeof(SElemType));if(!s->base)exit(1);//在原来空间的基础上额外增加空间s->top = s->base + s->stacksize;//栈顶指针加1s->stacksize += STACKINCREMENT;//栈大小增加}*s->top++ = data;//元素入栈,栈顶指针加1return 1;//入栈成功}int Pop(SqStack *s){if(s->base == s->top) return 0;//如果栈为空栈返回出栈失败(*--s->top);//栈顶指针减1return 1;//出栈成功}int GetTop(SqStack *s){if(s->base == s->top)return 0;//空栈返回失败return *(s->top-1); //返回栈顶元素}int StackLength(SqStack *s){SElemType *tmp = s->top;//设置临时变量和栈顶指针相同int flag = 0;while(tmp != s->base)//栈顶指针逐个减1知道栈底{flag ++;tmp--;}return flag;//返回栈的长度}int DestroyStack(SqStack *s){free(s->base);//释放掉栈的分配空间s->base = s->top = NULL;//栈顶和栈底指向NULLs->stacksize = 0;//栈的长度还原为0return 1;}int ClearStack(SqStack *s){s->top = s->base;//栈清空最方便只需要将栈顶指针指向栈底return 1;}int StackTraverse(SqStack *s){SElemType *tmp = (s->top-1);if(s->top == s->base)return 0;while(1){printf("%d ",*tmp);if(tmp == s->base) break;//这个地方我刚刚犯了一个错误就是忽视栈底base指针指向的区域也有一个数据tmp--;}return 1;}int IsEmpty(SqStack *s){if(s->base == s->top)return 0;else return 1;}void Match(SqStack *s){char ch;while((ch = getchar()) != '\n'){switch (ch){case '(': Push(s,ch);break;case '<': Push(s,ch);break;case '[': Push(s,ch);break;case '{': Push(s,ch);break;case ')': if(GetTop(s) == '('){Pop(s);break;}  else{printf("括号不匹配.\n");return;}case '>': if(GetTop(s) == '<'){Pop(s);break;}  else  {printf("括号不匹配.\n");return;}case ']': if(GetTop(s) == '['){Pop(s);break;}  else  {printf("括号不匹配。\n");return;}case '}': if(GetTop(s) == '{'){Pop(s);break;}  else  {printf("括号不匹配。\n");return;}}}if (IsEmpty(s))printf("括号不匹配。\n");elseprintf("括号匹配.\n");}int main(){SqStack s;//初始化栈并且创建栈InitStack(&s);Match(&s);//清空栈ClearStack(&s);//销毁栈DestroyStack(&s);return 0;}




原创粉丝点击