• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

『初阶数据结构 • C语言』⑩ - 栈的概念和实现附完整源码

武飞扬头像
花想云
帮助1

学新通


学新通 

1.栈的概念及结构

栈存储数据的方式跟数组一样,都是将元素排成一行。只不过它还有以下 3 条约束。

  ● 只能在末尾插入数据。
  ● 只能读取末尾的数据。
  ● 只能移除末尾的数据。

你可以将栈看成一叠碟子:你只能看到最顶端那只碟子的碟面,其他都看不到。另外,要加碟子只能往上加,不能往中间塞,要拿碟子只能从上面拿,不能从中间拿(至少你不应该这么做)。绝大部分计算机科学家都把栈的末尾称为栈顶,把栈的开头称为栈底。

尽管这些约束看上去令人很拘束,但很快你就会发现它们带来的好处。

我们先从一个空栈开始演示。

往栈里插入数据,也叫作压栈。你可以想象把一个碟子压在其他碟子上的画面。

首先,将 5 压入栈中。

学新通接着,将 3 压入栈中。

学新通再将 0 压入栈中。

学新通

注意,每次压栈都是把数据加到栈顶(也就是栈的末尾)。如果想把 0 插入到栈底或中间,那是不允许的,因为这就是栈的特性:只能在末尾插入数据。

从栈顶移除数据叫作出栈。这也是栈的限制:只能移除末尾的数据。

来把栈中的一些数据弹出。

首先,弹出 0。 

学新通

接着,弹出 3。

学新通这就剩下 5了。 

学新通

总结:

栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据也在栈顶。 


2.栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

2.1栈的结构定义

  1.  
    typedef int STDataType;
  2.  
     
  3.  
    typedef struct Stack
  4.  
    {
  5.  
    STDataType* a; //动态开辟数组
  6.  
    int capacity; //记录栈的容量大小
  7.  
    int top; //记录栈顶的位置
  8.  
    }Stack;

2.2函数接口的实现

首先是在Stack.h文件中进行函数声明

Stack.h

  1.  
    #pragma once
  2.  
    #include<stdio.h>
  3.  
    #include<stdlib.h>
  4.  
    #include<assert.h>
  5.  
    #include<stdbool.h>
  6.  
     
  7.  
    typedef int STDataType;
  8.  
     
  9.  
    typedef struct Stack
  10.  
    {
  11.  
    STDataType* a; //动态开辟数组
  12.  
    int capacity; //记录栈的容量大小
  13.  
    int top; //记录栈顶的位置
  14.  
    }Stack;
  15.  
     
  16.  
    //栈的初始化
  17.  
    void StackInit(Stack* ps);
  18.  
    //释放动态开辟的内存
  19.  
    void StackDestroy(Stack* ps);
  20.  
    //压栈
  21.  
    void StackPush(Stack* ps, STDataType data);
  22.  
    //出栈
  23.  
    void StackPop(Stack* ps);
  24.  
    //读取栈顶的元素
  25.  
    STDataType StackTop(Stack* ps);
  26.  
    //判断栈是否为空
  27.  
    bool StackEmpty(Stack* ps);
  28.  
    //栈存储的数据个数
  29.  
    int StackSize(Stack* ps);

在Stack.c文件中进行函数的定义

Stack.c

  1.  
    #define _CRT_SECURE_NO_DEPRECATE 1
  2.  
    #include"Stack.h"
  3.  
     
  4.  
    void StackInit(Stack* ps)
  5.  
    {
  6.  
    assert(ps);
  7.  
    //初始化时,可附初值,也可置空
  8.  
    ps->a = NULL;
  9.  
    ps->capacity = 0;
  10.  
    ps->top = 0;
  11.  
    }
  12.  
     
  13.  
    void StackDestroy(Stack* ps)
  14.  
    {
  15.  
    assert(ps);
  16.  
    //若并未对ps->a申请内存,则无需释放
  17.  
    if (ps->capacity == 0)
  18.  
    return;
  19.  
    //释放
  20.  
    free(ps->a);
  21.  
    ps->a = NULL;
  22.  
    ps->capacity = ps->top = 0;
  23.  
    }
  24.  
     
  25.  
    void StackPush(Stack* ps,STDataType data)
  26.  
    {
  27.  
    assert(ps);
  28.  
    //若容量大小等于数据个数,则说明栈已满,需扩容
  29.  
    if (ps->capacity == ps->top)
  30.  
    {
  31.  
    //若为第一次扩容,则大小为4,否则每次扩大2倍
  32.  
    int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
  33.  
    STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
  34.  
    if (tmp == NULL)
  35.  
    {
  36.  
    perror("realloc fail");
  37.  
    exit(-1);
  38.  
    }
  39.  
     
  40.  
    ps->a = tmp;
  41.  
    ps->capacity = newCapacity;
  42.  
    }
  43.  
    //压栈
  44.  
    ps->a[ps->top] = data;
  45.  
    ps->top ;
  46.  
    }
  47.  
     
  48.  
    void StackPop(Stack* ps)
  49.  
    {
  50.  
    assert(ps);
  51.  
    assert(!StackEmpty(ps));
  52.  
    //出栈
  53.  
    ps->top--;
  54.  
    }
  55.  
     
  56.  
    STDataType StackTop(Stack* ps)
  57.  
    {
  58.  
    assert(ps);
  59.  
    assert(!StackEmpty(ps));
  60.  
    //返回栈顶的数据
  61.  
    return ps->a[ps->top - 1];
  62.  
    }
  63.  
     
  64.  
    bool StackEmpty(Stack* ps)
  65.  
    {
  66.  
    assert(ps);
  67.  
    //返回top
  68.  
    return ps->top == 0;
  69.  
    }
  70.  
     
  71.  
    int StackSize(Stack* ps)
  72.  
    {
  73.  
    assert(ps);
  74.  
    return ps->top;
  75.  
    }

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgggebk
系列文章
更多 icon
同类精品
更多 icon
继续加载