C语言中栈和队列实现表达式求值的实例

C语言中栈和队列实现表达式求值的实例

实现代码:

#include<stdio.h>
#include<stdlib.h> 

#define OK 1
#define ERROR 0
#define STACK_SIZE 20
#define STACK_INCREMENT 10
#define QUEUE_SIZE 20 

typedef int Status; 

typedef char StackElemtype;
typedef struct Stack{
  StackElemtype* base;
  StackElemtype* top;
  int stackSize;
}Stack;
Status StackInit(Stack* s){
  s->base = (StackElemtype*)malloc(sizeof(StackElemtype) * STACK_SIZE);
  if( !s->base )
    return ERROR;
  s->top = s->base;
  s->stackSize = STACK_SIZE;
  return OK;
}
Status Pop(Stack* s,StackElemtype* value){
  if( s->base == s->top ){
    printf("\nstack empty\n");
    return ERROR;
  }
  *value = *(--(s->top));
  return OK;
}
Status Push(Stack* s,StackElemtype value){
  if( s->top - s->base == s->stackSize){ 

    s->base = (StackElemtype*)realloc(s->base,sizeof(StackElemtype) * (STACK_INCREMENT + STACK_SIZE));
    if( !s->base )
      return ERROR;
    s->top = s->base + STACK_SIZE;
    s->stackSize = STACK_SIZE + STACK_INCREMENT;
  }
  *(s->top) = value;
  s->top++;
  return OK;
}
int StackLength(Stack s){
  return s.top - s.base;
} 

typedef double StackElemtype_ForValueExperssion;
typedef struct Stack_2{
  StackElemtype_ForValueExperssion* base;
  StackElemtype_ForValueExperssion* top;
  int stackSize;
}Stack_2;
Status StackInit_2(Stack_2* s){
  s->base = (StackElemtype_ForValueExperssion*)malloc(sizeof(StackElemtype_ForValueExperssion) * STACK_SIZE);
  if( !s->base )
    return ERROR;
  s->top = s->base;
  s->stackSize = STACK_SIZE;
  return OK;
}
Status Pop_2(Stack_2* s,StackElemtype_ForValueExperssion* value){
  if( s->base == s->top ){
    printf("\nstack empty\n");
    return ERROR;
  }
  *value = *(--(s->top));
  return OK;
}
Status Push_2(Stack_2* s,StackElemtype_ForValueExperssion value){
  if( s->top - s->base == s->stackSize){
    s->base = (StackElemtype_ForValueExperssion*)realloc(s->base,sizeof(StackElemtype_ForValueExperssion) * (STACK_INCREMENT + STACK_SIZE));
    if( !s->base )
      return ERROR;
    s->top = s->base + STACK_SIZE;
    s->stackSize = STACK_SIZE + STACK_INCREMENT;
  }
  *(s->top) = value;
  s->top++;
  return OK;
} 

typedef double QueueElemtype;
typedef char  QueueOperatorValue;
typedef struct QueueNode{
  QueueElemtype data;
  QueueOperatorValue operator;
  struct QueueNode* next;
  int flag;
}QueueNode,*QueueNodePtr;
typedef struct Queue{
  QueueNodePtr front;
  QueueNodePtr rear;
}Queue; 

Status QueueInit(Queue* q){
  q->front = (QueueNodePtr)malloc(sizeof(QueueNode));
  if( !q->front )
    return ERROR;
  q->rear = q->front;
  q->rear->next = NULL;
  return OK;
}
Status QueueInsert(Queue* q,QueueElemtype value){
  QueueNodePtr new;
  new = (QueueNodePtr)malloc(sizeof(QueueNode));
  if( !new )
    return ERROR;
  new->data = value;
  new->flag = 1;
  new->next = NULL;
  q->rear->next = new;
  q->rear = new;
  return OK;
}
Status QueueInsert_operatorValue(Queue* q,QueueOperatorValue value){
  QueueNodePtr new;
  new = (QueueNodePtr)malloc(sizeof(QueueNode));
  if( !new )
    return ERROR;
  new->operator = value;
  new->flag = 0;
  new->next = NULL;
  q->rear->next = new;
  q->rear = new;
  return OK;
}
Status QueueDelete(Queue* q,QueueElemtype* value,QueueOperatorValue *operator,int* symbol){
  QueueNodePtr first;
  if( q->front == q->rear )
    return ERROR;
  first = q->front->next;
  if( first->flag == 1 ){
    *value = first->data;
    *symbol = 1;
  }
  else{
    *operator = first->operator;
    *symbol = 0;
  }
  q->front->next = first->next;
  if( first == q->rear ){
    q->rear = q->front;
  }
  return OK;
} 

