注:不足及错误请指正

 +qq 1366963396讨论

栈(stack)时限定仅在表位进行插入和删除操作的线性表。

栈又称为后进先出的线性表。

一.顺序栈

//建栈

void CreatStack(stack* s)

{

    s->top = -1;

    int i = 1;

    int data;

    do

    {

        printf("请输入第%d个元素:\n",i);

        scanf("%d", &data);

        if (data != -1)

        {

            s->top++;

            s->data[s->top] = data;

        }

    i++;

    } while (i<=MAXSIZE&&data!=-1);

}

//设置空栈

void SetEmpty(stack* s)

{

    s->top = -1;

}

//判断是否空栈

bool IsEmpty(stack* s)

{

    return ((s->top >= 0) ? false : true);

}

//进栈

stack* StackPush(stack* s, int x)

{

    if (s->top == MAXSIZE - 1)//栈满

    {

        printf("OverFlow\n");

        return NULL;

    }

    else

    {

        s->top++;//栈顶加一

        s->data[s->top] = x;//新元素赋给栈顶空间

    }

    return s;

}

//出栈

int StackPop(stack* s)

{

    if (IsEmpty(s) == true)//是否为空栈

    {

        printf("underflow\n");

        return NULL;

    }

    else

    {

        return s->data[s->top--]; //栈顶出去,top--;

    }

}

//读取栈顶元素

int ShowTop(stack* s)

{

    if (IsEmpty(s))////是否为空栈

    {

        printf("underflow\n");

        return NULL;

    }

    else

    {

        return s->data[s->top];

    }

}

二.两栈共享空间

两栈共享空间

关键思路:

让一个栈的栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下标为数组长度n-1处。这样,如果两个栈增加元素,就是两端点向中间靠拢,只要top1和top2不见面,两个栈就可以一直使用。所以,当栈1为空时,栈1的top1为-1;而当栈2为空时,top2为n。反之,top1为n-1时,栈1满;top2为0时栈2满。更多的情况是两个栈顶之间相差1时,即top1+1==top2时为栈满。

//建栈

void CreatDoubleStack(doubleStack* s,int stackNumber)

{

    int i = 1;//计数

    int data;

    if (stackNumber == 1)//栈1

    {

        s->top1 = -1;

        do

        {

            printf("请输入栈1第%d个元素:", i);

            scanf("%d", &data);

            if (data!=-1)

                s->data[++s->top1] = data;//top+1后,data传进去

            i++;//计数

            } while (data != -1 && s->top1 + 1 != s->top2);//判断是否栈满

    }

if (stackNumber == 2)//栈2

{

    s->top2 = MAXSIZE;//栈2为空

    do

    {

        printf("请输入栈2第%d个元素:", i);

        scanf("%d", &data);

        if (data!=-1)

            s->data[--s->top2] = data;//data传进去

        i++;//计数

        } while (data!=-1&&s->top1+1!=s->top2);//判断栈是否为空

    }

}

//设置空栈

void SetEmpty(doubleStack* s,int stackNumber)

{

    if (stackNumber==1)

        s->top1 = -1;//栈1为空

    else

        s->top2 =MAXSIZE;//栈2为空

}

//判断是否为空栈

int IsEmpty(doubleStack* s,int stackNumber)

{

    if (stackNumber == 1)

    {

        if (s->top1 == -1)

        {

            return 1;//1表示栈1为空

        }

    }

    if (stackNumber == 2)

    {

        if (s->top2 == MAXSIZE)

            return 2;//2表示栈2为空

    }

    return 0;//0表示都不为空

}

//入栈

doubleStack* StackPush(doubleStack* s, int data, int stackNumber)

{

    if (s->top1+1==s->top2)//栈满

    {

        printf("overflow\n");

        return NULL;

    }

    if (stackNumber == 1)//进栈1

    {

        s->top1++;

        s->data[s->top1] = data;

    }

    else if (stackNumber == 2)//进栈2

    {

        s->data[--s->top2] = data;

    }

    return s;

}

