• 栈 和 队列


    1、栈

    1.1栈的概念

    栈是一种特殊的线性表,只能在一端进行插入或者删除。表中允许进行插入或者删除的一端成为栈顶,表的另一端叫做栈底。当栈中没有元素时称为空栈,栈的插入操作称为入栈,栈的删除操作称为出栈。

    栈主要的特点就是后进先出。即就是后进栈的元素先出栈,每次进栈的数据元素都放在原来栈顶元素之前成为新的栈顶元素,每次出栈的元素都是当前栈顶的元素。

     

    如上图所示就是栈的插入(进栈)和删除(出栈),大家可以看到,我在图中标记了一个top的位置,这个位置其实表示的就是栈顶元素的下一个位置,因为我们习惯性定义一个变量把它的初始化置为0,但是又要和栈里面有一个元素区分,所以我们将top指向的位置表示成栈顶元素的下一个,就可以可以理解为:top一开始为0,当进栈一个元素时,插入在top的位置,top++。 

     1.2栈的实现

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

     

     1.2.1初始化

    1. void STInit(ST* pst)//初始化
    2. {
    3. assert(pst);
    4. pst->a = NULL;
    5. pst->capacity = 0;
    6. pst->top = 0;//栈顶元素下一个位置;
    7. }

     1.2.2销毁

    1. void STDestroy(ST* pst)//销毁
    2. {
    3. assert(pst);
    4. free(pst->a);
    5. pst->a = NULL;
    6. pst->capacity = 0;
    7. pst->top = 0;
    8. }

     1.2.3入栈

    1. void STPush(ST* pst, STDatatype x)//入栈;
    2. {
    3. assert(pst);
    4. if (pst->top == pst->capacity)
    5. {
    6. int newcapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;
    7. STDatatype* tmp =(STDatatype *) realloc(pst->a, sizeof(STDatatype) * newcapacity);
    8. if (tmp == NULL)
    9. {
    10. perror("realloc");
    11. return;
    12. }
    13. pst->a = tmp;
    14. pst->capacity = newcapacity;
    15. }
    16. pst->a[pst->top] = x;
    17. pst->top++;
    18. }

     1.2.4出栈

    1. void STPop(ST* pst)//出栈;
    2. {
    3. assert(pst);
    4. assert(pst->top>0);
    5. pst->top--;
    6. }

     1.2.5栈顶元素

    1. STDatatype STTop(ST* pst)
    2. {
    3. assert(pst);
    4. return pst->a[pst->top-1];
    5. }

    1.2.6判断空

    1. bool STEmpty(ST* pst)//判断是否为空
    2. {
    3. assert(pst);
    4. return pst->top == 0;
    5. }

    2、队列

    2.1队列的概念

    队列,它也是一种操作受限制的线性表,只允许它在表的一端进行插入,而在表的另一端删除操作。把进行插入一端的称为队尾,把进行删除一端的称为对首。向队列中插入新元素称为进队,先元素进队后就成为新的队尾元素;从队列中删除元素称为出队,元素出队后,他后面的元素就成为新的队首元素。

    由于队列的插入和删除操作分别是在各自一端操作的,每个元素必然按照进入的次序出队,所以队列最显著的特点就是先进先出。

    队列的进队出队如上图所示

    2.2队列的实现

    队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

    2.2.1初始化

    1. void QueueInit(Queue* pq)//初始化;
    2. {
    3. assert(pq);
    4. pq->phead = NULL;
    5. pq->ptail = NULL;
    6. pq->Queuesize = 0;
    7. }

    2.2.2销毁

    1. void QueueDestroy(Queue* pq)//销毁
    2. {
    3. assert(pq);
    4. QNode* cur = pq->phead;
    5. while (cur)
    6. {
    7. QNode* Next = cur->next;
    8. free(cur);
    9. cur = Next;
    10. }
    11. pq->phead = NULL;
    12. pq->ptail = NULL;
    13. pq->Queuesize = 0;
    14. }

    2.2.3入队

    1. void QueuePush(Queue* pq, QDatatype x)//进队
    2. {
    3. QNode* newnode = (QNode*)malloc(sizeof(QNode));
    4. if (newnode == NULL)
    5. {
    6. perror("malloc");
    7. return;
    8. }
    9. newnode->data = x;
    10. newnode->next = NULL;
    11. if (pq->ptail == NULL)
    12. {
    13. pq->ptail = pq->phead = newnode;
    14. }
    15. else
    16. {
    17. pq->ptail->next=newnode;
    18. pq->ptail = newnode;
    19. }
    20. pq->Queuesize++;
    21. }

    2.2.4出队

    1. void QueuePop(Queue* pq)//出队
    2. {
    3. assert(pq);
    4. assert(pq->phead);
    5. QNode* cur = pq->phead;
    6. if (cur->next == NULL)
    7. {
    8. free(cur);
    9. cur = NULL;
    10. pq->phead = pq->ptail = NULL;
    11. }
    12. else
    13. {
    14. pq->phead = pq->phead->next;
    15. free(cur);
    16. cur = NULL;
    17. }
    18. pq->Queuesize--;
    19. }

    2.2.5返回队首元素

    1. QDatatype QueueFront(Queue* pq)//返回队首元素;
    2. {
    3. assert(pq);
    4. assert(pq->phead);
    5. return pq->phead->data;
    6. }

    2.2.6队尾元素

    1. QDatatype QueueBack(Queue* pq)//队尾元素
    2. {
    3. assert(pq);
    4. assert(pq->ptail);
    5. return pq->ptail->data;
    6. }

    2.2.7判空

    1. bool QueueEmpty(Queue* pq)//判断是否空
    2. {
    3. assert(pq);
    4. return pq->phead == NULL;
    5. }

    2.2.8队内元素个数

    1. int QueueSize(Queue* pq)//队里面个数
    2. {
    3. assert(pq);
    4. return pq->Queuesize;
    5. }

    3、源码

    3.1栈的实现源码

    1. #include<stdio.h>
    2. #include<assert.h>
    3. #include<stdlib.h>
    4. #include<stdbool.h>
    5. typedef int STDatatype;
    6. typedef struct stack
    7. {
    8. STDatatype* a;
    9. int top;
    10. int capacity;
    11. }ST;
    12. void STInit(ST* pst);//初始化
    13. void STDestroy(ST* pst);//销毁
    14. void STPush(ST* pst,STDatatype x);//入栈;
    15. void STPop(ST* pst);//出栈;
    16. STDatatype STTop(ST* pst);//栈顶元素;
    17. bool STEmpty(ST* pst);//判断是否为空
    18. void STInit(ST* pst)//初始化
    19. {
    20. assert(pst);
    21. pst->a = NULL;
    22. pst->capacity = 0;
    23. pst->top = 0;//栈顶元素下一个位置;
    24. }
    25. void STDestroy(ST* pst)//销毁
    26. {
    27. assert(pst);
    28. free(pst->a);
    29. pst->a = NULL;
    30. pst->capacity = 0;
    31. pst->top = 0;
    32. }
    33. void STPush(ST* pst, STDatatype x)//入栈;
    34. {
    35. assert(pst);
    36. if (pst->top == pst->capacity)
    37. {
    38. int newcapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;
    39. STDatatype* tmp =(STDatatype *) realloc(pst->a, sizeof(STDatatype) * newcapacity);
    40. if (tmp == NULL)
    41. {
    42. perror("realloc");
    43. return;
    44. }
    45. pst->a = tmp;
    46. pst->capacity = newcapacity;
    47. }
    48. pst->a[pst->top] = x;
    49. pst->top++;
    50. }
    51. void STPop(ST* pst)//出栈;
    52. {
    53. assert(pst);
    54. assert(pst->top>0);
    55. pst->top--;
    56. }
    57. STDatatype STTop(ST* pst)
    58. {
    59. assert(pst);
    60. return pst->a[pst->top-1];
    61. }
    62. bool STEmpty(ST* pst)//判断是否为空
    63. {
    64. assert(pst);
    65. return pst->top == 0;
    66. }
    67. 以下为测试代码
    68. void test1()
    69. {
    70. ST s;
    71. STInit(&s);
    72. STPush(&s, 1);
    73. STPush(&s, 2);
    74. STPush(&s, 3);
    75. STPush(&s, 4);
    76. STPush(&s, 5);
    77. while (!STEmpty(&s))
    78. {
    79. printf("%d ", STTop(&s));
    80. STPop(&s);
    81. }
    82. STDestroy(&s);
    83. }
    84. int main()
    85. {
    86. test1();
    87. return 0;
    88. }

    3.2队列的实现源码

    1. #include<stdio.h>
    2. #include<stdlib.h>
    3. #include<assert.h>
    4. #include<stdbool.h>
    5. typedef int QDatatype;
    6. typedef struct QueueNode
    7. {
    8. QDatatype data;
    9. struct QueueNode* next;
    10. }QNode;
    11. typedef struct Queue
    12. {
    13. QNode* phead;
    14. QNode* ptail;
    15. int Queuesize;
    16. }Queue;
    17. void QueueInit(Queue* pq);//初始化;
    18. void QueueDestroy(Queue* pq);//销毁
    19. void QueuePush(Queue* pq, QDatatype x);//进队
    20. void QueuePop(Queue* pq);//出队
    21. QDatatype QueueFront(Queue* pq);//返回队首元素;
    22. QDatatype QueueBack(Queue* pq);//队尾元素
    23. bool QueueEmpty(Queue* pq);//判断是否空
    24. int QueueSize(Queue* pq);//队里面个数
    25. void QueueInit(Queue* pq)//初始化;
    26. {
    27. assert(pq);
    28. pq->phead = NULL;
    29. pq->ptail = NULL;
    30. pq->Queuesize = 0;
    31. }
    32. void QueueDestroy(Queue* pq)//销毁
    33. {
    34. assert(pq);
    35. QNode* cur = pq->phead;
    36. while (cur)
    37. {
    38. QNode* Next = cur->next;
    39. free(cur);
    40. cur = Next;
    41. }
    42. pq->phead = NULL;
    43. pq->ptail = NULL;
    44. pq->Queuesize = 0;
    45. }
    46. void QueuePush(Queue* pq, QDatatype x)//进队
    47. {
    48. QNode* newnode = (QNode*)malloc(sizeof(QNode));
    49. if (newnode == NULL)
    50. {
    51. perror("malloc");
    52. return;
    53. }
    54. newnode->data = x;
    55. newnode->next = NULL;
    56. if (pq->ptail == NULL)
    57. {
    58. pq->ptail = pq->phead = newnode;
    59. }
    60. else
    61. {
    62. pq->ptail->next=newnode;
    63. pq->ptail = newnode;
    64. }
    65. pq->Queuesize++;
    66. }
    67. void QueuePop(Queue* pq)//出队
    68. {
    69. assert(pq);
    70. assert(pq->phead);
    71. QNode* cur = pq->phead;
    72. if (cur->next == NULL)
    73. {
    74. free(cur);
    75. cur = NULL;
    76. pq->phead = pq->ptail = NULL;
    77. }
    78. else
    79. {
    80. pq->phead = pq->phead->next;
    81. free(cur);
    82. cur = NULL;
    83. }
    84. pq->Queuesize--;
    85. }
    86. QDatatype QueueFront(Queue* pq)//返回队首元素;
    87. {
    88. assert(pq);
    89. assert(pq->phead);
    90. return pq->phead->data;
    91. }
    92. QDatatype QueueBack(Queue* pq)//队尾元素
    93. {
    94. assert(pq);
    95. assert(pq->ptail);
    96. return pq->ptail->data;
    97. }
    98. bool QueueEmpty(Queue* pq)//判断是否空
    99. {
    100. assert(pq);
    101. return pq->phead == NULL;
    102. }
    103. int QueueSize(Queue* pq)//队里面个数
    104. {
    105. assert(pq);
    106. return pq->Queuesize;
    107. }
    108. //以下为测试代码
    109. void test1()
    110. {
    111. Queue st;
    112. QueueInit(&st);
    113. QueuePush(&st, 1);
    114. QueuePush(&st, 2);
    115. QueuePush(&st, 3);
    116. QueuePush(&st, 4);
    117. QueuePush(&st, 5);
    118. while (!QueueEmpty(&st))
    119. {
    120. printf("%d ", QueueFront(&st));
    121. QueuePop(&st);
    122. }
    123. QueueDestroy(&st);
    124. }
    125. int main()
    126. {
    127. test1();
    128. return 0;
    129. }

     

  • 相关阅读:
    6.套餐管理业务开发
    如何在不同平台上搭建Flutter开发环境
    代码重构的一些理由
    适合Python初学者阅读的Github开源代码
    计算机网络-物理层
    【C++】简单理解模板 函数模板 类模板
    基于Springboot外卖系统07:员工分页查询+ 分页插件配置+分页代码实现
    Mysql 数据库
    python3调用阿里云openapi脚本 - 生产环境
    区块链的认识
  • 原文地址:https://blog.csdn.net/weixin_67131528/article/details/134499149