Data|【练习】04(栈相关操作)

Stack栈
目录

  • Stack栈
        • 1.顺序栈操作:
        • 2.顺序栈扩容:
        • 3.LC20:ValidParathese
          • (1)方法1:简化思维:
          • (2)方法2:stack栈解决:
        • 4.链栈基本操作:
        • 5.栈和队列的应用:

1.顺序栈操作:
#include #include #includetypedef struct SqStack { int *base; //栈底指针 int top; //栈顶指针 int stacksize; //栈可用最大容量 } SqStack; //1.初始化栈操作 SqStack *InitStack(int n) { SqStack *s = (SqStack *)malloc(sizeof(SqStack)); s->base = (int *)malloc(sizeof(int) * n); s->stacksize = n; s->top = -1; return s; }//2.栈的销毁操作 void DestroyStack(SqStack *s) { if (s == NULL) return; free(s->base); free(s); return; }//3.判断栈是否为空 int StackEmpty(SqStack *s) { return s->top == -1; }//4.获取栈顶元素 int GetTop(SqStack *s) { return s->base[s->top]; }//5.入栈操作 int Push(SqStack *s, int val) { if (s == NULL) return 0; if (s->top == s->stacksize - 1) return 0; //栈已满 s->top++; //注意:这里栈顶指针指向的是栈顶元素故需要先++再赋值 s->base[s->top] = val; return 1; }//6.出栈操作 int Pop(SqStack *s) { if (s == NULL) return 0; if (StackEmpty(s)) return 0; s->top--; return 1; }//print操作 void print(SqStack *s) { if (s == NULL) return; printf("Stack : ["); for (int i = 0; i <= s->top; ++i){ i && printf(", "); printf("%d", s->base[i]); } printf("]\n"); return; }int main(){ srand(time(0)); #define MAX_OP 20 SqStack *s = InitStack(MAX_OP); for (int i = 0; i < MAX_OP; ++i) { int op = rand() % 4; int val = rand() % 100; switch (op) { case 0: case 1: case 2: { printf("push %d to the Stack = %d\n", val, Push(s, val)); } break; case 3: { printf("pop %d from the stack = ", GetTop(s)); printf("%d\n", Pop(s)); } break; } print(s); } #undef MAX_OP DestroyStack(s); return 0; }

Data|【练习】04(栈相关操作)
文章图片

2.顺序栈扩容: 关键代码
//SqStack扩容操作 int expand(SqStack *s) { int expand_size = s->stacksize; int *p; //顺序栈的循环扩容 while (expand_size) { p = (int *)realloc(s->base, sizeof(int) * (s->stacksize + expand_size)); if (p != NULL) break; //realloc扩容成功 expand_size >>= 1; //realloc扩容失败则将扩容容量extend缩小,再次尝试扩容 } if (p == NULL) return 0; s->stacksize += expand_size; s->base = p; return 1; }//5.入栈操作 int Push(SqStack *s, int val) { if (s == NULL) return 0; if (s->top == s->stacksize - 1) { if (!expand(s)) { printf(RED("fail to expand!\n")); return 0; } printf(GREEN("success to expand! the new size = %d\n"), s->stacksize); } s->top++; //注意:这里栈顶指针指向的是栈顶元素故需要先++再赋值 s->base[s->top] = val; return 1; }

