栈 学习笔记&&总结

栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈的顶。对栈的基本操作有Push(进栈)和 Pop(出栈),前者相当于插入,后者则是删除最后插入的元素。所以栈有时叫做LIFO(后进先出)表。

PART 1 栈的基本了解
对栈的第一次接触也是在C语言的学习中。不同的数据存放的方式不同,使用的机制也相应不同。普通函数的调用,递归等都要用到栈。
对栈的实现有两种方法,一种方法使用指针,而另一种方法则是使用数组。

用指针实现,则是使用链表。通过之前的学习知道,链表有头部和尾部,那么如果要用链表,显然应该用头部来作为栈表的顶。因为我们使用的是单向链表,如果要用尾部作为栈的顶,就必须知道倒数第二个结点和尾部结点的指针,操作起来是相对麻烦而且费时的。因为链表的头部将会一直存在,否则整个链表将不复存在,所以用头部来作为顶,更加简单。

代码实现:
1.构建结构体

struct Node
{
    ElementType Element;                 //数据域
    struct Node *Next;    //建立指针
}

2.创建一个空栈的例程

Stack
CreatStack( void )
{
    Stack S;
    S = malloc( sizeof( struct Node));   //新建动态结构体
    if( S == NULL )
        FatalError( "Out of space !!!");
    S->Next == NULL;
    MakeEmpty(S);
    return S;
}
void
MakeEmpty( Stack S )
{
    if( S == NULL )
        Error( "Must use CreateStack first" );
    else
        while( !IsEmpty( S ))        //如果非空,就将数据Pop出
            Pop(S);
}

3.检测栈是否是空栈

int 
IsEmpty( Stack S )
{
    return S->Next == NULL;   //返回 判断S->是否指向NULL的bool值
}   

4.Push进栈的例程

void
Push( ElementType X, Stack S)
{
    PtrToNode TmpCell;                                   
    TmpCell = malloc( sizeof( struct Node) );   //创建动态结构体
    if( TmpCell == NULL )
        FatalError(" Out of space !!!");
    else
    {
        TmpCell->Element = X;                  //进行Push操作
        TmpCell->Next = S->Next;
        S->Next = TmpCell;
    }
}   

5.从栈弹出元素的例程

void
Pop( Stack S )
{
    PtrToNode FirstCell;
    if( IsEmpty( S ) )                                //判断其是否为空栈
        Error( "Empty stack");
    else
    {
        FirstCell = S->Next;                          //进行Pop操作
        S->Next = S->Next->Next;
        free( FirstCell);
    }
}

第二个方法就是通过数组来实现。

如果要使用数组,我认为有以下几个需要注意的地方。
1.必须声明数组的大小,在一直最大数量的情况下进行操作。
2.只能通过数组创建同类型数据的栈表,最好使用结构体来实现。
3.在数据庞大的情况下可能会造成数值溢出。

通过数组实现的思想大概与链表相同。但是数组的存储方式是连续的,通常情况下我们可以直接通过访问下表的方式来访问数组中的成员。但是此例中我们必须判断此表是否为空表。所以还是必须在结构体中用到指针。
下面列出部分与链表差异较大的代码。
1.结构体的建立

struct StackRecord
{
    int Capacity;
    int TopOfStack;                      //栈表的顶
    ElementType *Array;
}

2.栈的创建

Stack
CreateStack(int MaxElemnts)                 //定义一个变量记录最大成员个数
{
    stack S;
    if(MaxElemnts < MinStackSize)            //将最大成员个数和数组大小比较
        Error("Stack is too small");
    S = malloc( sizeof( struct StackRecord));  //申请动态内存内存
    if(s == NULL)
        FatalError("Out of space!!!");
    S->Array = malloc (sizeof(ElementType) * MaxElements);  //将指针指向数组末尾
    if(S->Array == NULL)
        FatalError("Out of space!!!");
    S->Capacity = MaxElements;            
    MakeEmpty(S);
    return S;         //返回建立好的数组
}

数组实现,源代码

#include<iostream>
#include<cstdlib>
using namespace std;

typedef struct StackRecord
{
    int Capacity;
    int TopOfStack;
    char *Array;
}Stack;
Stack CreateStack(void);
void DisposeStack(Stack S);
Stack Push(char X, Stack S);
Stack Pop(Stack S);
char TopandPop(Stack S); 

//定义全局变量
int MaxElements = 20; 
int MinStackSize = 25;
int count = 0;

int IsEmpty(Stack S)           //判断栈是否为空 
{
    return S.TopOfStack == -1;

}
int IsFull(Stack S)  //判断栈是否为满 
{
    return count == MaxElements;
}

int main()
{   Stack S;
    S = CreateStack();
    int i = 1;
    char X;
    while(i)
    {
        cout << "Please enter 1 to push, 2 to pop, 0 to end:" << endl;
        cin >> i;
        if(i == 1)
        {
            cout << "Please Input the Element:" << endl;
            cin >> X;
            S = Push(X, S);

        }
        if(i == 2)
        {
            S = Pop(S);
        }
    }

    return 0;
}



Stack CreateStack(void)      //创建栈 
{
    if(MaxElements >= MinStackSize)
    {
        cout << "This Stack is too small" << endl;
        exit(1);
    }
    Stack S;
    S.Array = (char*)malloc(sizeof(char)*MaxElements);  //创建动态数组 
    if(S.Array == NULL)
    {
        cout << "out of space!!" << endl;
        exit(1);
    }
    S.Capacity = MaxElements;
    S.TopOfStack = -1;            //MakeEmpty
    return S; 
}
void DisposeStack(Stack S)      //释放动态内存 
{
    if(S.Array != NULL)
    {
        free(S.Array);         //先释放动态数组
     } 
}

Stack Push(char X, Stack S)
{
    if(!IsFull(S))
    {
        S.Array[++(S.TopOfStack)] = X; //随着push操作,TopOfStack往后移 
        count++;
        return S;
    }
    else
    {
        cout << "out of space !!" << endl;
        DisposeStack(S);
        exit(1);
     } 
} 

Stack Pop(Stack S)
{
    if(!IsEmpty(S))
    {
        cout << S.Array[S.TopOfStack--] << endl;
        return S;
    }
    else
    {
        cout << "This Strack is Empty!" <<endl;
        DisposeStack(S);
        exit(1);
    }
}

PART2 栈的应用
1.平衡符合
用栈的方法编代码查找源代码中符号错误匹配
2.后缀表达式
在之前的计算中我们常用形式一般是4.99+5.99+6.99*1.06
但是利用栈可以将其转化成后缀表达式或逆波兰记法。
形如 4.99 1.06 * 5.99+6.99 1.06 * +

这里写图片描述

3.函数调用

总结

理解…继续理解…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值