//出栈

int StackPop(doubleStack* s, int stackNumber)

{

    if (stackNumber == 1)//出栈1

    {

        if (s->top1 == -1)//空栈

        {

            printf("Empty\n");

            return NULL;

        }

        return s->data[s->top1--];//不为空,出栈

    }

    if (stackNumber == 2)

    {

        if (s->top2 == MAXSIZE)

        {

            printf("underflow\n");

            return NULL;

        }

        return s->data[s->top2++];

    }

    return NULL;

}

三.链栈

struct StackNode//栈的节点

{

    int data;

    StackNode* next;

};

struct LinkStack//链栈

{

    StackNode* top;//栈顶

    int count;//计数

};

//初始化栈

void InitStack(LinkStack* S)

{

    S->top = NULL;

    S->count = 0;

}

//元素进栈

void LinkStackPush(LinkStack* S, int data)

{

    StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));

    newNode->data = data;

    newNode->next = S->top;//新节点指向top

    S->top = newNode;//top上移

    S->count++;

}

//判空栈

bool IsEmpty(LinkStack* S)

{

    if (S->top == NULL)

    return true;

    return false;

}

//元素出栈

int LinkStackPop(LinkStack* S, int data)

{

    if (IsEmpty(S))

    {

        return NULL;

    }

    StackNode* p = S->top;//复制top

    data = p->data;//保存top数据

    S->top = S->top->next;//top下移

    free(p);//释放原来的栈顶

    S->count--;

    return data;

}

//取栈顶元素

int ShowTop(LinkStack* S)

{

    if (IsEmpty(S))

    {

         return NULL;

    }

    return S->top->data;

}

//建栈

void CreatLinkStack(LinkStack* S)

{

    int data=0;

    int i=0;

    while (data != -1)//-1结束

    {

        printf("请输入第%d个元素:", ++i);

        scanf("%d", &data);

        if (data==-1)

            break;

        LinkStackPush(S, data);//入栈

    }

}

例:斐波那契数列(递归)

0    1    2    3    4    5    6    7    8    9

0    1    1    2    3    5    8    13   21  34

fbi(i)=fbi(i-1)+fbi(i-2)

int Fbi(int i)

{

    if (i < 2)

    return i == 1 ? 1 : 0;

    return Fbi(i - 1) + Fbi(i - 2);

}

递归函数定义:

把一个直接调用自己或通过一系列的调用语句间接的调用自己的函数,称为递归函数。

递归和栈的关系:

前面的例子我们可以看到递归是如何执行他的前行和退回阶段的。递归过程退回的顺序是它前行的逆序。在退回过程中,可能要执行某些动作,包括恢复在前行过程中存储起来的数据。

这种存储数据,并在后面又以存储的逆序恢复这些数据,显然很符合栈这样的数据结构。因此,编译器使用栈实现了递归。

栈应用:

四则运算表达式求值:

中缀表达式:标准的四则运算表达式。

后缀表达式(逆波兰表达式):

例如:9+(3-1)*3+10/2(中缀)

           9 3 1 - 3 * 10 2 / +(后缀);

后缀表达式计算规则:

从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到符号,就将处于栈顶的两个数字出栈,进行运算,运算结果进栈,直到获得最终结果。

中后缀转换规则:

从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级不高于栈顶符号(乘除优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,直到最终输出后缀表达式为止。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 记得大一的时候自学数据结构,那时候却没有深入的去研究代码,只是了解了个表面的东西,不过还好有基础,并且去年的时候看...
    KevinCool阅读 611评论 1 3
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 2,027评论 0 2
  • 【今日小作业】主题格式:Day20_忽悠【心态管理—建立良好的职业心态】 1、通过学习,评价一下你现在的工作状态?...
    忽悠小朋友阅读 192评论 0 0
  • 峡迩阅读 123评论 0 0
  • 来自:数据观https://www.shujuguan.cn/?from=jianshu 技术的世界正在爆炸式发展...
    数据观数据分析平台阅读 309评论 0 1