【练习】04:栈相关操作

Stack栈


目录

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

1.顺序栈操作:

#include
#include
#include

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];
}

//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;
}

【练习】04:栈相关操作_第1张图片

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;
}

【练习】04:栈相关操作_第2张图片

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种括号的匹配问题(判断左括号、右括号的数量是否相等),再扩展括号匹配的种类:

【练习】04:栈相关操作_第3张图片

  1. +1可以等价为进入,-1可以等价为出去
  2. 一对()可以等价为一个完整的事件
  3. (())可以看做事件与事件之间的完全包含关系

1种括号的匹配问题

【练习】04:栈相关操作_第4张图片


【练习】04:栈相关操作_第5张图片

多种括号的匹配问题

#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
#include

typedef 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 = 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;
}

【练习】04:栈相关操作_第6张图片

5.栈和队列的应用:

【练习】04:栈相关操作_第7张图片

你可能感兴趣的:(Data,Structure,c语言,数据结构)