嵌入式学习的第二十二天-数据结构-栈+队列

一、栈

1.定义:栈是限定仅在表尾进行插入和删除操作的线性表先进后出、后进先出

2.栈顶(top):允许操作的一端  栈底(bottom):不允许操作的一端

3.栈的插入操作叫做进栈,也叫压栈、入栈;栈的删除操作叫做出站,也叫弹栈。

:链式结构只支持头删和头插

4.栈的一般操作

(1).创建 CreateSeqStack

LinkStack*CreateLinkStack()
{
    LinkStack*ls = (LinkStack*)malloc(sizeof(LinkStack));
    if(NULL == ls)
    {
        fprintf(stderr,"CreateLinkStack malloc\n");
        return NULL;
    }
    ls->top =NULL;
    ls->clen = 0;
    return ls;
}


(2).销毁 DestroySeqStack

int DestoryLinkStack(LinkStack*ls)
{
    int len = GetSizeLinkStack(ls);
    int i = 0;
    for(i = 0;i < len;++i)
    {
       PopLinkStack(ls);
    }
    free(ls);
    ls->top = NULL;
    return 0;
}


(3).判断是否为空栈 IsEmptySeqStack

int IsEmptyLinkStack(LinkStack*ls)
{
    return 0 == ls->clen;
}


(4).获取栈顶元素

DATATYPE*GetTopLinkStack(LinkStack*ls)
{
    if(IsEmptyLinkStack(ls))
    {
        return NULL;
    }
    return &ls->top->data;
}


(5).进栈 PushSeqStack

int PushLinkStack(LinkStack*ls,DATATYPE*data)
{
    LinkStackNode *newnode = malloc(sizeof(LinkStackNode));
    if(NULL == ls)
    {
        fprintf(stderr,"PushLinkStack malloc\n");
        return 1;
    }
    memcpy(&newnode->data, data, sizeof(DATATYPE));
    newnode->next =NULL;

    newnode->next = ls->top;
    ls->top = newnode;
    ls->clen++;
    return 0;
}


(6).出栈 PopSeqStack

int PopLinkStack(LinkStack*ls)
{
    if(IsEmptyLinkStack(ls))
    {
        return 1;
    }
    LinkStackNode *tmp = ls->top;
    ls->top = ls->top->next;
    free(tmp);
    ls->clen--;
    return 0;
}

二、队列

1.定义:队列是只允许在一段进行插入,而在另一端进行删除操作的线性表。

2.允许插入的称谓队尾,允许删除的一端队头。

3.特性:先进先出

4.队列的一般操作

(1)满队和空队的判断

满队:(tail+1)%tlen=head;空对:tail = head;

(2)创建 CreateSeQue

SeqQueue* CreateSeqQue(int len)
{
    SeqQueue*sq = (SeqQueue*)malloc(sizeof(SeqQueue));
    if(NULL == sq)
    {
        fprintf(stderr, "CreateSeQueue malloc\n");
        return NULL;
    }
    sq->array = (malloc(sizeof(DATATYPE)*len));
    if(NULL == sq->array)
    {
        fprintf(stderr, "CreateSeQueue malloc\n");
        return NULL;
    }
    sq->head = 0;
    sq->tail = 0;
    sq->tlen =len;
    return sq;
    
}

(3)判空

int IsEmptySeqQue(SeqQueue*sq)
{
    return sq->head==sq->tail;
}

(4)判满

int IsFullSeqQue(SeqQueue*sq)
{
    return (sq->tail+1)%sq->tlen == sq->head;
}

(5)进队

int EnterSeqQue(SeqQueue*sq,DATATYPE*data)
{
    if(IsFullSeqQue(sq))
    {
        fprintf(stderr,"EnterSeqQue,SeqQue full\n");
        return 1;
    }
    memcpy(&sq->array[sq->tail], data, sizeof(DATATYPE));
    sq->tail = (sq->tail+1)%sq->tlen;
    return 0;;
}

(6)出队

int QuitSeqQue(SeqQueue*sq)
{
     if(IsEmptySeqQue(sq))
    {
        fprintf(stderr,"QuitSeqQue SeqQue empty\n");
        return 1;
    }
    sq->head =(sq->head+1)%sq->tlen;
    return 0;
}

(7)获得队头元素

DATATYPE* GetHeadSeqQue(SeqQueue*sq)
{
    if(IsEmptySeqQue(sq))
    {
        return NULL;
    }
    return &sq->array[sq->head];
}

(9)销毁

int DestroySeqQue(SeqQueue*sq)
{
    free(sq->array);
    free(sq);
    return 0;
}

三、四则运算底层逻辑(运算及优先问题)


#include <stdio.h>
#include <string.h>
#include "linkstack.h"

