数据结构(寒假小结)--3.1桟

来源:互联网 发布:手机贴膜品牌 知乎 编辑:程序博客网 时间:2024/06/18 10:35

1.本节学习要点:

2.基本定义及相关名词:


栈(Stack):限制在表的一端进行插入删除运算的线性表

  1. 空栈:当表中没有元素时。

  2. 栈顶(Top):插入、删除的一端;栈底(Bottom):另一端。

  3. 栈为后进先出(Last In First Out)的线性表,简称为LIFO表

  4. 上溢:当栈满时再进栈必定产生空间溢出,简称“上溢”;上溢是一种出错状态,应该设法避免;
  5. 下溢:当栈空时再退栈也将产生溢出,简称“下溢”;下溢则可能是正常现象,因为栈初态或终态都是空,下溢常作程序控制转移的条件

3.桟的基本运算:

  • 初始化INITIATE(S):构造一个空栈S。
  • 判栈空EMPTY(S):若栈S空,返回1,否则返回0。
  • 进栈PUSH(S, x):在栈顶插入(压入)元素x,x 成为新的栈顶。
  • 退栈POP(S):将栈顶元素删除(弹出),并返回该元素。
  • 取栈顶GETTOP(S):取栈顶元素,但不删除它。

4.顺序桟

顺序栈:栈的顺序存储结构,运算受限的顺序表

  1. 用数组来实现

  2. 栈底位置不变,可设在数组两端的任何一端;

  3. 栈顶位置随进栈、退栈而变,需用一个整型变量top指示  当前位置,通常称top为栈顶指针。
  4. 栈空:top=-1;栈满:top=maxsize-1;

顺序桟的基本运算:

typedef int datatype; //栈元素类型,假设为整型const int maxsize=100; //栈容量typedef struct {   datatype data[maxsize];   int top;} sqstack;//顺序栈类型//初始化void init_sqstack(sqstack *sq) {  sq–>top=-1;}//判空int empty_sqstack(sqstack *sq) {   if(sq−>top==−1) return 1;   else return 0;}//进桟int push_sqstack(sqstack *sq,datatype x) {  if(sq−>top==maxsize−1)    {cout<<"栈满,不能进栈!\n"; return 0;} //上溢  else    {sq−>data[++sq−>top]=x; return 1;}}//退桟int pop_sqstack(sqstack *sq,datatype *x) {  if(sq−>top==−1)    {cout<<"栈空,不能退栈!\n"; return 0;}//下溢  else    {*x=sq−>data[sq−>top−−]; return 1;}}//取桟顶int gettop_sqstack(sqstack *sq,datatype *x) {  if(sq−>top==−1)    {cout<<"栈空,无栈顶可取!\n"; return 0;}  else     {*x=sq−>data[sq−>top]; return 1;}}

5.链表

链栈:栈的链式存储结构,运算受限的单链表。

链桟的基本运算:

typedef struct node * pointer; struct node {   datatype data;   pointer next;}; //链栈结点类型typedef struct {   pointer top;} lkstack;//链栈类型//初始化void init_lkstack(lkstack *ls) {   ls−>top=NULL;}//判空int empty_lkstack(lkstack *ls) {    if(ls−>top==NULL) return 1;   else return 0;}//进桟void push_lkstack(lkstack *ls,datatype x) {    pointer p;  p=new node;        //申请新结点*p  p−>data=x;        //新结点data域装入x的值  p−>next=ls−>top;    //新结点next为原栈顶  ls−>top=p;        //新结点为新栈顶}//退桟int pop_lkstack(lkstack *ls,datatype *x) {  pointer p;  if(ls−>top==NULL)    {cout<<”栈空,不能退栈!\n”; return 0;}//下溢  else    {p=ls−>top; *x=p−>data; ls−>top=p−>next;     delete p; return 1;}}//取桟顶int gettop_lkstack(lkstack *ls,datatype *x) {  if(ls−>top==NULL)   {cout<<”栈空,无栈顶可取!\n”;return 0;}//栈空  else   {*x=ls−>top−>data; return 1;}}

6.顺序桟与链桟的比较

时间性能:相同,都是常数时间O(1)。
空间性能:
顺序栈:有元素个数的限制和空间浪费的问题。
链栈:没有栈满的问题,只有当内存没有可用空间时才会出现栈满,但是每个元素都需要一个指针域,从而产生了结构性开销。
PS:栈的使用过程中元素个数变化较大时,用链栈是适宜的,反之,应该采用顺序栈

7.桟的应用

1.递归

#include<stdio.h>long f(int 3){   if(n==0) return 1;   else return n*f(n−1);}void main(){    //求f(3);    printf("f(3)=",f(3));}


2.表达式求值

