精华内容
下载资源
问答
  • 2. 利用数据结构实现一个简单的4则运算计算器(不需要支持括号)。例如, 分析5 * 2 + 3 * 4的执行过程,输出进出的顺序(提示:中间结果得到后可继续push到中)。 最好能写出代码 并加注释 c语言 不是...
  • Python栈数据结构的实现

    千次阅读 2017-11-20 19:49:49
    栈结构:stack 生活例子:电梯 的特点:先进后出(FirstInLastOut,简称FILO) 的基本用法:push(入栈:添加元素) pop(出栈:删除元素) size(返回的大小) is_empty(判断是否为空) empty(清空) top(返回...
    栈结构:stack
    生活例子:电梯
    栈的特点:先进后出(FirstInLastOut,简称FILO)

    栈的基本用法:push(入栈:添加元素) pop(出栈:删除元素) size(返回栈的大小) is_empty(判断栈是否为空) empty(清空栈) top(返回栈顶元素)

    # -*- coding:utf-8 -*-
    
    
    # 利用python的列表来模拟一个栈结构
    class MyStack(object):
        # 构造函数、初始化函数
        def __init__(self):
            # 私有属性: 类内部可以用,但是外部不能用
            self.__stack = []
    
        def push(self, value):
            # 入栈
            self.__stack.append(value)
    
        def pop(self, value=None):
            # 出栈
            if value:
                if value in self.__stack:
                    index = self.__stack.index(value)
                    return self.__stack[0:index]
            else:
                if self.__stack:
                    return self.__stack.pop()
            return None
    
        def size(self):
            # 返回栈的大小
            return len(self.__stack)
    
        def is_empty(self):
            # 判断栈是否为空
            # 返回False:表示不空
            # 返回True:表示空
            if self.__stack:
                return False
            return True
    
      def empty(self):
            # 清空栈
            # Python 的内存管理机制  叫 GC(GarbageCollection:垃圾回收)
            # 如果这个对象没有人使用,会被系统自动回收删除
            self.__stack = []
    
        def top(self):
            # 返回栈顶元素
            if self.__stack:
                return self.__stack[-1]
            return None
    
    my_stack = MyStack()
    my_stack.push("A")
    my_stack.push("B")
    print my_stack.size()
    print my_stack.top()
    print my_stack.is_empty()
    print my_stack.pop("A")
    my_stack.empty()



    展开全文
  • C语言实现栈数据结构操作

    千次阅读 2013-12-31 21:14:59
    把允许插入和删除的一端称为栈顶(top),另一端称为底(bottom),不含任何数据元素的称为空栈。又称为后进先出的线性表,简称为LIFO。 的插入操作,叫做进栈,也称为压栈或者入栈。 的删除操作,叫做...

    定义:栈是限定仅在表尾进行插入和删除操作的线性表。

    把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表,简称为LIFO。

    栈的插入操作,叫做进栈,也称为压栈或者入栈。

    栈的删除操作,叫做出栈,也称为弹栈。

     

    栈的顺序存储结构

    因为栈是线性表的一种特殊形式,所以用数组实现栈的顺序存储结构。

    我们约定,下标为0的一端作为栈底。定义一个top变量来指示栈顶元素在数组中的位置。约定把空栈的判定条件定为top等于-1。

    栈的结构定义:

    #define MAXSIZE 100;
    typedef int SElemType;
    typedef struct
    {
    	SElemType data[MAXSIZE];
    	int top;  /*用于栈顶指针*/ 
    }SqStack;


    栈的顺序存储结构-----进栈

    C语言代码如下:

    /*插入元素e为新的栈顶元素*/
    int Push(SqStack *S, SElemType e)
    {
    	if (S->top == MAXSIZE - 1)
    	{
    		return 0;
    	}
    	S->top++;
    	S->data[S->top] = e;
    	return 1;
    }


     

    栈的顺序存储结构---出栈

    C语言代码如下:

    /*若栈不空,则删除S的栈顶元素,用e返回其值,并返回1;否则返回0*/
    int Pop(SqStack *L, SElemType *e)
    {
    	if (S->top == -1)
    	{
    		return 0;
    	}
    	*e = S->data[S->top];
    	return 1; 
    }


    说明:栈的顺序存储结构的进栈和出栈都没有涉及循环,时间复杂度都为O(1)。

     

     

    两栈共享空间

    如果有两个相同类型的栈,我们为他们各自开辟了数组空间,极有可能是第一个栈满了 ,再进栈就溢出了,而另一个栈还有很多存储空间空闲。因此我们完全可用一个数组来存储两个栈。

    做法:数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈的栈底为栈的末端,即下标为n-1处。这样,两个栈如果增加元素,就是两端点向中间延伸。

    我们约定top1和top2是两个栈的栈顶指针。

    栈1为空时,top1=-1;栈2空时,top2=n。

    当栈满时有top2 = top1+1。

    两栈共享空间结构代码如下:

    /*两栈共享空间结构*/
    typedef struct
    {
    	SElemType data[MAXSIZE];
    	int top1;
    	int top2;
    }SqDoubleStack;


    两栈共享空间的进栈操作

    /*插入元素e为新的栈顶元素*/
    int Push(SqDoubleStack *S, SElemType e, int stackNumber)
    {
    	if (S->top1+1==S->top2) /*栈已经满,不能再push新元素*/
    	{
    		return 0;	
    	}
    	if (stackNumber == 1) /*栈1有元素进栈*/
    	{
    		S->data[++S->top1] = e /*若栈1则先top1+1后给数组元素赋值*/ 
    	} 
    	else if(stackNumber == 2)
    	{
    		S->data[--S->top2] = e;
    	} 
    	return 1;
    } 


     

    两栈共享空间出栈操作

    /*若栈不空,则删除S的栈顶元素,用e返回其值,并返回1,否则返回0*/
    int Pop(SqDoubleStack *S, SElemType *e, int stackNumber)
    {
    	if (stackNumber == 1)
    	{
    		if (S->top1 == -1)
    		{
    			return 0;
    		}
    		*e = S->data[S->top1--];
    	}
    	else if (stackNumber == 2)
    	{
    		if (S->top2 == MAXSIZE)
    		{
    			return 0;
    		}
    		*e = S->data[S->top2++];
    	}
    	return 1;
    } 

    说明:使用两栈共享空间这样的数据结构,通常都是当两个栈的空间需求有相反关系时,也就是一个栈增长时另一个栈在缩短的情况。当然,这只是针对两个具有相同数据类型的栈的一个设计上的技巧。

     

    栈的链式存储结构----简称链栈

    由于单链表有头指针,而栈顶指针也是必须的,因此比较好的方法时把栈顶放在单链表的头部。通常对于链栈来说,是不需要头结点的。

    链栈的结构定义:

     

    typedef int SElemType;
    typedef struct StackNode
    {
    	SElemType data;
    	struct StackNode *next; 
    }StackNode;
    typedef StackNode * LinkStackPtr;
    
    typedef struct LinkStack
    {
    	LinkStackPtr top;  //栈顶指针 
    	int count;
    }LinkStack;


    链栈的进栈操作:

    /*插入元素e为新的栈顶元素*/
    int Push(LinkStack *S, SElemType e)
    {
    	LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));
    	s->data = e;
    	s->next = S->top;//把当前的栈顶元素赋值给新结点的直接后继
    	S->top = s;
    	S->count++;
    	return 1; 
    	
    }


    链栈的出栈操作:

    /*若栈不为空,则删除S的栈顶元素,用e返回其值,并返回1;否则返回0*/
    int Pop(LinkStack *S, SElemType *e)
    {
    	LinkStackPtr p;
    	if (S->top == NULL)
    	{
    		return 0;
    	}
    	*e = S->top->data;
    	p = S->top;
     	S->top = S->top->next;
     	free(p);
     	S->count--;
    	return 1; 
    }


    说明:对于链栈的进栈和出栈操作,它们的时间复杂度都为O(1)。
     

    展开全文
  • C语言 数据结构 迷宫求解(附完整代码)

    千次阅读 多人点赞 2018-11-15 20:20:49
    要求:以书中3.2.4节迷宫求解为基础实现迷宫游戏,游戏运行时显示一个迷宫地图(迷宫内容结构可以参照书中图片,也可以自己编写),玩家从地图左上角的入口处进入迷宫,从右下角出口离开迷宫。玩家不能穿墙而过。本...

    一、程序设计思路

    1、题目:应用栈实现迷宫游戏

    要求:以书中3.2.4节迷宫求解为基础实现迷宫游戏,游戏运行时显示一个迷宫地图(迷宫内容结构可以参照书中图片,也可以自己编写),玩家从地图左上角的入口处进入迷宫,从右下角出口离开迷宫。玩家不能穿墙而过。

    2、解决思路

    采用“穷举求解”方法,需要用到栈,从入口开始,往四个方向走,依次将走过的坐标点–入栈;如果走到“死路”,就出栈;一一循环;最后栈中保存的就是出迷宫的路线。

    3、算法描述

    求迷宫中一条从入口到出口的路径的算法可简单描述如下:

    设当前位置的初值为入口位置;

    do{
    若当前位置可通,
    则{
    将当前位置压至栈顶; //纳入路径
    如果当前位置是出口位置,则结束;
    否则切换当前位置的东邻方块为新的当前位置;
    }
    否则,
    若栈不为空且栈顶位置尚有其他方向未经探索,
    则设定新的当前位置为沿顺时针方向旋转找到的栈顶位置的下一相邻方块;
    若栈不为空且栈顶位置的四周均不可通,
    则{
    删去栈顶位置;
    若栈不为空,则重新测试新的栈顶位置,
    直至找到一个可通的相邻块或者出栈至栈空;
    }
    }while(栈不为空);

    二、程序源代码
    栈部分

    
    
    
    #include "stdafx.h"                //包含标准C的头文件,stdio.h,string.h等
    
    #include <malloc.h>               //动态储存分配函数头文件,用于栈的储存空间分配
    
    #include <stdlib.h>               //standard library标准库头文件
    
    typedef int DirectiveType;        //下一个通道方向  
    
    #define RANGE 100                 //迷宫大小  
    
    #define STACK_INIT_SIZE 100       //定义栈的初始大小
    
    #define STACKINCREMENT    10      //定义栈的储存增量,在栈长度越界时
    
    typedef int DirectiveType;        //下一个通道方向  
    
    #define RANGE 100                 //迷宫大小  
    
    #define ROW 10                    //迷宫的行数
    
    #define COL 10                    //迷宫的列数    
    
     
    
    typedef struct        
    
    {
    
        int m, n;
    
        int arr[RANGE][RANGE];       //迷宫数组
    
    }MazeType;                       //迷宫的类型
    
     
    
    typedef struct
    
    {
    
        int row;                     //迷宫中的行
    
        int col;                     //迷宫中的列
    
    }PosType;                        //坐标(row,col)
    
     
    
    typedef struct
    
    {
    
        int step;                    //当前位置在路径上的"序号"
    
        PosType seat;                //当前的坐标位置
    
        DirectiveType di;            //往下一个坐标位置的方向
    
    }SElemType;                      //栈的元素类型
    
     
    
    typedef struct
    
    {
    
        SElemType *base;             //栈底
    
        SElemType *top;              //栈顶
    
        int stacksize;               //栈的大小
    
    }SqStack;                        //定义栈
    
     
    
    bool InitStack(SqStack &s)
    
    {                                //栈的初始化
    
        s.base = (SElemType
    *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    
        if (!s.base)
    
        {
    
           exit(-2);
    
        }
    
        s.top = s.base;
    
        s.stacksize = STACK_INIT_SIZE;
    
        return true;
    
    }
    
     
    
    bool GetTop(SqStack s, SElemType &e)  
    //当栈s不为空时,返回栈顶e
    
    {
    
        if (s.top == s.base)
    
           return false;
    
        e = *(s.top - 1);
    
        return true;
    
    }
    
     
    
    bool Push(SqStack &s, SElemType e)    
    //在栈s中插入元素e,入栈
    
    {
    
        if (s.top - s.base >=
    s.stacksize)
    
        {                                 //若栈满,追加存储空间
    
           s.base = (SElemType
    *)realloc(s.base, (s.stacksize + STACKINCREMENT) * sizeof(SElemType));
    
           if (!s.base)
    
               exit(-2);  
    
           s.top = s.base + s.stacksize;
    
           s.stacksize += STACKINCREMENT;
    
        }
    
        *s.top++ = e;
    
        return true;
    
    }
    
     
    
    bool Pop(SqStack &s, SElemType &e)     //在栈s中删除栈顶,出栈
    
    {
    
        if (s.top == s.base)               //当栈空时
    
           return false;                  //返回错误
    
        e = *--s.top;                      //e指向新栈顶
    
        return true;
    
    }
    
     
    
    bool StackEmpty(SqStack s)            
    //栈判空
    
    {
    
        return s.base == s.top;            
    
    }
    
     
    
    bool DestoryStack(SqStack &s)         
    //销毁栈
    
    {
    
        free(&s);                          //释放栈s的储存空间
    
        return true;
    
    }
    
    
    

    迷宫部分

    
    
    bool InitMaze(MazeType &maze, int a[ROW][COL], int row, int col)  //初始化迷宫
    
    {
    
        int i, j;                            //设置迷宫maze的初值,包括加上边缘一圈的值
    
        for (i = 1; i<row - 1;
    i++)         
    
        {
    
           for (j = 1; j<col - 1; j++)
    
           {
    
               maze.arr[i][j] = a[i][j];
    
           }
    
        }                                          
    
        for (j = 0; j<row; j++)                     //加上围墙
    
           maze.arr[0][j] = maze.arr[row
    - 1][j] = 1;
    
        for (i = 0; i<col; i++)
    
           maze.arr[i][0] =
    maze.arr[i][col - 1] = 1;
    
        return true;
    
    }
    
     
    
    bool Pass(MazeType maze, PosType curpos)
    
    {                                                 
    //判断当前节点是否通过
    
        if (maze.arr[curpos.row][curpos.col]
    == 0)     //当节点为0时返回真
    
           return true;
    
        else
    
           return false;
    
    }
    
     
    
    bool FootPrint(MazeType &maze, PosType curpos)
    
    {                                                  
    //留下足迹
    
        maze.arr[curpos.row][curpos.col]
    = 2;           //走过且走得通
    
        return true;
    
    }
    
     
    
    bool MarkPrint(MazeType &maze, PosType curpos)
    
    {                                                  
    //留下不能通过的标记
    
        maze.arr[curpos.row][curpos.col]
    = 3;           //走过但走不通
    
        return true;
    
    }
    
     
    
    SElemType CreateSElem(int step, PosType pos, int di)
    
    {                                                   
    //创建元素e
    
        SElemType e;
    
        e.step = step;
    
        e.seat = pos;
    
        e.di = di;
    
        return e;
    
    }
    
     
    
    PosType NextPos(PosType curpos, DirectiveType di)   //curpos当前位置
    
    {                                                  
    //返回当前节点的下一节点
    
        PosType pos = curpos;
    
        switch (di)
    
        {
    
        case 1:        //右
    
           pos.col++;
    
           break;
    
        case 2:        //下
    
           pos.row++;
    
           break;
    
        case 3:        //左
    
           pos.col--;
    
           break;
    
        case 4:        //上
    
           pos.row--;
    
           break;
    
        }
    
        return pos;
    
    }
    
     
    
    bool PosEqual(PosType pos1, PosType pos2)
    
    {                                               
    //判断是不是出口
    
        if (pos1.row == pos2.row
    && pos1.col == pos2.col)    
    
           return true;                            
    
        else
    
           return false;
    
    }
    
     
    
    void PrintMaze(MazeType maze, int row, int col)
    
    {                                               
    //打印路径
    
        int i, j;
    
        printf(" ");
    
        for (i = 0; i<col; i++)                    //打印列数名
    
           printf("%d ", i);
    
        printf("\n");
    
        for (i = 0; i<row; i++)
    
        {
    
           printf("%d",
    i);                      //打印行数名
    
           for (j = 0; j<col; j++)
    
           {
    
               switch (maze.arr[i][j])
    
               {
    
               case 0:
    
                  printf("  ");                 //没走过,但是通路
    
                  break;
    
               case 1:
    
                  printf("■");                  //墙,障碍物
    
                  break;
    
               case 2:
    
                  printf("*
    ");                 //走过且走得通
    
                  break;
    
               case 3:
    
                  printf("@
    ");                 //走过但走不通,死胡同
    
                  break;
    
               default:
    
                  break;
    
               }
    
           }
    
           printf("\n");
    
        }
    
    }
    
     
    
    bool MazePath(MazeType &maze, PosType start, PosType end)
    
    {                               //求解迷宫maze中,从入口start到出口end的一条路径
    
        SqStack s;                  //定义栈
    
        SElemType e;            
    
        InitStack(s);               //初始化栈
    
        PosType curpos = start;             
    
        int curstep = 1;                                //探索第一步
    
        do {
    
           if (Pass(maze, curpos))
    
           {    //如果当前位置可以通过,即是未曾走到的通道块
    
               FootPrint(maze,
    curpos);                //留下足迹
    
               e = CreateSElem(curstep,
    curpos, 1);    //创建元素
    
               Push(s, e);                             //加入路径
    
               if (PosEqual(curpos,
    end))              //到达终点(出口)
    
                  return true;                        
    
               curpos = NextPos(curpos,
    1);            //获得下一节点
    
               curstep++;                              //探索下一步
    
           }
    
           else 
    
           {                                           //当前位置不能通过
    
               if (!StackEmpty(s))
    
               {
    
                  Pop(s, e);
    
                  while (e.di == 4
    && !StackEmpty(s)) //找寻了四个方向
    
                  {
    
                      MarkPrint(maze,
    e.seat);
    
                      Pop(s, e);                      //留下不能通过的标记,并退回一步
    
                  }
    
                  if (e.di<4)
    
                  {
    
                      e.di++;                         //换一个方向探索
    
                      Push(s, e);
    
                      curpos =
    NextPos(e.seat, e.di); //设定当前位置是该方向上的相邻块
    
                  }
    
               }
    
           }
    
        } while (!StackEmpty(s));
    
        return false;
    
    }
    
     
    
    
    

    主函数部分

    
    
    int main()                   //迷宫求解主函数
    
    {
    
        int i, j;                
    
        PosType start, end;      //开始,终点坐标
    
        MazeType maze;           
    
        int a[ROW][COL] = {                 //原始迷宫,其中'1'表示墙,'0'表示通道
    
           { 1,1,1,1,1,1,1,1,1,1 },
    
           { 1,0,0,1,0,0,0,1,0,1 },
    
           { 1,0,0,1,0,0,0,1,0,1 },
    
           { 1,0,0,0,0,1,1,0,0,1 },
    
           { 1,0,1,1,1,0,0,0,0,1 },
    
           { 1,0,0,0,1,0,0,0,0,1 },
    
           { 1,0,1,0,0,0,1,0,0,1 },
    
           { 1,0,1,1,1,0,1,1,0,1 },
    
           { 1,1,0,0,0,0,0,0,0,1 },
    
           { 1,1,1,1,1,1,1,1,1,1 }
    
        };
    
        printf("\n-------------------------------------------------\n");
    
        printf("\n原始迷宫如下:\n");
    
        printf("(其中'1'表示墙,'0'表示通道)\n");
    
        for (i = 0; i<10; i++)           //双重循环输出原始迷宫
    
        {
    
           for (j = 0; j<10; j++)
    
           {
    
               printf("%d ",
    a[i][j]);
    
           }
    
           printf("\n");
    
        }
    
        InitMaze(maze, a, ROW, COL);                 //初始化迷宫
    
        start.row = 1;                               //给定迷宫起点坐标
    
        start.col = 1;                               //(1,1)
    
        end.row = 8;                                 //给定迷宫终点坐标   
    
        end.col = 8;                                 //(8,8)
    
        if (MazePath(maze, start,
    end))              //如果找到一条路径
    
        {
    
           printf("\n-------------------------------------------------\n");
    
           printf("\n穷举法求解迷宫路径如下:\n");
    
           printf("(其中'*'表示求解路径,'@'表示死胡同)\n");
    
           PrintMaze(maze, ROW,
    COL);               //输出迷宫路径
    
        }
    
        else                                         //否则,没有通路
    
           printf("\n---------从入口到出口没有通路!-----\n");
    
    }
    
    
    

    三、运行结果
    迷宫求解

    附:源代码链接迷宫求解源代码

    展开全文
  • 用静态栈数据结构实现表达式求值

    千次阅读 2004-10-01 02:32:00
    用静态栈数据结构实现表达式求值一、题目: 当用户输入一个合法的表达式后,能够返回正确的结果。能够计算的运算符包括:加、减、乘、除、括号;能够计算的数要求在实数范围内。对于异常表达式给出错误提示。(要求...

    用静态栈数据结构实现表达式求值<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    一、题目:

        当用户输入一个合法的表达式后,能够返回正确的结果。能够计算的运算符包括:加、减、乘、除、括号;能够计算的数要求在实数范围内。对于异常表达式给出错误提示。(要求使用静态栈数据结构。)

    二、数据结构:

        数据对象:D={ ai |ai∈ElemSet,i=1,2,3,……,n,n≥0}

    数据关系:R={<ai-1,ai,)>| ai-1,ai ∈D, i=2,3,……,n}

                约定a1为栈底,an 为栈顶。

        基本操作:

                Push(&s,e)

            初始条件:栈s已经存在。

    操作结果:插入元素e为新的栈顶元素
    Pop(&s,&e)

            初始条件:栈s已经存在且非空。

            操作结果:删除s的栈顶元素,并用e返回其值

                .

    .

    .

    三、存储结构:

            typedef struct{

    <?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

    Array[N-1]

    ……

    Array[0]

    Top 

    ……

                int top;

                double array[N];

    }NumStack;             //存放实数的栈

    typedef struct{

     

                int top;

                char array[N];

    }OpStack;              //存放操作符的栈

    四、主要算法:(伪代码)

    #define N 50
    #define OK 1

    #define ERROR 0

    #include <ctype.h>

    #include <string.h>

    typedef struct{

        int top;

        double array[N];

    }NumStack;

    typedef struct{

        int top;

        char array[N];

    }OpStack;

    //把字符转换为相应的整数的函数

    int Cint(char mychar){

        return (mychar-48);

    }

    //数字进栈的函数

    status PushNum(NumStack &numstack,double num){

        if(numstack.top<N)

    {numstack.top++;

         numstack.array[numstack.top-1]=num;
         return OK;

    }

    else return ERROR;

    }

    //数字出栈的函数

    status PopNum(NumStack &numstack,double &num){

        if(numstack.top>0){

    num=numstack.array[numstack.top-1];

        numstack.top--;

        return OK;

    }

    else return ERROR;

     

    }

    //操作符进栈的函数

    status PushOp(OpStack &opstack,char &op){

        if(opstack.top<N){

    opstack.top++;

        opstack.array[opstack.top-1]=op;
        return OK;

    }

    else return ERROR;

    }

    //操作符出栈的函数

    status PopOp(OpStack &opstack,char &op){

    if(opstack.top>0){

    op=opstack.array[opstack.top-1];

        opstack.top--;

    return OK;

    }

    else return ERROR;

    }

    //进行运算的函数

    double Calc(double a,double b,char c){

        double result;

        switch(c){

            case '+':result=a+b;break;

            case '-':result=a-b;break;

            case '*':result=a*b;break;

            case '/':result=a/b;break;

        }

        return result;

    }

    //判断优先级的函数

    char Priority(char y,char x){

            char priority='<';

            switch(x){

                case '+':

                case '-':if(y=='(' || y=='#')priority='>';break;

                case '*':

                case '/':if(y=='(' || y=='#'|| y=='+' || y=='-')priority='>';break;

                case '(':priority='>';break;

                case ')':if(y=='(')priority='=';break;

                case '#':if(y=='#')priority='=';break;

                default:priority='E';

            }

            return priority;

    }

    //处理表达式的主体函数

    void Process(NumStack &numstack,OpStack &opstack,char x){

        double a,b;char c;

        static double tempnum=0.00000000;static int len=10;static int dot=0,flags=0;

        if(isdigit(x) || x=='.'){

            if(x=='.')dot=1;

            else{

                if(dot==0)

                    tempnum=tempnum*10+Cint(x);

                else{

                    tempnum=tempnum+(double)Cint(x)/len;

                    len*=10;

                }

            }

        }

        else{

            if(flags==0 && x!='('){PushNum(numstack,tempnum);tempnum=0.00000000;len=10;dot=0;}

            switch(Priority(opstack.array[opstack.top-1],x)){

                case '>':PushOp(opstack,x);flags=0;break;

                case '<':

                        PopOp(opstack,&c);

                        PopNum(numstack,&b);

                        PopNum(numstack,&a);

                        PushNum(numstack,Calc(a,b,c));flags=1;

                        Process(numstack,opstack,x);break;

                case '=':PopOp(opstack,&c);flags=1;break;

                default:printf("Wrong Express!");exit(0);

            }

        }

    }

    //main函数

    main(){

        NumStack numstack;OpStack opstack;char *s;int i=0;

        numstack.top=0;opstack.top=0;

        PushOp(&opstack,'#');

        printf("/nEnter your expression adn end it with #:");scanf("%s",s);

        for(i=0;i<strlen(s);i++)

        Process(&numstack,&opstack,s[i]);

        printf("The result is %f",numstack.array[numstack.top-1]);

    }

    五、测试数据:

    ignore....
    六、小结:

            这次实验难度较高,我做了几个版本。最初的一个版本由于只用了一个栈,导致不能算小数。第二个版本用的是输入一次处理一次,不能处理括号运算。这一个版本,我个人目前比较满意。代码只有92行,但是功能很完善,能够处理实数的加减乘除运算,乘除法运算无误差,能执行多重括号嵌套运算。并且对错误表达式也有一定的识别能力。


    附C语言的源代码:
        #define N 50
    #include <ctype.h>
    #include <string.h>
    typedef struct{
     int top;
     double array[N];
    }NumStack;
    typedef struct{
     int top;
     char array[N];
    }OpStack;
    int Cint(char mychar){
     return (mychar-48);
    }
    void PushNum(NumStack *numstack,double num){
     numstack->top++;
     numstack->array[numstack->top-1]=num;
    }
    void PopNum(NumStack *numstack,double *num){
     *num=numstack->array[numstack->top-1];
     numstack->top--;
    }
    void PushOp(OpStack *opstack,char op){
     opstack->top++;
     opstack->array[opstack->top-1]=op;
    }
    void PopOp(OpStack *opstack,char *op){
     *op=opstack->array[opstack->top-1];
     opstack->top--;
    }
    double Calc(double a,double b,char c){
     double result;
     switch(c){
      case '+':result=a+b;break;
      case '-':result=a-b;break;
      case '*':result=a*b;break;
      case '/':result=a/b;break;
     }
     return result;
    }
    char Priority(char y,char x){
      char priority='<';
      switch(x){
       case '+':
       case '-':if(y=='(' || y=='#')priority='>';break;
       case '*':
       case '/':if(y=='(' || y=='#'|| y=='+' || y=='-')priority='>';break;
       case '(':priority='>';break;
       case ')':if(y=='(')priority='=';break;
       case '#':if(y=='#')priority='=';break;
       default:priority='E';
      }
      return priority;
    }
    void Process(NumStack *numstack,OpStack *opstack,char x){
     double a,b;char c;
     static double tempnum=0.00000000;static int len=10;static int dot=0,flags=0;
     if(isdigit(x) || x=='.'){
      if(x=='.')dot=1;
      else{
       if(dot==0)
        tempnum=tempnum*10+Cint(x);
       else{
        tempnum=tempnum+(double)Cint(x)/len;
        len*=10;
       }
      }
     }
     else{
      if(flags==0 && x!='('){PushNum(numstack,tempnum);tempnum=0.00000000;len=10;dot=0;}
      switch(Priority(opstack->array[opstack->top-1],x)){
       case '>':PushOp(opstack,x);flags=0;break;
       case '<':
         PopOp(opstack,&c);
         PopNum(numstack,&b);
         PopNum(numstack,&a);
         PushNum(numstack,Calc(a,b,c));flags=1;
         Process(numstack,opstack,x);break;
       case '=':PopOp(opstack,&c);flags=1;break;
       default:printf("Wrong Express!");exit(0);
      }
     }
    }
    main(){
     NumStack numstack;OpStack opstack;char s[N];int i=0;
     numstack.top=0;opstack.top=0;
     PushOp(&opstack,'#');
     printf("/nEnter your expression and end it with #:");scanf("%s",s);
     for(i=0;i<strlen(s);i++)
     Process(&numstack,&opstack,s[i]);
     printf("The result is %f",numstack.array[numstack.top-1]);
           }

    展开全文
  •  主要考虑的是怎样记录的最小元素,尤其在某些元素出栈以后,由于不能遍历中的元素,因此可以利用另外一个辅助的来存放中现有所有元素的最小值,即在每次入栈的元素和当前辅助的栈顶元素比较,如果入栈...
  • 在用C语言实现栈结构,实现压栈、进栈操作的时候,会碰到满的情况,此时需要增加的大小,在C语言的代码中将要用到realloc();这个函数,发现对这个函数认识模糊,查了各种资料,发现网上网友总结的内容都非常模糊...
  • 优点:有序添加、增删改速度快,对于链表数据结构,增加和删除只要修改元素中的指针就可以了; 缺点:查询慢,如果要访问链表中一个元素,就需要从第一个元素开始查找; 如果应用需要经常插入和删除元素,就应该用...
  • C++数据结构——

    万次阅读 多人点赞 2018-06-25 21:54:49
    C++数据结构—— 最近计划再复习一遍数据结构,看到一篇博客:https://www.cnblogs.com/QG-whz/p/5170418.html#_label0。 1、(Stack)是一种线性存储结构,它具有如下特点: ...
  • 数据结构————2016_11_21

    万次阅读 多人点赞 2016-11-21 21:35:58
    //定义栈结构 typedef struct{ int * base; int * top; int stacksize; }SqStack; //初始化 void InitStack(SqStack * s){ s->base=(int *)malloc(stack_init_size*sizeof(int)); if(!s->base) exit(0); ...
  • 数据结构-和队列

    万次阅读 多人点赞 2012-06-19 12:53:15
    其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。如下所示: 结论:后进先出(Last In First Out),简称为LIFO线性表。 的基本运算有六种: 构造空栈:InitStack(S)、 判空: StackEmpty...
  • [数据结构]——单调

    万次阅读 多人点赞 2019-04-09 17:23:28
    笔者在做leetcode的题(下一个出现的最大数字)时,接触到了单调这一种数据结构,经过研究之后,发现单调在解决某些问题时出奇的好用,下面是对单调的性质和一些典型题目。 什么是单调? 从名字上就听的出来...
  • JavaScript数据结构结构

    千次阅读 多人点赞 2021-01-17 16:36:12
    JavaScript数据结构结构前言一、结构是什么?二、常见的结构使用:**函数调用**、**递归等**。三、使用步骤1.创建Stack类2.使用总结 前言 随着前端的兴起,JavaScript这门语言也越来越受欢迎。接下来,...
  • 栈的数据元素之间的一一对应的关系可以利用顺序的存储来表示, 那么可以利用数组来实现栈数据结构. // 栈的数组实现 struct stack_record; typedef struct stack_record * stack; stack init_stack(int max_...
  • 数据结构

    千次阅读 2020-06-21 18:23:48
    首先需要说明本文讨论的(Stack)是一种数据结构,而非用户态虚拟存储器中的空间结构。作为数据结构是一种特殊的线性表,其数据成员也与线性表一致。区别在于是后进先出的,而线性表允许在任意位置插入和...
  • 数据结构——的详解

    万次阅读 多人点赞 2020-04-20 00:02:43
    和队列是两种重要的线性结构,从数据结构的角度看,和队列也是线性表,其特殊性在于和队列的基本操作是线性表的子集。他们是操作受限的线性表,因此,可称为限定性的数据结构。但从数据类型角度看,他们是和...
  • 结构是一种非常常见的数据结构,并且在很多场景下也被用到。其实结构跟数组结构很像,只是在数组的基础上,对结构做了一些限制,本文我们将对其进行详细的介绍。 先点赞,再看博客,顺手可以点个关注。 微信...
  • 定义数据结构

    千次阅读 2017-02-21 16:06:58
    定义数据结构,请在该类型中实现一个能够得到最小元素的min函数。 本以为让自己实现数据结构Stack,一看别人提交的都是直接用java的。好吧,那就很简单了。 /** * 定义数据结构,请在该类型中实现一...
  • 【C语言】数据结构栈链式结构

    千次阅读 2018-06-04 21:45:28
    的链式结构 链表节点 typedef struct node { char c; // 数据 struct node *next; // 指针 }node, *pt; 栈顶指针 typedef struct stack { pt top; ...
  • 数据结构——

    千次阅读 2019-03-21 21:36:13
    是一种数据结构,今天我们先来理解下的定义,然后再看几个在现实开发中运用到的实例。 1. 什么是是一个具有“先进后出、后进先出”这种特点的数据结构。 从的结构图中可以看出,是一种“操作受限...
  • Swift数据结构——的实现

    千次阅读 2018-02-21 21:05:04
    栈数据结构示意图如下所示: 一、背景知识   从上面的示意图中,我们知道了栈是一种受限制的数据结构,它不像数组那样可以随机存取,只能在栈顶执行入栈和出栈操作,并且最先入栈的元素最后出栈,而最后入栈...
  • 数据结构之自建算法库——顺序

    千次阅读 2015-09-15 09:48:30
    本文针对数据结构基础系列网络课程(2):线性表中第3课时栈的顺序存储结构及其基本运算实现。...头文件:sqstack.h,包含定义顺序栈数据结构的代码、宏定义、要实现算法的函数的声明;#ifndef SQSTACK_H_INCLUDED #defi
  • 数据结构-

    千次阅读 2017-08-13 00:24:25
    栈栈的定义是一种特殊的线性表,仅允许在表的一端进行插入和删除运算。这一端被称为栈顶(top),相对地,把另一端称为底(bottom)。向一个插入新元素又称作进栈、入栈或压栈(push),它是把新元素放到栈顶...
  • 数据结构:八大数据结构分类

    万次阅读 多人点赞 2018-09-05 18:23:28
    常用的数据结构有:数组,,链表,队列,树,图,堆,散列表等,如图所示: 每一种数据结构都有着独特的数据存储方式,下面为大家介绍它们的结构和优缺点。 1、数组 数组是可以再内存中连续存储多个元素的...
  • 数据结构

    千次阅读 2015-10-30 19:36:18
     是只能通过访问它的一端来实现数据存储和检索的一种线性数据结构。换句话说,的修改是按先进后出的原则进行的。因此,又称为先进后出(FILO)的线性表。在中进行插入和删除操作的一端称为栈顶(top),...
  • 数据结构——篇】

    千次阅读 多人点赞 2020-10-11 08:45:31
    目录【数据结构——篇】一、的表示和操作的实现(一)的顺序存储——顺序1、顺序的表示和实现2、顺序的定义2、顺序初始化3、顺序入栈4、顺序出栈5、取顺序栈顶元素6、输出内容(二)的链式...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 72,524
精华内容 29,009
关键字:

栈数据结构

数据结构 订阅