• 详解【数据结构】栈和队列


    目录

    1.栈

    1. 什么是栈?如何理解栈?

    2.栈的实现;

    一. 创建结构体变量;初始化栈

    二. 出栈 入栈 显示栈顶元素 等函数的实现;

    三. 销毁栈;

    四. 检验案例

    2.队列

    1.什么是队列?如何理解队列?

     2.队列的实现

    一. 创建结构体变量,初始化队列;

    二. 头删 头插 头查 尾查 等函数的实现;

    三 . 队列的销毁;

    四. 测试案例;


    1.栈

    1. 什么是栈?如何理解栈?

    栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来),。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。

    按图示来理解就是: 

    2.栈的实现;

    一. 创建结构体变量;初始化栈

    1. typedef struct Stack
    2. {
    3. int* a;
    4. int top; // 栈顶
    5. int capacity; // 容量
    6. }Stack;
    7. void StackInit(Stack* SL)
    8. {
    9. assert(SL);
    10. SL->a =NULL;
    11. SL->capacity = 0;
    12. SL->top = 0;
    13. }

    二. 出栈 入栈 显示栈顶元素 等函数的实现;

    1. //入栈
    2. void StackPush(Stack* SL,int x);
    3. //出栈
    4. void StackPop(Stack* SL);
    5. // 打印
    6. void StackPrintf(Stack SL);
    7. //获取栈顶元素
    8. int StackFront(Stack SL);
    9. //获取栈中有效元素的个数
    10. int StackSize(Stack SL);
    11. //检查栈是否为空 为空 返回 1 不为空 返回 0
    12. int StackEmpty(Stack SL);
    13. void StackPush(Stack* SL,int x)
    14. {
    15. assert(SL);
    16. if(SL->top == SL->capacity)
    17. {
    18. int newcapacity = SL->capacity == 0 ? 4 : (SL->capacity) * 2;
    19. int* newnode = (int*)realloc(SL->a, sizeof(int) * newcapacity);
    20. if (newnode == NULL)
    21. {
    22. perror("realloc fail");
    23. exit(-1);
    24. }
    25. SL->a = newnode;
    26. SL->capacity = newcapacity;
    27. }
    28. SL->a[SL->top] = x;
    29. SL->top++;
    30. }
    31. void StackPop(Stack* SL)
    32. {
    33. assert(SL);
    34. if (SL->top <= 0)
    35. {
    36. return;
    37. }
    38. else
    39. SL->top--;
    40. }
    41. void StackPrintf(Stack SL)
    42. {
    43. int i = 0;
    44. for (i = 0; i < SL.top; i++)
    45. {
    46. printf("%d ", SL.a[i]);
    47. }
    48. printf("\n");
    49. }
    50. int StackFront(Stack SL)
    51. {
    52. return SL.a[SL.top - 1];
    53. }
    54. int StackSize(Stack SL)
    55. {
    56. int i = 0;
    57. int n = 0;
    58. for (i = 0; i < SL.top; i++)
    59. {
    60. n++;
    61. }
    62. return n;
    63. }
    64. int StackEmpty(Stack SL)
    65. {
    66. return SL.top == 0;
    67. }

    三. 销毁栈;

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

    四. 检验案例

    1. #include"标头.h"
    2. test()
    3. {
    4. Stack SL;
    5. StackInit(&SL);
    6. StackPush(&SL, 2);
    7. StackPush(&SL, 3);
    8. StackPush(&SL, 5);
    9. StackPush(&SL, 4);
    10. StackPrintf(SL);
    11. StackPop(&SL);
    12. StackPush(&SL, 5);
    13. StackPush(&SL, 9);
    14. StackPrintf(SL);
    15. int a = StackFront(SL);
    16. printf("%d\n", a);
    17. StackPop(&SL);
    18. StackPop(&SL);
    19. StackPop(&SL);
    20. StackPop(&SL);
    21. StackPop(&SL);
    22. StackPop(&SL);
    23. StackPop(&SL);
    24. int b = StackEmpty(SL);
    25. printf("%d\n", b);
    26. StackPush(&SL, 2);
    27. StackPush(&SL, 3);
    28. StackPush(&SL, 5);
    29. StackPush(&SL, 4);
    30. StackPrintf(SL);
    31. int c = StackSize(SL);
    32. printf("%d\n", c);
    33. StackDestory(&SL);
    34. }
    35. int main()
    36. {
    37. test();
    38. return 0;
    39. }

    运行结果如下: 

    2.队列

    1.什么是队列?如何理解队列?

    队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)(头删头插)入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。

     2.队列的实现

    针对于队列的实现,也可以有两种实现的方法——数组和链表;那么哪种方法更为方便呢?
    答案是:使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

    一. 创建结构体变量,初始化队列;

    1. // 链式结构表示队列
    2. typedef struct Queue
    3. {
    4. struct Queue* next;
    5. int x;
    6. }Queue;
    7. // 队列的结构
    8. typedef struct QueueNode
    9. {
    10. Queue* head;
    11. Queue* tail;
    12. }QueueNode;
    13. void QueueInit(QueueNode* SL)
    14. {
    15. assert(SL);
    16. SL->head = SL->tail = NULL;
    17. }

    二. 头删 头插 头查 尾查 等函数的实现;

    1. //初始化
    2. void QueueInit(QueueNode* SL);
    3. //头插
    4. void QueuePush(QueueNode* SL, int x);
    5. //打印
    6. void QueuePrintf(QueueNode* SL);
    7. //头删
    8. void QueuePop(QueueNode* SL);
    9. //获取队头元素
    10. int QueueFront(QueueNode* SL);
    11. //获取队尾元素
    12. int QueueBack(QueueNode* SL);
    13. // 检查是否尾空 为空返回 1 不为空返回 0
    14. int QueueEmpty(QueueNode* SL);
    15. void QueuePush(QueueNode* SL, int x)
    16. {
    17. assert(SL);
    18. Queue* newnode = (Queue*)malloc(sizeof(Queue));
    19. if (newnode == NULL)
    20. {
    21. perror("malloc fail");
    22. }
    23. newnode->x = x;
    24. newnode->next = NULL;
    25. if (SL->tail == NULL)
    26. {
    27. SL->head = SL->tail = newnode;
    28. }
    29. else
    30. {
    31. SL->tail ->next = newnode;
    32. SL->tail = SL->tail->next;
    33. }
    34. }
    35. void QueuePrintf(QueueNode* SL)
    36. {
    37. assert(SL);
    38. Queue* cur = SL->head;
    39. while (cur)
    40. {
    41. printf("%d ", cur->x);
    42. cur = cur->next;
    43. }
    44. printf("\n");
    45. }
    46. void QueuePop(QueueNode* SL)
    47. {
    48. assert(SL);
    49. if (SL->head == NULL)
    50. {
    51. return ;
    52. }
    53. if (SL->head->next == NULL)
    54. {
    55. free(SL->head);
    56. SL->head = SL->tail = NULL;
    57. }
    58. else
    59. {
    60. Queue* del = SL->head;
    61. SL->head = SL->head->next;
    62. free(del);
    63. del = NULL;
    64. }
    65. }
    66. int QueueFront(QueueNode* SL)
    67. {
    68. assert(SL);
    69. return SL->head->x;
    70. }
    71. int QueueBack(QueueNode* SL)
    72. {
    73. assert(SL);
    74. return SL->tail->x;
    75. }
    76. int QueueEmpty(QueueNode* SL)
    77. {
    78. assert(SL);
    79. return (SL->tail == NULL)&&(SL->head == NULL);
    80. }

    三 . 队列的销毁;

    1. void QueueDestory(QueueNode* SL)
    2. {
    3. assert(SL);
    4. /*Queue* del = SL->head;
    5. while (del)
    6. {
    7. Queue* next = del->next;
    8. free(del);
    9. del = next;
    10. }*/
    11. Queue* cur = SL->head;
    12. while (cur)
    13. {
    14. Queue* del = cur;
    15. cur = cur->next;
    16. free(del);
    17. del = NULL;
    18. }
    19. SL->head = SL->tail = NULL;
    20. }

    四. 测试案例;

    1. #include"标头.h"
    2. test()
    3. {
    4. QueueNode SL;
    5. QueueInit(&SL);
    6. QueuePush(&SL, 1);
    7. QueuePush(&SL, 2);
    8. QueuePrintf(&SL);
    9. QueuePop(&SL);
    10. QueuePrintf(&SL);
    11. QueuePush(&SL, 3);
    12. QueuePush(&SL, 4);
    13. QueuePush(&SL, 5);
    14. QueuePrintf(&SL);
    15. int a = QueueFront(&SL);
    16. printf("%d\n", a);
    17. int b = QueueBack(&SL);
    18. printf("%d\n", b);
    19. int c = QueueEmpty(&SL);
    20. printf("%d\n", c);
    21. QueuePop(&SL);
    22. QueuePop(&SL);
    23. QueuePop(&SL);
    24. QueuePop(&SL);
    25. QueuePop(&SL);
    26. QueuePop(&SL);
    27. c = QueueEmpty(&SL);
    28. printf("%d\n", c);
    29. QueuePush(&SL, 3);
    30. QueuePush(&SL, 4);
    31. QueuePush(&SL, 5);
    32. QueuePrintf(&SL);
    33. QueueDestory(&SL);
    34. }
    35. int main()
    36. {
    37. test();
    38. return 0;
    39. }

    运行结果如下: 

  • 相关阅读:
    Kubernetes---Kubernetes集群部署Mysql集群
    Python二级备考
    docker容器化
    【JavaEE】HTML
    论文解读:Rectifying the Shortcut Learning of Background for Few-Shot Learning
    关于浙江22年下半年教师资格证面试报名注册时间
    ASP.NET的WebService跨域CORS问题解决方案
    【1】初识Java
    计算机视觉系列-轻松掌握 MMDetection 中常用算法 YOLOF(一)
    类加载和字节码技术篇
  • 原文地址:https://blog.csdn.net/weixin_57560405/article/details/126209028