• 探索顺序结构:栈的实现方式


    🔑🔑博客主页:阿客不是客

    🍓🍓系列专栏:渐入佳境之数据结构与算法

    欢迎来到泊舟小课堂

    😘博客制作不易欢迎各位👍点赞+⭐收藏+➕关注

    ​​

    一、栈的定义

    栈(Stack)是一种常见的数据结构,它是一种“后进先出”(Last In First Out,LIFO)的数据结构。栈可以看做是一种特殊的线性表,只能在栈顶进行插入和删除操作。栈顶是允许操作的,而栈底是固定的。

    二、栈的分类

    当我们了解栈的定义之后,我们就能大概知晓其实现方式无非就是顺序表或者单链表。根据其实现方式,我们又能将栈分为顺序栈链式栈。

     因为单链表头插的效率O(1)明显比尾差O(N)更高,所以我们用单链表实现栈时最好以链表的头为栈顶。如果一定要以尾节点作为栈顶的话,最好以双向链表来实现。本章实现链表栈时以头节点作为栈顶。

    三、栈的声明

    3.1 顺序栈

    顺序栈的声明需要一个指向一块空间的指针a,指向栈顶下一个元素的top,以及标志栈大小的capacity。

    1. typedef int STDataType;
    2. typedef struct Stack
    3. {
    4. STDataType* a;//动态数组
    5. int top;//栈顶的后一个
    6. int capacity;//数组大小
    7. }ST;

    当然也有实现top指向当前栈顶元素的,只不过这时top初始化要为-1,这样才能在填入元素时刚好指向栈顶元素。

    3.2 链式栈

    链式栈的声明只需要一个top指针,以及栈的容量capacity。

    1. typedef struct SListNode
    2. {
    3. STDataType data;
    4. struct SListNode* next;
    5. }SListNode;
    6. typedef struct Stack
    7. {
    8. SListNode* top;
    9. int size;
    10. }Stack;

    四、栈的操作实现

    顺序栈与链式栈的初始化分别与顺序表,链表的初始化大致相同。顺序栈先预先分配一块空间,而链式栈可以先初始为NULL,我们本章节就以顺序栈为例来进行讲解

    4.1 栈的初始化

    1. void StackInit(ST* ps)
    2. {
    3. assert(ps);
    4. ps->a = NULL;
    5. ps->top = 0;
    6. ps->capacity = 0;
    7. }

    4.2 销毁栈

    1. void StackDestroy(ST* ps)
    2. {
    3. assert(ps);
    4. free(ps->a);
    5. ps->a = NULL;
    6. ps->top = ps->capacity = 0;
    7. }

    4.3 入栈

    1. void StackPush(ST* ps, STDataType x)
    2. {
    3. assert(ps);
    4. if (ps->top = ps->capacity)
    5. {
    6. STDataType newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    7. STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
    8. if (tmp == NULL)
    9. {
    10. perror("realloc fail");
    11. }
    12. ps->a = tmp;
    13. ps->capacity = newcapacity;
    14. }
    15. ps->a[ps->top] = x;
    16. ps->top++;
    17. }

    4.4 出栈

    1. void StackPop(ST* ps)
    2. {
    3. assert(ps);
    4. assert(ps->top > 0);
    5. ps->top--;
    6. }

    4.5 获取栈顶元素

    1. STDataType StackTop(ST* ps)
    2. {
    3. assert(ps);
    4. assert(ps->top > 0);
    5. return ps->a[ps->top - 1];
    6. }

    4.6 获取栈中有效元素个数

    1. int StackSize(ST* ps)
    2. {
    3. assert(ps);
    4. return ps->top;
    5. }

    4.7 检测栈是否为空

    1. bool StackEmpty(ST* ps)
    2. {
    3. assert(ps);
    4. return ps->top == 0;
    5. }

    注意:虽然出栈等操作代码简单,但也需要严格使用函数接口,尽可能避免自己写代码,否则容易造成结构混乱。

    五、完整代码

    5.1 Stack.h

    1. #include
    2. #include
    3. #include
    4. #include
    5. typedef int STDataType;
    6. typedef struct Stack
    7. {
    8. STDataType* a;//动态数组
    9. int top;//栈顶的后一个
    10. int capacity;//数组大小
    11. }ST;
    12. // 初始化栈
    13. void StackInit(ST* ps);
    14. // 销毁栈
    15. void StackDestroy(ST* ps);
    16. // 入栈
    17. void StackPush(ST* ps, STDataType data);
    18. // 出栈
    19. void StackPop(ST* ps);
    20. // 获取栈顶元素
    21. STDataType StackTop(ST* ps);
    22. // 获取栈中有效元素个数
    23. int StackSize(ST* ps);
    24. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
    25. bool StackEmpty(ST* ps);

    5.2 Stack.c

    1. #include"Stack.h"
    2. void StackInit(ST* ps)
    3. {
    4. assert(ps);
    5. ps->a = NULL;
    6. ps->top = 0;
    7. ps->capacity = 0;
    8. }
    9. void StackDestroy(ST* ps)
    10. {
    11. assert(ps);
    12. free(ps->a);
    13. ps->a = NULL;
    14. ps->top = ps->capacity = 0;
    15. }
    16. void StackPush(ST* ps, STDataType x)
    17. {
    18. assert(ps);
    19. if (ps->top = ps->capacity)
    20. {
    21. STDataType newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    22. STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
    23. if (tmp == NULL)
    24. {
    25. perror("realloc fail");
    26. }
    27. ps->a = tmp;
    28. ps->capacity = newcapacity;
    29. }
    30. ps->a[ps->top] = x;
    31. ps->top++;
    32. }
    33. void StackPop(ST* ps)
    34. {
    35. assert(ps);
    36. assert(ps->top > 0);
    37. ps->top--;
    38. }
    39. STDataType StackTop(ST* ps)
    40. {
    41. assert(ps);
    42. assert(ps->top > 0);
    43. return ps->a[ps->top - 1];
    44. }
    45. int StackSize(ST* ps)
    46. {
    47. assert(ps);
    48. return ps->top;
    49. }
    50. bool StackEmpty(ST* ps)
    51. {
    52. assert(ps);
    53. return ps->top == 0;
    54. }
  • 相关阅读:
    [PAT-Advanced] A1015 Reversible Primes (20)
    开发程序员的宝藏工具/网站
    wordpress使用category order and taxonomy terms order插件实现分类目录的拖拽排序
    Java多线程【锁优化与死锁】
    CD147单克隆抗体通过酰胺反应偶联到Dox-CMCh-BAPE聚合物胶束/CBZ-AAN-Dox的制备
    RK3399平台开发中安卓系统去除USB权限弹窗
    字节跳动测开实习生面试,拿15K过分吗?
    php实现抖音小程序支付
    thinkPHP框架详解+部署
    IO流~File
  • 原文地址:https://blog.csdn.net/x3262551980/article/details/138538523