堆栈

来源:互联网 发布:sl会员商城源码 编辑:程序博客网 时间:2024/06/06 01:28

什么是堆栈

计算机如何进行表达式求值?

[例] 算术表达式5+6/2-3*4。正确理解: 5+6/2-3*4 = 5+3-3*4 = 8-3*4 = 8-12 = -4

由两类对象构成的:

1.运算数,如2、3、4

2.运算符号,如+、-、*、/

不同运算符号优先级不一样

后缀表达式

中缀表达式:运算符号位于两个运算数之间。如a + b*c - d/e

后缀表达式:运算符号位于两个运算数之后。如abc*+de/-

后缀表达式求值策略:从左向右“扫描”,逐个处理运算数和运算符号

启示:需要有种存储方法,能顺序存储运算数,并在需要时“倒序”输出!

堆栈的抽象数据类型描述

堆栈(Stack):具有一定操作约束的线性表,只在一端(栈顶,Top)做插入、删除

1.插入数据:入栈(Push)
2.删除数据:出栈(Pop)
特点:后入先出:Last In First Out(LIFO)

类型名称: 堆栈(Stack)

数据对象集:一个有0个或多个元素的线性表。

操作集:长度为MaxSize的堆栈S∈Stack,堆栈元素item∈ElementType

1、Stack CreateStack( int MaxSize ): 生成空堆栈,其最大长度为MaxSize;

2、int IsFull( Stack S, int MaxSize ):判断堆栈S是否已满;

3、int Push( Stack S, ElementType item ):将元素item压入堆栈;

4、int IsEmpty ( Stack S ):判断堆栈S是否为空;

5、ElementType Pop( Stack S ):删除并返回栈顶元素;

栈的顺序存储实现

    struct SNode {        ElementType *Data; /* 存储元素的数组 */        Position Top;      /* 栈顶指针 */        int MaxSize;       /* 堆栈最大容量 */    };    typedef struct SNode *Stack;         Stack CreateStack( int MaxSize )    {        Stack S = (Stack)malloc(sizeof(struct SNode));        S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));        S->Top = -1;        S->MaxSize = MaxSize;        return S;    }         int IsFull( Stack S )    {        return (S->Top == S->MaxSize-1);    }         int Push( Stack S, ElementType X )    {        if ( IsFull(S) ) {            printf("堆栈满");            return 0;        }        else {            S->Data[++(S->Top)] = X;            return 1;        }    }         int IsEmpty( Stack S )    {        return (S->Top == -1);    }         ElementType Pop( Stack S )    {        if ( IsEmpty(S) ) {            printf("堆栈空");            return ERROR; /* ERROR是ElementType的特殊值,标志错误 */        }        else             return ( S->Data[(S->Top)--] );    }

栈的链式存储实现

typedef struct SNode *Stack;    struct SNode {        ElementType Data;        SNode *Next;    };    Stack CreateStack( )     {         Stack S;        S = (Stack)malloc(sizeof(struct SNode));        S->Next = NULL;        return S;    }    int IsEmpty ( Stack S )    {         return ( S->Next == NULL );  /* 判断堆栈S是否为空*/    }         void Push( Stack S, ElementType X )    {         Stack TmpCell;  /* 将元素X压入堆栈S */             TmpCell = (Stack)malloc(sizeof(struct SNode));        TmpCell->Data = X;        TmpCell->Next = S->Next;        S->Next = TmpCell;     }         ElementType Pop( Stack S )  /* 删除并返回堆栈S的栈顶元素 */    {         Stack FirstCell;          ElementType TopElem;             if( IsEmpty(S) ) {            printf("堆栈空");             return ERROR;        }        else {            FirstCell = S->Next;             TopElem = FirstCell->Data;            S->Next = FirstCell->Next;            free(FirstCell);            return TopElem;        }    }

中缀表达式如何转换为后缀表达式

从头到尾读取中缀表达式的每个对象,对不同对象按不同的情况处理。
① 运算数:直接输出;
② 左括号:压入堆栈;
③ 右括号:将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出);
④ 运算符:
  •若优先级大于栈顶运算符时,则把它压栈;
  •若优先级小于等于栈顶运算符时,将栈顶运算符弹出并输出;再比较新的栈顶运算符,直到该运算符大于栈顶运算符优先级为止,然后将该运算符压栈;
⑤ 若各对象处理完毕,则把堆栈中存留的运算符一并输出。

中缀转换为后缀示例: ( 2*(9+6/3-5)+4)




1 0
原创粉丝点击