/* 利用栈将中缀表达式转化为后缀表达式:
 * ——————————————————————————————————————————————————————————————
 * | 用户的输入  |      进行的处理      |
 * |  0~9:   | 直接输出到控制台        |
 * |  /,*,(  | 直接Push          |
 * |  +,-    | 将栈中的元素Pop直到1.栈空或者是2.遇到(   |
 * |  )     | 在遇到(之前将栈中的元素全部Pop   |
 * ——————————————————————————————————————————————————————————————
 * */ 

Status Infix2Postfix(Queue* q){
  //Queue q;
  //QueueInit(&q);
  Stack s;
  StackInit(&s);
  char c,e;
  char bufferDigit[10];
  int i = 0;
  double longDigit;
  printf("    Please Enter Infix Expression\n");
  printf("------------NOTE: end of '#'--------------\n");
  scanf("%c", &c);
  while( '#' != c){
    while( c <= '9' && c >= '0' || '.' == c ){
      bufferDigit[i++] = c;
      bufferDigit[i] = '\0';
      scanf("%c", &c);
      if(!((c <= '9' && c >= '0' ) || '.' == c )){
        longDigit = atof(bufferDigit);
        QueueInsert(q,longDigit);
        i = 0;
      }
    }
    if( '(' == c || '*' == c || '/' == c ){
      Push(&s, c);
    }
    else if( '+' == c || '-' == c ){
      if( !StackLength(s) )
        Push(&s, c);
      else{
        Pop(&s, &e);
        while( '(' != e ){
          QueueInsert_operatorValue(q, e);
          if( StackLength(s) == 0 ){
            break;
          }else
            Pop(&s, &e);
        }
        if( '(' == e )
          Push(&s, e);
        Push(&s, c);
      }
    }else if( ')' == c ){
      Pop(&s, &e);
      while( '(' != e ){
        QueueInsert_operatorValue(q, e);
        Pop(&s, &e);
      }
    }else if( '#' == c){
      break;
    }else{
      printf("input ERROR!\n");
      return ERROR;
    }
    scanf("%c", &c);
  }
  while(StackLength(s)){
    Pop(&s, &e);
    QueueInsert_operatorValue(q, e);
  }
  QueueInsert_operatorValue(q,'#');
  return OK;
}
Status ShowQueue(Queue q){
  printf("The Reverse Polish Notation is:");
  if(q.front == q.rear){
    printf("Queue Empty");
    return ERROR;
  }
  QueueNodePtr p = q.front->next;
  while(p != q.rear){
    if(p->flag)
      printf("%g ", p->data);
    else
      printf("%c ", p->operator);
    p = p->next;
  }
  printf("\n");
  return OK;
} 

/* 利用栈求解后缀表达式(逆波兰表达式)的值。
 * ——————————————————————————————————————————————————————————————————————
 * |  +,-,*,/,  |   将栈顶的两个元素弹出进行计算,将结果压入栈顶 |
 * | 数字      |   将其压入栈顶                 |
 * ———————————————————————————————————————————————————————————————————————
 * */
