算法开启小码农栈血脉

简介: 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

003.gif

出栈:栈的删除操作叫做出栈。出数据也在栈顶

3.gif


栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

image.png

栈节点

typedef int STDataType;
typedef struct Stack
{
  STDataType* a;
  int top;       //栈顶
  int capacity;  //容量
}ST;


栈初始化函数StackInit


image.png

//栈初始化函数
void StackInit(ST* ps)
{
  assert(ps);
  ps->a = NULL;
  ps->top = 0;
  ps->capacity = 0;
}

入栈函数StackPush

image.png

//入栈函数
void StackPush(ST* ps, STDataType x)
{
  assert(ps);
  if (ps->top == ps->capacity)//判断是否扩容
  {
    int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity*sizeof(STDataType));
    if (!tmp)
    {
      printf("relloc fail\n");
      exit(-1);
    }
    ps->a = tmp;
    ps->capacity = newcapacity;
  }
  //扩容扩好以后把数据给过去
  ps->a[ps->top] = x;
  ps->top++;
}

提前把栈销毁函数写好

栈销毁函数StackDestroy

image.png

//栈销毁函数
void StackDestroy(ST* ps)
{
  assert(ps);
  free(ps->a);
  ps->a = NULL;
  ps->capacity = ps->top = 0;
}

出栈函数StackPop

image.png

//出栈函数
void StackPop(ST* ps)
{
  assert(ps);
  assert(ps->top>0);
  ps->top--;    
}


判断栈是否为空 函数StackEmpty

image.png

//判断栈是否为空函数
bool StackEmpty(ST* ps)
{
  assert(ps);
  return ps->top == 0;
}


取栈顶元素函数StackTop

image.png

//取栈顶部函数
STDataType StackTop(ST* ps)
{
  assert(ps);
  assert(!StackEmpty(ps));
  return ps->a[ps->top - 1];
}


栈大小函数StackSize

image.png

//栈大小函数
int StackSize(ST* ps)
{
  assert(ps);
  return ps->top;
}


遍历栈

image.png

while (!StackEmpty(&stack))
  {
    printf("%d ", StackTop(&stack));
    StackPop(&stack);
  }

代码

