《栈》

Posted xiangzhong-com

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《栈》相关的知识,希望对你有一定的参考价值。

《栈》

目录:

1.栈的定义

2.栈的抽象数据类型

3.顺序栈

4.链栈

 

1.栈的定义

  • 栈(Stack)是限定仅在表尾进行插入和删除的线性表。
  • 我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)
  • 不含任何数据元素的栈称为空栈
  • 栈为后进先出(Last In First Out)的线性表,简称LIFO结构。(如图1所示)

技术分享图片

图1

  • 栈的插入操作,叫做压入栈(push,或压栈
  • 栈的删除操作,叫做弹出栈(pop),或弹栈

 

2.栈的抽象数据类型

类型名称:堆栈(Stack).

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

操作集:对于一个具体的长度为正整数MaxSize的堆栈S属于Stack,记堆栈中的任意一个元素X属于ElementType,堆栈的基本操作主要有:

 

 

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

bool IsFull(Stack S);判断堆栈S是否已满。

bool IsEmpty(Stack S); 判断堆栈S是否是空。

bool Push(Stack S,ElementType X);入栈。

ElementType Pop(Stack S);出栈。

 

3.顺序栈

一. 栈的顺序存储实现

#include<stdio.h>

#include<stdlib.h>

 

#define true 1

#define ERROR 0

#define false 0

 

typedef int bool;

typedef int ElementType;

typedef int Position;

typedef struct SNode* PtrToSNode;

typedef PtrToSNode Sequence_Stack;

 

struct SNode

{

    ElementType* Data;//存储元素的数组

    Position top;//栈顶指针

    int MaxSize;//顺序栈的最大容量

};

 

Sequence_Stack CreateStack(int MaxSize);

bool IsFull(Sequence_Stack S);

bool IsEmpty(Sequence_Stack S);

bool Push(Sequence_Stack S,ElementType X);

ElementType Pop(Sequence_Stack S);

 

int main()

{

    printf("请您输入您要输入多少数!\\n");

    int n = 0;

    int i = 0;

    scanf("%d", &n);

    Sequence_Stack S = CreateStack(n);

    int m = 0;

    while(i < n)

    {

        scanf("%d", &m);

        Push(S,m);

        i++;

    }

    i = 0;

    

    while(i < n)

    {

        printf("%d\\n", Pop(S));

        i++;

    }

    

    return 0;

}

 

Sequence_Stack CreateStack(int MaxSize)

{

    Sequence_Stack S = (Sequence_Stack)malloc(sizeof(struct SNode));

    S->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType));

    S->top = -1;

    S->MaxSize = MaxSize;

    return S;

}

 

bool IsEmpty(Sequence_Stack S)

{

    if(S->top == -1)

    {

        return true;

    }

    else

    {

        return false;

    }

}

 

bool IsFull(Sequence_Stack S)

{

    if(S->top == S->MaxSize-1)

    {

        return true;

    }

    else

    {

        return false;

    }    

}

 

bool Push(Sequence_Stack S, ElementType X)

{

    if(IsFull(S))

    {

        printf("顺序栈满!\\n");

        return false;

    }

    else

    {

        S->top++;

        S->Data[S->top] = X;

        //简洁版:S->Data[++(S->top)] = X;

        return true;

    }

}

 

ElementType Pop(Sequence_Stack S)

{

    if(IsEmpty(S))

    {

        printf("顺序栈空!\\n");

        return false;

    }

    else

    {

        S->top--;

        return S->Data[S->top+1];

        //简洁版:return S->Data[(S->top)--];

    }

}

 

二. 栈的共享顺序存储实现

通常,当两个栈的空间需求有相反关系时,也就是一个栈增长时另一个栈在缩短的情况下,可以使用两栈共享空间。

 

#include<stdio.h>

#include<stdlib.h>

 

#define true 1

#define ERROR 0

#define false 0

 

typedef int bool;

typedef int ElementType;

typedef int Position;

typedef struct SNode* PtrToSNode;

typedef PtrToSNode Sequence_Share_Stack;

 

struct SNode

{

    ElementType* Data;//存储元素的数组

    Position top1;//堆栈1的栈顶指针

    Position top2;//堆栈2的栈顶指针

    int MaxSize;//顺序栈的最大容量

};

 

Sequence_Share_Stack CreateStack(int MaxSize);

