1.栈的概念
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
2.栈的特性:"先进后出,后进先出"。
(1)顺序栈代码:
/*顺序栈*/ #include<bits/stdc++.h> using namespace std; typedef struct snode { int data[105]; int top; }SeqStack; void Init(SeqStack *s) //置空栈 { s->top=-1; } int EmptyStack(SeqStack *s) //判断栈是否为空 { if(s->top<0) return 1; //为空返回1 else return 0; } int Push(SeqStack *s,int x) //将x进栈 { if(s->top>=105) { printf("overflow!\n"); return 0; } s->top++; s->data[s->top]=x; return 1; } int Pop(SeqStack *s) //出栈 { int x; if(s->top<0) { printf("underflow!\n"); return 0; } x=s->data[s->top]; s->top--; return x; } int GetTop(SeqStack *s) //取栈顶元素 { if(s->top<0) { printf("underflow!\n"); exit(0); } return(s->data[s->top]); } int main() { SeqStack *s; s=(SeqStack *)malloc(sizeof(SeqStack)); s->top=-1; for(int i=1;i<=10;i++) { Push(s,i); } printf("栈顶元素%d\n",GetTop(s)); printf("出栈:\n"); for(int i=1;i<=10;i++) { printf("%d ",Pop(s)); } }
(2)链式栈:
#include <stdio.h> #include <stdlib.h> #define Empty 0 /* 栈空 */ #define Avail 1 /* 栈可用 */ typedef struct SNode { int data; struct SNode *next; }StackNode; typedef struct LStack { StackNode *top; /* 栈顶指针 */ StackNode *bottom; /* 栈底指针 */ int height; /* 链式栈高度 */ }LinkStack; LinkStack InitStack (LinkStack pStack); /* 栈顶指针、栈底指针、栈高度初始化*/ LinkStack Push (LinkStack pStack); /* 入栈 */ LinkStack Pop (LinkStack pStack); /* 出栈 */ int StackEmpty (LinkStack pStack); /* 判断栈是否为空 */ LinkStack DeletStack (LinkStack pStack);/* 清空栈 */ void DisplyStack (LinkStack pStack); /* 遍历栈----自顶至底*/ int main() { LinkStack p; char ch; p.height = 0; /* 栈高度初始化为零 */ p = InitStack (p); /* 栈初始化 */ printf("Do you want to push stack(Y/N)?"); scanf(" %c", &ch); while (ch == 'Y' || ch == 'y') { p = Push(p); /* 入栈 */ DisplyStack(p); /* 遍历栈 */ printf("Do you want to push stack(Y/N)?"); scanf(" %c", &ch); } printf("Do you want to pop stack(Y/N)?"); scanf(" %c", &ch); while (ch == 'Y' || ch == 'y') { p = Pop(p); /* 出栈 */ DisplyStack(p); /* 遍历栈 */ printf("Do you want to pop stack(Y/N)?"); scanf(" %c", &ch); } return 0; } /* Function: 初始化栈顶、栈底、栈高度*/ LinkStack InitStack (LinkStack pStack) { pStack.top = pStack.bottom = NULL; pStack.height = 0; return pStack; } /* Function: 判断栈是否为空 */ int StackEmpty (LinkStack pStack) { if (pStack.top == NULL && pStack.bottom == NULL) { return Empty; } else { return Avail; } } /* Function: 入栈 */ LinkStack Push (LinkStack pStack) { int data; StackNode *temp; if ((temp = (StackNode *)malloc(sizeof(StackNode))) == NULL) { printf("内存空间不足\n"); return pStack; } if (StackEmpty(pStack) == Empty) /* 如果栈为空 */ { pStack.top = pStack.bottom = temp; /* 栈顶、栈底指针都指向新建节点 */ temp->next = NULL; /* 节点指针域为空 */ printf("Please input data"); scanf("%d", &data); pStack.top->data = data; pStack.height++; return pStack; } else /* 栈不为空 */ { temp->next = pStack.top;/* 新建节点指向原来的栈顶 */ pStack.top = temp; /* 栈顶指针指向新建节点 */ printf("Please input data"); scanf("%d", &data); pStack.top->data = data; pStack.height++; return pStack; } } /* Function: 出栈 */ LinkStack Pop (LinkStack pStack) { StackNode *Second; if (StackEmpty(pStack) == Empty) /* 判断栈是否为空 */ { printf("栈为空,无法出栈\n"); return pStack; } if (pStack.top == pStack.bottom) /* 如果出栈的元素为最后一个元素 */ { printf("出栈元素为%d\n", pStack.top->data); free(pStack.top); pStack.top = pStack.bottom = NULL; /* 栈顶、栈底都指针都置为空 */ pStack.height--; return pStack; } printf("出栈元素为%d\n", pStack.top->data); Second = pStack.top->next; /* 指向栈顶的前一个元素*/ free(pStack.top); /* 释放栈顶节点 */ pStack.top = Second;/* 将头指针移动到新的栈顶节点 */ pStack.height--; return pStack; } /* Function: 遍历栈 自顶到底*/ void DisplyStack (LinkStack pStack) { if (StackEmpty(pStack) == Empty) { printf("栈为空,无法遍历\n"); return ; } printf("栈中元素["); while (pStack.top != NULL) { printf("%d->", pStack.top->data); pStack.top = pStack.top->next; } printf("]\n"); } /* Function: 清空栈 */ LinkStack DeletStack (LinkStack pStack) { StackNode *del; while (pStack.top != NULL) { del = pStack.top->next; /* 栈顶节点的前一个节点 */ free(pStack.top); /* 释放节点 */ pStack.top = del; /* 栈顶指针移动到新栈顶 */ } return pStack; }
括号匹配:
#include <stdio.h> #include <string.h> int top = -1; void push(char *a, char ch) { a[++top] = ch; } void pop(char *a) { if (top == -1) return; top--; } char visit(char *a) { if (top != -1) { return a[top]; } else { return ' '; } } int main() { char a[30]; char b[100]; int n; int flag = 1; scanf("%d", &n); while (n--) { top = -1; scanf("%s", b); getchar(); int len = (int)strlen(b); for (int i = 0; i < len; i++) { if (b[i] == '(' || b[i] == '{' || b[i] == '[' || b[i] == '<') { push(a, b[i]); } else { if (b[i] == ')') { if (visit(a) == '(') { pop(a); } else { printf("No\n"); flag = 0; break; } } else if (b[i] == '}') { if (visit(a) == '{') { pop(a); } else { printf("No\n"); flag = 0; break; } } else if (b[i] == ']') { if (visit(a) == '[') { pop(a); } else { printf("No\n"); flag = 0; break; } } else { if (visit(a) == '<') { pop(a); } else { printf("No\n"); flag = 0; break; } } } } if (flag == 1) { if (top != -1) { printf("No\n"); } else { printf("Yes\n"); } } flag = 1; } }