Stack.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack
{
  STDataType* a;
  int top;       //栈顶
  int capacity;  //容量
}ST;
//栈初始化函数
extern void StackInit(ST* ps);
//栈销毁函数
extern void StackDestroy(ST* ps);
//入栈函数
extern void StackPush(ST* ps, STDataType x);
//出栈函数
extern void StackPop(ST* ps);
//取栈顶部函数
extern STDataType StackTop(ST* ps);
//栈大小函数
extern int StackSize(ST* ps);
//判断栈是否为空函数
extern bool StackEmpty(ST* ps);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
//栈初始化函数
void StackInit(ST* ps)
{
  assert(ps);
  ps->a = NULL;
  ps->top = 0;
  ps->capacity = 0;
}
//入栈函数
void StackPush(ST* ps, STDataType x)
{
  assert(ps);
  if (ps->top == ps->capacity)//判断是否扩容
  {
    int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity*sizeof(STDataType));
    if (!tmp)
    {
      printf("relloc fail\n");
      exit(-1);
    }
    ps->a = tmp;
    ps->capacity = newcapacity;
  }
  //扩容扩好以后把数据给过去
  ps->a[ps->top] = x;
  ps->top++;
}
//栈销毁函数
void StackDestroy(ST* ps)
{
  assert(ps);
  free(ps->a);
  ps->a = NULL;
  ps->capacity = ps->top = 0;
}
//出栈函数
void StackPop(ST* ps)
{
  assert(ps);
  assert(ps->top>0);
  ps->top--;    
}
//取栈顶部函数
STDataType StackTop(ST* ps)
{
  assert(ps);
  assert(!StackEmpty(ps));
  return ps->a[ps->top - 1];
}
//栈大小函数
int StackSize(ST* ps)
{
  assert(ps);
  return ps->top;
}
//判断栈是否为空函数
bool StackEmpty(ST* ps)
{
  assert(ps);
  return ps->top == 0;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void Test1()
{
  ST stack = { 0 };
  StackInit(&stack);
  StackPush(&stack, 1);
  StackPush(&stack, 2);
  StackPush(&stack, 3);
  StackPush(&stack, 4);
  //遍历栈
  while (!StackEmpty(&stack))
  {
    printf("%d ", StackTop(&stack));
    StackPop(&stack);
  }
  printf("\n");
  StackDestroy(&stack);
}
int main()
{
  Test1();
  return 0;
}


练习

image.png

image.png

image.png

image.png

typedef char STDataType;
typedef struct Stack
{
  STDataType* a;
  int top;       //栈顶
  int capacity;  //容量
}ST;
//栈初始化函数
void StackInit(ST* ps)
{
  assert(ps);
  ps->a = NULL;
  ps->top = 0;
  ps->capacity = 0;
}
//栈销毁函数
void StackDestroy(ST* ps)
{
  assert(ps);
  free(ps->a);
  ps->a = NULL;
  ps->capacity = ps->top = 0;
}
//入栈函数
void StackPush(ST* ps, STDataType x)
{
  assert(ps);
  if (ps->top == ps->capacity)//判断是否扩容
  {
    int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity*sizeof(STDataType));
    if (!tmp)
    {
      printf("relloc fail\n");
      exit(-1);
    }
    ps->a = tmp;
    ps->capacity = newcapacity;
  }
  //扩容扩好以后把数据给过去
  ps->a[ps->top] = x;
  ps->top++;
}
//判断栈是否为空函数
bool StackEmpty(ST* ps)
{
  assert(ps);
  return ps->top == 0;
}
//取栈顶部函数
STDataType StackTop(ST* ps)
{
  assert(ps);
  assert(!StackEmpty(ps));
  return ps->a[ps->top - 1];
}
//出栈函数
void StackPop(ST* ps)
{
  assert(ps);
  assert(ps->top>0);
  ps->top--;    
}
bool isValid(char * s){
    ST st = {0};
    StackInit(&st);
    while(*s)
    {
        //如果是左括号就入栈
        if(*s == '(' 
        || *s == '{' 
        || *s == '[')
        {
            //入栈
            StackPush(&st,*s);
            s++;
        }
        else
        {     
           if(StackEmpty(&st))     
           {
                StackDestroy(&st);
                return false;
           }
           //出栈
           STDataType tmp = StackTop(&st);
           StackPop(&st);
           if(*s == '}' && tmp != '{'
           || *s == ']' && tmp != '['
           || *s == ')' && tmp != '(')
           {
               StackDestroy(&st);
               return false;
           }           
           else
           {
               s++;
           }           
        }
    }
    //如果栈不是空说明还有左括号
    bool ret = StackEmpty(&st);
    StackDestroy(&st);
    return ret;
}


目录
相关文章
|
2月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
79 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
47 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
6月前
|
存储 算法 调度
数据结构与算法-栈篇
数据结构与算法-栈篇
32 3
|
2月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
64 3
|
6月前
|
算法 C语言
【数据结构与算法 经典例题】使用栈实现队列(图文详解)
【数据结构与算法 经典例题】使用栈实现队列(图文详解)
|
2月前
|
算法 C++
【算法单调栈】 矩形牛棚(C/C++)
【算法单调栈】 矩形牛棚(C/C++)
|
4月前
|
算法
【算法】栈算法——逆波兰表达式求值
【算法】栈算法——逆波兰表达式求值
|
4月前
|
存储 算法
【算法】栈算法——最小栈
【算法】栈算法——最小栈
|
4月前
|
算法
【算法】栈算法——栈的压入、弹出序列
【算法】栈算法——栈的压入、弹出序列
下一篇
DataWorks