Status ValueExpression(Queue q){
  Stack_2 s;
  StackInit_2(&s);
  double o1;
  double o2;
  QueueElemtype number;
  QueueOperatorValue operator;
  int symbol;
  QueueDelete(&q,&number,&operator,&symbol);
  while( symbol == 1 || ( symbol == 0 && '#' != operator)){
    if(symbol == 1){
      Push_2(&s, number);
    }
    else if(symbol == 0){
      switch(operator){
        case '+':
          Pop_2(&s,&o1);
          Pop_2(&s,&o2);
          Push_2(&s,o2 + o1);
          break;
        case '-':
          Pop_2(&s,&o1);
          Pop_2(&s,&o2);
          Push_2(&s,o2 - o1);
          break;
        case '*':
          Pop_2(&s,&o1);
          Pop_2(&s,&o2);
          Push_2(&s,o2 * o1);
          break;
        case '/':
          Pop_2(&s,&o1);
          Pop_2(&s,&o2);
          Push_2(&s,o2 / o1);
          break;
      }
    }
    QueueDelete(&q,&number,&operator,&symbol);
  }
  Pop_2(&s,&o1);
  printf("The Value of the Expression is %g\n",o1);
  return OK;
} 

int main(){
  Queue q;
  QueueInit(&q);
  Infix2Postfix(&q);
  ShowQueue(q);
/*
  QueueElemtype number;
  QueueOperatorValue operator;
  int symbol;
  QueueDelete(&q,&number,&operator,&symbol);
  printf("%f,%c,%d\n",number,operator,symbol);
*/
  ValueExpression(q);
//Stack
/*
  Stack s;
  StackInit(&s);
  StackElemtype c;
  Push(&s,'1');
  Push(&s,'2');
  Push(&s,'3');
  Push(&s,'4');
  Pop(&s,&c);
  printf("%c ", c);
  Pop(&s,&c);
  printf("%c ", c);
  Pop(&s,&c);
  printf("%c ", c);
  Pop(&s,&c);
  printf("%c ", c);
*/
  //Queue
/*
  Queue q;
  QueueElemtype c;
  QueueInit(&q);
  QueueInsert(&q,1);
  QueueInsert(&q,2);
  QueueInsert(&q,3);
  QueueInsert(&q,4);
  QueueDelete(&q,&c);
  printf("%d ", c);
  QueueDelete(&q,&c);
  printf("%d ", c);
  QueueDelete(&q,&c);
  printf("%d ", c);
  QueueDelete(&q,&c);
  printf("%d ", c);
  if(QueueDelete(&q,&c)){
    printf("%d ",c);
  }
*/
/*
  Queue q;
  QueueInit(&q);
  QueueInsert(&q,2.1);
  QueueInsert_operatorValue(&q,'+');
  QueueInsert(&q,43.1);
  QueueInsert_operatorValue(&q,'a');
  QueueInsert_operatorValue(&q,'(');
  int iswho;
  double d;
  char c;
  QueueDelete(&q,&d,&c,&iswho);
  if(iswho == 1)
    printf("%f ",d);
  else
    printf("%c ", c);
  QueueDelete(&q,&d,&c,&iswho);
  if(iswho == 1)
    printf("%f ",d);
  else
    printf("%c ", c);
  QueueDelete(&q,&d,&c,&iswho);
  if(iswho == 1)
    printf("%f ",d);
  else
    printf("%c ", c);
  QueueDelete(&q,&d,&c,&iswho);
  if(iswho == 1)
    printf("%f ",d);
  else
    printf("%c ", c);
*/
  return 0;
}