完整代码
#include #include #include#define COLOR(a, b) "\033[" #b "m" a "\033[0m" #define GREEN(a) COLOR(a, 32) #define RED(a) COLOR(a, 31)typedef struct SqStack { int *base; //栈底指针 int top; //栈顶指针 int stacksize; //栈可用最大容量 } SqStack; //1.初始化栈操作 SqStack *InitStack(int n) { SqStack *s = (SqStack *)malloc(sizeof(SqStack)); s->base = (int *)malloc(sizeof(int) * (n)); s->stacksize = n; s->top = -1; return s; }//2.栈的销毁操作 void DestroyStack(SqStack *s) { if (s == NULL) return; free(s->base); free(s); return; }//3.判断栈是否为空 int StackEmpty(SqStack *s) { return s->top == -1; }//4.获取栈顶元素 int GetTop(SqStack *s) { return s->base[s->top]; }//SqStack扩容操作 int expand(SqStack *s) { int expand_size = s->stacksize; int *p; //顺序栈的循环扩容 while (expand_size) { p = (int *)realloc(s->base, sizeof(int) * (s->stacksize + expand_size)); if (p != NULL) break; //realloc扩容成功 expand_size >>= 1; //realloc扩容失败则将扩容容量extend缩小,再次尝试扩容 } if (p == NULL) return 0; s->stacksize += expand_size; s->base = p; return 1; }//5.入栈操作 int Push(SqStack *s, int val) { if (s == NULL) return 0; if (s->top == s->stacksize - 1) { if (!expand(s)) { printf(RED("fail to expand!\n")); return 0; } printf(GREEN("success to expand! the new size = %d\n"), s->stacksize); } s->top++; //注意:这里栈顶指针指向的是栈顶元素故需要先++再赋值 s->base[s->top] = val; return 1; }//6.出栈操作 int Pop(SqStack *s) { if (s == NULL) return 0; if (StackEmpty(s)) return 0; s->top--; return 1; }//print操作 void print(SqStack *s) { if (s == NULL) return; printf("Stack : ["); for (int i = 0; i <= s->top; ++i){ i && printf(", "); printf("%d", s->base[i]); } printf("]\n"); return; }int main(){ srand(time(0)); #define MAX_OP 20 SqStack *s = InitStack(1); for (int i = 0; i < MAX_OP; ++i) { int op = rand() % 4; int val = rand() % 100; switch (op) { case 0: case 1: case 2: { printf("push %d to the Stack = %d\n", val, Push(s, val)); } break; case 3: { printf("pop %d from the stack = ", GetTop(s)); printf("%d\n", Pop(s)); } break; } print(s); } #undef MAX_OP DestroyStack(s); return 0; }

Data|【练习】04(栈相关操作)
文章图片

3.LC20:ValidParathese Given a string s containing just the characters (, ), {, }, [ and ], determine if the input string is valid.
An input string is valid if:
Open brackets must be closed by the same type of brackets. Open brackets must be closed in the correct order.

(1)方法1:简化思维: 可以将问题先简化为1种括号的匹配问题(判断左括号、右括号的数量是否相等),再扩展括号匹配的种类:
Data|【练习】04(栈相关操作)
文章图片

  1. +1可以等价为进入,-1可以等价为出去
  2. 一对()可以等价为一个完整的事件
  3. (())可以看做事件与事件之间的完全包含关系
1种括号的匹配问题
Data|【练习】04(栈相关操作)
文章图片

Data|【练习】04(栈相关操作)
文章图片

多种括号的匹配问题
#include #include #include using namespace std; bool judgeOne(char *s, int *i, int d) { bool flag = true; int j = d; while (s[*i] && flag) { switch (s[*i]) { case '(' : ++(*i); flag = judgeOne(s, i, d + 1); if (s[*i] == ')') {++(*i); flag &= true; } else if (s[*i] == ']' || s[*i] == '}' || s[*i] == '\0') flag = false; break; case '[' : ++(*i); flag = judgeOne(s, i, d + 1); if (s[*i] == ']') {++(*i); flag &= true; } else if (s[*i] == ')' || s[*i] == '}' || s[*i] == '\0') flag = false; break; case '{' : ++(*i); flag = judgeOne(s, i, d + 1); if (s[*i] == '}') {++(*i); flag &= true; } else if (s[*i] == ')' || s[*i] == ']' || s[*i] == '\0') flag = false; break; case ')' : case ']' : case '}' : return j = 0 ? false : true && flag; default : return false; } } return flag; }bool isValid(char * s) { int i = 0, len = strlen(s); bool flag = true; while (i < len && flag) { flag &= judgeOne(s, &i, 0); } return flag; }int main() { char s[1000]; cin >> s; cout << s << " isValid : " << isValid(s) << endl; return 0; }

