10. 栈

一、什么是栈

  (Stack)是一种 后入先出(FILO - First In Last Out)的有序列表。栈中的元素的插入和删除只能在线性表的同一端进行,该位置是表的末端,叫做栈的顶。对栈的基本操作有 进栈(Push) 和 出栈(Pop),前者相当于插入,后者是删除最后插入的元素。栈有时又叫做 后进先出表(FIFO)。根据栈的定义可知,最先放入栈中元素在栈低,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素先删除,最先放入的元素最后删除。

栈

ADT Stack
{
Data:
    栈S∈Stack, 栈顶元素Item∈ElementType;
Operation:
    Stack CreateStack(void);                    // 生成一个空的栈
    int IsEmpty(Stack PtrS);                    // 栈是否为空
    void Push(Stack PtrS, ElementType Item);    // 压栈
    ElementType Pop(Stack PtrS);                // 出栈
    ElementType Peek(Stack PtrS);               // 查看栈顶元素
} ADT Stack;

二、栈的顺序存储实现

2.1、栈的顺序存储

顺序栈

#define MAX_SIZE 10

typedef int ElementType;

typedef struct QNode
{
    int Data[MAX_SIZE];
    int Front;
    int Rear;
}QNode, * Queue;

2.2、创建空的栈

/**
 * @brief 生成一个栈
 * 
 * @return Stack 生成的栈
 */
Stack CreateStack(void)
{
    Stack PtrS = (Stack)malloc(sizeof(SNode));
    PtrS->Top = -1;
    return PtrS;
}

2.3、判断栈是否为空

/**
 * @brief 栈是否空
 * 
 * @param PtrS 栈
 * @return int 0: 栈非空; 1: 栈空;
 */
int IsEmpty(Stack PtrS)
{
    return PtrS->Top == -1;
}

2.4、压栈

/**
 * @brief 压栈
 * 
 * @param PtrS 栈 
 * @param Item 要压栈的元素
 */
void Push(Stack PtrS, ElementType Item)
{
    if (PtrS->Top == MAX_SIZE - 1)
    {
        printf("栈已满!\n");
        return;
    }
  
    PtrS->Data[++PtrS->Top] = Item;
}

2.5、出栈

/**
 * @brief 出栈
 * 
 * @param PtrS 栈 
 * @return ElementType 要出栈的元素 
 */
ElementType Pop(Stack PtrS)
{
    if (PtrS->Top == -1)
    {
        printf("栈已空!\n");
        return;
    }
    return PtrS->Data[PtrS->Top--];  
}

2.6、获取栈顶元素

/**
 * @brief 获取栈顶元素
 * 
 * @param PtrS 栈
 * @return ElementType 栈顶的元素
 */
ElementType Peek(Stack PtrS)
{
    if (PtrS->Top == -1)
    {
        printf("栈已空!\n");
        return NULL;
    }
    return PtrS->Data[PtrS->Top];  
}

2.7、遍历栈

/**
 * @brief 遍历栈中的元素
 * 
 * @param PtrS 
 */
void PrintStack(Stack PtrS)
{
    for (int i = 0; i <= PtrS->Top; i++)
    {
        printf("%d ", PtrS->Data[i]);
    }
    printf("\n");
}

三、栈的链式存储实现

3.1、栈的链式存储

链栈

typedef int ElementType;

typedef struct SNode
{
    ElementType Data;
    struct SNode * Next;
}SNode, * Stack;

3.2、创建空的栈

/**
 * @brief 创建空栈
 * 
 * @return Stack 指向带头节点的空栈
 */
Stack CreateStack(void)
{
    Stack PtrS = (Stack)malloc(sizeof(SNode));
    PtrS->Data = 0;
    PtrS->Next = NULL;
    return PtrS;
}

3.3、 判断栈是否为空

/**
 * @brief 判断栈是否为空
 * 
 * @param S 栈
 * @return int 0: 栈非空; 1: 栈为空
 */
int IsEmpty(Stack PtrS)
{
    return PtrS->Next == NULL;
}

3.4、压栈

/**
 * @brief 压栈
 * 
 * @param PtrS 栈 
 * @param Item 要压栈的元素
 */
void Push(Stack PtrS, ElementType Item)
{
    Stack  NewNode = (SNode *)malloc(sizeof(SNode));
    NewNode->Data = Item;
    NewNode->Next = PtrS->Next;
    PtrS->Next = NewNode;
}

3.5、出栈

/**
 * @brief 出栈
 * 
 * @param PtrS 栈
 * @return ElementType 出栈的元素
 */
ElementType Pop(Stack PtrS)
{
    Stack Item = NULL;
    ElementType ItemData = 0;

    if (PtrS->Next == NULL)
    {
        printf("栈为空\n");
        return NULL;
    }

    Item = PtrS->Next;
    ItemData = Item->Data;
    PtrS->Next = Item->Next;
    free(Item);

    return ItemData;
}

3.6、获取栈顶元素

/**
 * @brief 获取栈顶元素
 * 
 * @param PtrS 栈
 * @return ElementType 栈顶的元素
 */
ElementType Peek(Stack PtrS)
{
    Stack Item = NULL;
    ElementType ItemData = 0;

    if (PtrS->Next == NULL)
    {
        printf("栈为空\n");
        return NULL;
    }

    return PtrS->Next->Data;
}

3.7、遍历栈

/**
 * @brief 遍历栈
 * 
 * @param PtrS 栈
 */
void PrintStack(Stack PtrS)
{
    if (PtrS == NULL)
    {
        return;
    }
  
    Stack Ptr = PtrS->Next;
    while (Ptr != NULL)
    {
        printf("%d ", Ptr->Data);
        Ptr = Ptr->Next;
    }
    printf("\n");
}
posted @ 2023-07-03 19:30  星光樱梦  阅读(110)  评论(0编辑  收藏  举报