(迂者-贺利坚老师写得挺好,偷懒大笑

#include <stdio.h>#include <stdlib.h>#define MaxOp 100#define MaxSize 100struct  //设定运算符优先级{    char ch;   //运算符    int pri;   //优先级}lpri[]= {{'=',0},{'(',1},{'*',5},{'/',5},{'+',3},{'-',3},{')',6}},//左运算符op的优先级rpri[]= {{'=',0},{'(',6},{'*',4},{'/',4},{'+',2},{'-',2},{')',1}};//右运算符op的优先级int leftpri(char op)    //求左运算符op的优先级{    int i;    for (i=0; i<MaxOp; i++)        if (lpri[i].ch==op)            return lpri[i].pri;}int rightpri(char op)  //求右运算符op的优先级{    int i;    for (i=0; i<MaxOp; i++)        if (rpri[i].ch==op)            return rpri[i].pri;}bool InOp(char ch)       //判断ch是否为运算符{    if (ch=='(' || ch==')' || ch=='+' || ch=='-'            || ch=='*' || ch=='/')        return true;    else        return false;}int Precede(char op1,char op2)  //op1和op2运算符优先级的比较结果{    if (leftpri(op1)==rightpri(op2))        return 0;    else if (leftpri(op1)<rightpri(op2))        return -1;    else        return 1;}void trans(char *exp,char postexp[])//将算术表达式exp转换成后缀表达式postexp{    struct    {        char data[MaxSize]; //存放运算符        int top;            //栈指针    } op;               //定义运算符栈    int i=0;                //i作为postexp的下标    op.top=-1;    op.top++;                  //将'='进栈    op.data[op.top]='=';    while (*exp!='\0')      //exp表达式未扫描完时循环    {        if (!InOp(*exp))        //为数字字符的情况        {            while (*exp>='0' && *exp<='9') //判定为数字            {                postexp[i++]=*exp;                exp++;            }            postexp[i++]='#';   //用#标识一个数值串结束        }        else    //为运算符的情况            switch(Precede(op.data[op.top],*exp))            {            case -1:           //栈顶运算符的优先级低:进栈                op.top++;                op.data[op.top]=*exp;                exp++;     //继续扫描其他字符                break;            case 0:        //只有括号满足这种情况                op.top--;      //将(退栈                exp++;     //继续扫描其他字符                break;            case 1:             //退栈并输出到postexp中                postexp[i++]=op.data[op.top];                op.top--;                break;            }    } //while (*exp!='\0')    while (op.data[op.top]!='=')    //此时exp扫描完毕,退栈到'='为止    {        postexp[i++]=op.data[op.top];        op.top--;    }    postexp[i]='\0';    //给postexp表达式添加结束标识}float compvalue(char exp[]) //计算后缀表达式的值{    struct    {        float data[MaxSize];    //存放数值        int top;            //栈指针    } st;               //定义数值栈    float d;    char ch;    int t=0; //t作为exp的下标    st.top=-1;    ch=exp[t];    t++;    while (ch!='\0')    //exp字符串未扫描完时循环    {        switch (ch)        {        case'+':            st.data[st.top-1]=st.data[st.top-1]+st.data[st.top];            st.top--;            break;        case '-':            st.data[st.top-1]=st.data[st.top-1]-st.data[st.top];            st.top--;            break;        case '*':            st.data[st.top-1]=st.data[st.top-1]*st.data[st.top];            st.top--;            break;        case '/':            if (st.data[st.top]!=0)                st.data[st.top-1]=st.data[st.top-1]/st.data[st.top];            else            {                printf("\n\t除零错误!\n");                exit(0);  //异常退出            }            st.top--;            break;        default:            d=0; //将数字字符转换成数值存放到d中            while (ch>='0' && ch<='9')   //为数字字符            {                d=10*d+ch-'0';                ch=exp[t];                t++;            }            st.top++;            st.data[st.top]=d;        }        ch=exp[t];        t++;    }    return st.data[st.top];}int main(){    char exp[]="(56-20)/(4+2)"; //可将exp改为键盘输入    char postexp[MaxSize];    trans(exp,postexp);    printf("中缀表达式:%s\n",exp);    printf("后缀表达式:%s\n",postexp);    printf("表达式的值:%g\n",compvalue(postexp));    return 0;}

如果有错误请大家指出,共同学习共同进步!更多百度百科奋斗奋斗








1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 耳机戴不住总掉怎么办 眼睛被辣椒辣了怎么办 电信光猫复位后怎么办 电信光猫重置了怎么办 u盘无法安全弹出怎么办 u盘不能安全弹出怎么办 真空杯不保温了怎么办 锅底外面烧黑了怎么办 锅底里面烧黑了怎么办 佳能50镜头跑焦怎么办 g7x镜头进灰了怎么办 leica镜头进灰了怎么办 请问喉咙痒咳嗽该怎么办 喉咙痒咳嗽有痰怎么办 痒咳嗽停不下来怎么办 嗓子疼咳嗽有痰怎么办 上火了喉咙干痒怎么办 喉咙里总是有痰怎么办 1岁宝宝喉咙有痰怎么办 嗓子总感觉有痰怎么办 嗓子痒感觉有痰怎么办 1岁宝宝嗓子有痰怎么办 3岁宝宝嗓子有痰怎么办 喉咙总感觉有痰怎么办 感冒了喉咙有痰怎么办 咽喉有异物感是怎么办 老感觉喉咙有痰怎么办 感冒有痰怎么办最有效 感冒快好了有痰怎么办 喉咙里一直有痰怎么办 一到晚上就咳嗽怎么办 1岁宝宝咳嗽痰多怎么办 3岁宝宝咳嗽痰多怎么办 六岁儿童咳嗽有痰怎么办 很多白痰在喉咙怎么办 我喉咙总是有痰怎么办 喉咙老感觉有痰怎么办 喉咙痒老是有痰怎么办 抽烟多了嗓子疼怎么办 抽烟多了老咳嗽怎么办 抽烟抽多了咳嗽怎么办