注意:该程序虽然可以判断成功,但是执行的时间复杂度太高导致超时。
(2)方法2:stack栈解决:
#include using namespace std; typedef struct Stack { char *base; int top; int stackSize; } Stack; void InitStack(Stack &s, int n) { s.base = new char[100000]; // s->base = (int *)malloc(sizeof(int) * n); // s->base = malloc(stackSize); s.stackSize = n; s.top = -1; }; bool EmptyStack(Stack &s) { return s.top == -1; }void PushStack(Stack &s, char c) { s.top++; s.base[s.top] = c; }void PopStack(Stack &s) { s.top--; }char GetTop(Stack &s) { return s.base[s.top]; }bool isValid(string s) { int len = s.length(); Stack stack; InitStack(stack, len); for (int i = 0; i < len; ++i) { switch (s[i]) { case '(': case '[': case '{': PushStack(stack, s[i]); break; case ')': if (EmptyStack(stack)) return false; if (GetTop(stack) != '(') return false; PopStack(stack); break; case '}': if (EmptyStack(stack)) return false; if (GetTop(stack) != '{') return false; PopStack(stack); break; case ']': if (EmptyStack(stack)) return false; if (GetTop(stack) != '[') return false; PopStack(stack); break; } } return EmptyStack(stack); }int main() { char s[1000]; cin >> s; cout << s << "isValid : " << isValid(s) << endl; return 0; }

4.链栈基本操作:
#include #include #includetypedef struct Node { int data; struct Node *next; } Node; typedef struct Stack { Node *top; int length; } LinkStack; //1.初始化结点 Node *InitNode(int val) { Node *p = (Node *)malloc(sizeof(Node)); p->data = https://www.it610.com/article/val; p->next = NULL; return p; }//2.初始化栈 LinkStack *InitStack() { LinkStack *s = (LinkStack *)malloc(sizeof(LinkStack)); s->top = NULL; s->length = 0; return s; }//3.销毁结点 void DestroyNode(Node *node) { if (node == NULL) return; free(node); return; }//4.销毁栈操作 void DestroyStack(LinkStack *ls) { if (ls == NULL) return; Node *p = ls->top, *temp; while (p != NULL) { temp = p->next; free(p); p = temp; } free(ls); return; }//5.链栈判空 int Empty(LinkStack *ls) { return ls->top == NULL; }//6.获取栈顶元素 int GetTop(LinkStack *ls) { return ls->top->data; }//7.链栈入栈 int Push(LinkStack *ls, int val) { if (ls == NULL) return 0; Node *p = InitNode(val); p->next = ls->top; ls->top = p; ls->length += 1; return 1; }//8.链栈出栈 int Pop(LinkStack *ls) { if (ls == NULL) return 0; if (Empty(ls)) return 0; Node *temp = ls->top; ls->top = ls->top->next; free(temp); ls->length -= 1; return 1; }void print(LinkStack *ls) { if (ls == NULL) return; printf("Stack[%d] : ", ls->length); for (Node *p = ls->top; p; p = p->next) { p != ls->top && printf(" "); printf("%d", p->data); } printf("\n"); return; }int main(){ srand(time(0)); #define MAX_OP 20 LinkStack *ls = InitStack(); for (int i = 0; i < MAX_OP; ++i) { int op = rand() % 4; int val = rand() % 100; switch (op) { case 0: case 1: case 2: { printf("push %d to the Stack = %d\n", val, Push(ls, val)); } break; case 3: { if (!Empty(ls)) { printf("pop %d form the Stack = ", GetTop(ls)); printf("%d\n", Pop(ls)); } } break; } print(ls); } #undef MAX_OP DestroyStack(ls); return 0; }

Data|【练习】04(栈相关操作)
文章图片

5.栈和队列的应用: 【Data|【练习】04(栈相关操作)】Data|【练习】04(栈相关操作)
文章图片

    推荐阅读