以上就是C语言数据结构中栈和队列的应用,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • C语言数据结构之顺序数组的实现

    C语言数据结构之顺序数组的实现 以下为展示顺序数组的示例: 1.用C语言实现的版本 #include<stdio.h> /* EOF(=^Z或F6),NULL */ #include<math.h> /* floor(),ceil(),abs() */ #include<stdlib.h> /*申请和释放内存*/ #include<stdarg.h> /*可变参数*/ #define OK 1 //成功标志 #define ERROR 0 //错误标志 #d

  • C语言约瑟夫环的实现

    C语言约瑟夫环的实现 一.典故: 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是商量了一个自杀方式: 41个人排成一个圆圈,由第1个人 开始报数,每数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止.然而Josephus 和他的朋友并不想遵从,Josephus要 他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死

  • C语言去除相邻重复字符函数的实现方法

    C语言去除相邻重复字符函数的实现方法 字符去重函数 功能:去重字符串相邻重复的字符,不相邻的不用去重 参数: arg1 -- 输入字符串 arg2 -- 字符串开始位置 arg3 -- 字符串结束位置 要求: 输入参数为arg1时, 对这个字符串去重 输入参数为arg1,arg2时, 从arg2位置到字符串结束,去重 输入参数为arg1,arg2,arg3时,从arg2到arg3位置,去重 src/include/catalog/pg_proc.h DATA(insert OID = 6669

  • C语言数据结构旋转链表的实现

    C语言数据结构旋转链表的实现 实例: 给出链表1->2->3->4->5->null和k=2 返回4->5->1->2->3->null 分析: 感觉很直观,直接把分割点找出来就行,记得k可能大于len,要取模 代码: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x

  • C语言数据结构之中缀树转后缀树的实例

    C语言数据结构之中缀树转后缀树的实例 对于一个中缀表达式 a+b*c*(d-e/f) 转换成后缀是这样的形式 abc*def/-+ 后缀表达式是相当有用处的,转换成后缀表达式后求值会简单很多.那么该如何转换呢? 网上关于这方面的资料一搜一大把,每本数据结构的书中都会提及这个算法,在这个算法中,用到 栈 这个数据结构. 1,关键是比较运算符的优先级,谁的优先级高,谁就出现在前面上面的表达式中,有括号的时候括号优先级最高,*/次之,+-最后. 在上面的表达式中+的优先级不如*的高,因此,在后缀表达式

  • C语言实现动态顺序表的实现代码

    C语言实现动态顺序表的实现代码 顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构.线性表采用顺序存储的方式存储就称之为顺序表.顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中. 静态实现:结构体内部只需两个成员,其中一个为固定大小(MAX)的数组,用来存放我们的数据.数组大小我们可以通过在头文件中改变MAX的值来改变. 动态实现:在内存中开辟一块空间,可以随我们数据数量的增多来扩容. 来看看动态的顺序表实现: 1.seqli

  • C语言中栈和队列实现表达式求值的实例

    C语言中栈和队列实现表达式求值的实例 实现代码: #include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define STACK_SIZE 20 #define STACK_INCREMENT 10 #define QUEUE_SIZE 20 typedef int Status; typedef char StackElemtype; typedef struct Stack{ StackElemty

  • JavaScript数据结构中栈的应用之表达式求值问题详解

    本文实例讲述了JavaScript数据结构中栈的应用之表达式求值问题.分享给大家供大家参考,具体如下: 下面来谈一个比较经典的表达式求值问题,这个问题主要是设计到操作符的优先级.我们通常看到的表达式都是中缀表达式,存在很多优先级差别,而后缀表达式则没有这些优先级问题.下面先看看两种表达式的区别. 中缀表达式:a*b+c*d-e/f      后缀表达式:ab*cd*+ef/- 从中缀表达式转换到后缀表示式是很难实现的,我们这里可以通过栈的思想来实现.下面进行详细的介绍是什么样的思想: 在对一个中

  • 浅谈C/C++ 语言中的表达式求值

    经常可以在一些讨论组里看到下面的提问:"谁知道下面C语句给n赋什么值?" m = 1; n = m+++m++; 最近有位不相识的朋友发email给我,问为什么在某个C++系统里,下面表达式打印出两个4,而不是4和5: a = 4; cout << a++ << a; C++ 不是规定 << 操作左结合吗?是C++ 书上写错了,还是这个系统的实现有问题? 注:运行a = 4; cout << a++ << a; 如在Visua

  • 深入浅析C语言中堆栈和队列

    1.堆和栈 (1)数据结构的堆和栈 堆栈是两种数据结构. 栈(栈像装数据的桶或箱子):是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取.这就如同要取出放在箱子里面底下的东西(放入的比较早的物体),首先要移开压在它上面的物体(放入的比较晚的物体). 堆(堆像一棵倒过来的树):是一种经过排序的树形数据结构,每个结点都有一个值.通常所说的堆的数据结构,是指二叉堆.堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆.由于堆的这个特性,常用来实现优先队列,堆的存取是随意,

  • C语言用栈和队列实现的回文检测功能示例

    本文实例讲述了C语言用栈和队列实现的回文功能.分享给大家供大家参考,具体如下: #include<stdio.h> #include<malloc.h>//内存分配头文件 #include<math.h>//在math.h中已定义OVERFLOW的值为3 #define SIZE 100 #define STACKINCREMENT 10 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typede

  • Go语言实现栈与队列基本操作学家

    目录 一.前言 二.实现栈与队列基本操作 2.1 栈基本操作 2.2 队列基本操作 三.用栈实现队列 3.1 理论 3.2 算法题 3.3 思路 3.4 代码部分 四.用队列实现栈 4.1 理论 4.2 算法题 4.3 思路 4.4 使用两个队列实现 4.5 优化 4.6 使用一个队列实现 一.前言 go语言中,并没有栈与队列相关的数据结构,但是我们可以借助切片来实现栈与队列的操作:接下来我们一起实现栈与队列基本操作,并且还会实现用栈实现队列,用队列实现栈的操作. 二.实现栈与队列基本操作 2.

  • java中栈和队列的实现和API的用法(详解)

    在java中要实现栈和队列,需要用到java集合的相关知识,特别是Stack.LinkedList等相关集合类型. 一.栈的实现 栈的实现,有两个方法:一个是用java本身的集合类型Stack类型:另一个是借用LinkedList来间接实现Stack. 1.Stack实现 直接用Stack来实现非常方便,常用的api函数如下: boolean        isEmpty() // 判断当前栈是否为空 synchronized E        peek() //获得当前栈顶元素 synchro

  • C语言中栈的两种实现方法

    栈的两种实现方式 通常情况下,栈的实现方式有两种,一种方法是使用指针,而另一种方法则是使用数组.但是在调用程序时,我们没有必要知道具体使用了哪种方法. 一.顺序栈 #include<stdio.h> #include<stdlib.h> #define maxsize 64 //定义栈 typedef struct { int data[maxsize]; int top; }sqstack,*sqslink; //设置栈空 void Clearstack(sqslink s) {

  • JavaScript中栈和队列应用详情

    目录 什么是栈和队列 什么时候用到栈 目录的计算 什么是栈和队列 栈如果用数组模拟的话是类似于一个U形桶状堆栈空间,地下是封口的,只能从顶部一个地方进出,它的进出都是有顺序的,看下图:如果是进入,则是最下是最先进入的,如果要出,则是从最顶部先出 和队列来对比,只是数据结构相同,队列是一侧进一侧出,做任务队列调度的时候都是先入先出 什么时候用到栈 从编辑器开发写代码的时候,如果代码的中的括号写错了,则很容易判定出那个地方少了括号,在JavaScript语法中有可以设定大括号{}.中括号:[].小括

  • 数据结构课程设计-用栈实现表达式求值的方法详解

    1.需求分析设计一个程序,演示用算符优先法对算术表达式求值的过程.利用算符优先关系,实现对算术四则混合运算表达式的求值.(1)输入的形式:表达式,例如2*(3+4)     包含的运算符只能有'+' .'-' .'*' .'/' .'('. ')':(2)输出的形式:运算结果,例如2*(3+4)=14:(3)程序所能达到的功能:对表达式求值并输出 2.系统设计1.栈的抽象数据类型定义:ADT Stack{数据对象:D={ai|ai∈ElemSet,i=1,2,-,n,n≥0}数据关系:R1={<

随机推荐