bool Push(Sequence_Share_Stack S, ElementType X, int Tag);

ElementType Pop(Sequence_Share_Stack S, int Tag);

 

int main()

{

    //请读者根据自己的需求来完善代码,这里已经把共享栈搭建好了!

    return 0;

}

 

Sequence_Share_Stack CreateStack(int MaxSize)

{

    Sequence_Share_Stack S = (Sequence_Share_Stack)malloc(sizeof(struct SNode));

    S->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType));

    S->top1 = -1;

    S->top2 = S->MaxSize;

    S->MaxSize = MaxSize;

    return S;

}

 

bool Push(Sequence_Share_Stack S, ElementType X, int Tag)

{

    if(S->top2 - S->top1 == 1)

    {

        printf("共享栈满!\\n");

        return false;

    }

    else

    {

        if(Tag == 1)

        {

            S->Data[++(S->top1)] = X;     

        }

        else

        {

            S->Data[--(S->top2)] = X;

        }

        return true;

    }

}

 

ElementType Pop(Sequence_Share_Stack S, int Tag)

{

    if(Tag == 1)

    {

        if(S->top1 == -1)

        {

            printf("栈1空\\n");

        }

        else

        {

            return S->Data[(S->top1)--];

        }

    }

    else

    {

        if(S->top2 == S->MaxSize)

        {

            printf("栈2空\\n");

            

        }

        else

        {

            return S->Data[(S->top2)++];

        }

        

        

    }

}

 

4.链栈

栈的链式存储实现

//链栈基本结构已搭建好了,用斐波那契函数来完善了链栈的实现

#include<stdio.h>

#include<stdlib.h>

 

#define OK 1

#define ERROR 0

 

typedef int bool;

typedef int SElemType;

 

typedef struct StackNode

{

SElemType data;

struct StackNode *next;

}StackNode,*LinkStackPtr;

 

typedef struct

{

LinkStackPtr top; /*栈顶指针*/

int count; /* 链栈元素个数*/

}LinkStack;

 

LinkStack* InitStack();

bool Push(LinkStack *S,SElemType e);

bool Pop(LinkStack *S,SElemType *e);

int Fbi(int i);

void Fbistore();

 

int main()

{

    Fbistore();

 

 

return 0;

}

 

LinkStack* InitStack()

{

LinkStack* s = (LinkStack*)malloc(sizeof(LinkStack));

if(!s)

{

printf("内存分配失败!\\n");

return NULL;

}

memset(s, 0x00, sizeof(LinkStack));

 

return s;

}

//进栈

bool Push(LinkStack *S,SElemType e)

{

LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));

s->data=e;

s->next=S->top;    /* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */

S->top=s; /* 将新的结点s赋值给栈顶指针,见图中② */

S->count++;

return OK;

}

 

//出栈

bool Pop(LinkStack *S,SElemType *e)

{

LinkStackPtr p;

if(S->count == NULL)

return ERROR;

*e=S->top->data;

p=S->top;                    /* 将栈顶结点赋值给p,见图中③ */

S->top=S->top->next; /* 使得栈顶指针下移一位,指向后一结点,见图中④ */

free(p); /* 释放结点p */

S->count--;

return OK;

}

 

 

 

int Fbi(int i) /* 斐波那契的递归函数 */

{

    if( i < 2 )

        return i == 0 ? 0 : 1;

/* 这里Fbi就是函数自己,等于在调用自己 */

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

}

 

 

 

 

void Fbistore()

{

//初始化一个空栈

LinkStack* s = InitStack();

int a = 0;

    int m = 0, i = 0;

    scanf("%d", &m);

while(i <= m)

{

Push(s, Fbi(i));

        i++;

 

}

while(s->count != 0)

{

Pop(s, &a);

printf("%d ", a);

}

    printf("\\n");

}

 

接下来将发布栈的几个具体应用(表达式求值 迷宫问题)

以上是关于《栈》的主要内容,如果未能解决你的问题,请参考以下文章

虚拟内存[02] Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈

Android UICanvas 画布 ① ( Canvas 状态栈 | Canvas 状态栈入栈与出栈 | 获取 Canvas 状态栈容量 | Canvas 状态栈原点数据 )

数据结构笔记——栈

数据结构-栈(C++实现)

栈6:最小栈和最大栈3道题

栈文档之共享栈