int num = 0;
void getnum(char c) { num = num * 10 + c - '0'; }
int get_priority(char c)
{
  switch (c)
    {
      case '+':
      case '-':
        return 1;
        break;
      case '*':
      case '/':
        return 2;
        break;
      default:
        return 100;
    }
  return 100;
}
int get_result(int num1,int num2,char c)
{
    switch (c) 
    {
        case '+':
        return num1+num2;
          case '-':
        return num1-num2;
          case '*':
        return num1*num2;
          case '/':
        return num1/num2;
    }
    return -1;

}
int main(int argc, char** argv)
{
  char buf[] = "2*3+4";
  LinkStack* ls_op = CreateLinkStack();
  LinkStack* ls_num = CreateLinkStack();
  char* tmp = buf;
  DATATYPE data;
  DATATYPE* top = NULL;
  int flag = 0;
  while (*tmp)
    {
      memset(&data, 0, sizeof(data));
      if (*tmp >= '0' && *tmp <= '9')
        {
          getnum(*tmp);
          tmp++;
          continue;
        }

      if (0 == flag)
        {
          data.num = num;
          PushLinkStack(ls_num, &data);
          num = 0;
        }

      memset(&data, 0, sizeof(data));
      top = GetTopLinkStack(ls_op);
      if (IsEmptyLinkStack(ls_op) ||
          get_priority(*tmp) >
              get_priority(
                  top->c))  //栈顶为空 或 当前运算符优先级大于 栈顶运算符优先级
        {
          data.c = *tmp;
          PushLinkStack(ls_op, &data);
          flag = 0 ;
        }
      else
        {
          int num2 = GetTopLinkStack(ls_num)->num;
          PopLinkStack(ls_num);
          int num1 = GetTopLinkStack(ls_num)->num;
          PopLinkStack(ls_num);

          int c = GetTopLinkStack(ls_op)->c;
          PopLinkStack(ls_op);

          int result = get_result(num1, num2, c);
          memset(&data, 0, sizeof(data));
          data.num = result;
          PushLinkStack(ls_num, &data);
          flag = 1;  // 当前符号需要继续判断优先级
          continue;
        }

      tmp++;
    }
  data.num = num;
  PushLinkStack(ls_num, &data);

  while (!IsEmptyLinkStack(ls_op))
    {
      int num2 = GetTopLinkStack(ls_num)->num;
      PopLinkStack(ls_num);
      int num1 = GetTopLinkStack(ls_num)->num;
      PopLinkStack(ls_num);

      int c = GetTopLinkStack(ls_op)->c;
      PopLinkStack(ls_op);

      int result = get_result(num1, num2, c);
      memset(&data, 0, sizeof(data));
      data.num = result;
      PushLinkStack(ls_num, &data);
    }

  int result = GetTopLinkStack(ls_num)->num;
  printf("result is %d\n", result);

  DestroyLinkStack(ls_num);
  DestroyLinkStack(ls_op);

  return 0;
}

四、判断括号匹配问题

检查文件有无括号匹配问题


#include <stdio.h>
#include <string.h>
#include "linkstack.h"

/**
 * @brief 读取文件内容
 *
 * @param filename 文件名
 * @param filecontext  接收文件内容的字符数组  char buf[1024]={0};
 * @return int 0 表示成功  1 表示失败
 */
int readfile(char *filename, char *filecontext)
{
  FILE *fp = fopen(filename, "r");
  if (NULL == fp)
    {
      return 1;
    }
  fread(filecontext, 1024, 1, fp);
  fclose(fp);
  return 0;
}
int main(int argc, char **argv)
{
  char buf[1024] = {0};
  int ret = readfile("/home/linux/2.c", buf);
  if (1 == ret)
    {
      return 1;
    }
  LinkStack *ls = CreateLinkStack();
  char *tmp = buf;
  DATATYPE data = {0};
  int row = 1;
  int col = 1;
  DATATYPE *top;
  while (*tmp)  // ( [ {
    {
      memset(&data, 0, sizeof(DATATYPE));
      switch (*tmp)
        {
          case '(':
          case '[':
          case '{':
            data.c = *tmp;
            data.col = col;
            data.row = row;

            PushLinkStack(ls, &data);
            break;

          case ')':
            top = GetTopLinkStack(ls);
            if ('(' == top->c && NULL != top)
              {
                PopLinkStack(ls);
              }
            else
              {
                if (NULL == top)
                  {
                    printf("sym:%c row:%d col%d\n", ')', row, col);
                  }
                else
                  {
                    printf(
                        "top sym:%c row:%d col%d , or file sym:%c row:%d "
                        "col%d\n",
                        top->c, top->row, top->col, *tmp, row, col);
                  }
                return 1;
              }

            break;

          case ']':
            top = GetTopLinkStack(ls);
            if ('[' == top->c && NULL != top)
              {
                PopLinkStack(ls);
              }
            else
              {
                if (NULL == top)
                  {
                    printf("sym:%c row:%d col%d\n", ')', row, col);
                  }
                else
                  {
                    printf(
                        "top sym:%c row:%d col%d , or file sym:%c row:%d "
                        "col%d\n",
                        top->c, top->row, top->col, *tmp, row, col);
                  }
                return 1;
              }

            break;

          case '}':
            top = GetTopLinkStack(ls);
            if ('{' == top->c && NULL != top)
              {
                PopLinkStack(ls);
              }
            else
              {
                if (NULL == top)
                  {
                    printf("sym:%c row:%d col%d\n", ')', row, col);
                  }
                else
                  {
                    printf(
                        "top sym:%c row:%d col%d , or file sym:%c row:%d "
                        "col%d\n",
                        top->c, top->row, top->col, *tmp, row, col);
                  }
                return 1;
              }

            break;
        }
      col++;
      if ('\n' == *tmp)
        {
          col = 1;
          row++;
        }
      tmp++;
    }

  if ('\0' == *tmp && IsEmptyLinkStack(ls))
    {
      printf("ok");
    }
  else
    {
      top = GetTopLinkStack(ls);
      printf("top sym:%c row:%d col%d\n", top->c, top->row, top->col);
    }

    DestroyLinkStack(ls);
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值