当前位置:   article > 正文

数据结构--栈,队列_栈和队是挨着的吗

栈和队是挨着的吗

前言

        这篇文章主要是关于栈与队列,为什么一般都是将栈与队列挨着讲,因为他们两个像一对欢喜冤家一样,在争锋相对的同时也互相成就,彼此通过不同的性质又可以联系在一起。本章节主要成分部分:什么是栈和队列,栈和队列的构造,栈和队列的习题。通过基础知识完成练习,通过练习巩固知识与理解栈与队列的联系。相信这篇文章会对大家有帮助,因为计算机就是解决我们生活中的问题,栈与队列的性质也是来源于生活中,比如栈--手枪的弹夹,队列--排队。

目录

前言

栈的概念及结构

 栈的实现

实现代码

队列

队列的概念及结构

 队列的实现

 实现代码

循环队列

 栈和队列面试题

括号匹配问题---链接

用队列实现栈--链接

用栈实现队列--链接

设计循环队列--链接


栈的概念及结构

栈:

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

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

动态演示

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

动态演示

 栈的实现

        栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为压栈与出栈正好满足数组的尾插与头删。数组的代价是及小的,操作相当于链表也更加简便。

动态演示

                                                                        压栈

出栈 

实现代码

主要步骤:

构建栈结构--数组,容量,栈顶

接口的实现--初始化栈 ,入栈,出栈 ,获取栈顶元素 ,获取栈中有效元素个数 ,检测栈是否为空, 销毁栈 

主函数演示

Stack.h

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #pragma once
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6. #include <stdbool.h>
  7. typedef int STDataType;
  8. //#define N 10
  9. //typedef struct Stack
  10. //{
  11. // STDataType _a[N];
  12. // int _top; // 栈顶
  13. //}Stack;
  14. // 支持动态增长的栈
  15. typedef int STDataType;
  16. typedef struct Stack
  17. {
  18. STDataType* _a;
  19. int _top; // 栈顶
  20. int _capacity; // 容量
  21. }Stack;
  22. // 初始化栈
  23. void StackInit(Stack* ps);
  24. // 入栈
  25. void StackPush(Stack* ps, STDataType data);
  26. // 出栈
  27. void StackPop(Stack* ps);
  28. // 获取栈顶元素
  29. STDataType StackTop(Stack* ps);
  30. // 获取栈中有效元素个数
  31. int StackSize(Stack* ps);
  32. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  33. bool StackEmpty(Stack* ps);
  34. // 销毁栈
  35. void StackDestroy(Stack* ps);

Stack.c

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include "Stack.h"
  3. // 初始化栈
  4. void StackInit(Stack* ps)
  5. {
  6. assert(ps);//断言传入地址是否为空
  7. ps->_a = NULL;
  8. ps->_capacity = ps->_top = 0;
  9. }
  10. // 入栈
  11. void StackPush(Stack* ps, STDataType data)
  12. {
  13. assert(ps);
  14. if (ps->_top == ps->_capacity)
  15. {
  16. int newCapacity = ps->_capacity == 0 ? 4 : ps->_capacity*2;//判断容量是否为空并设置增加容量数量
  17. STDataType* temp = (STDataType*)realloc(ps->_a, newCapacity*sizeof(STDataType));//增加容量
  18. if (temp == NULL)//判断地址是否开辟成功
  19. {
  20. perror("realloc fail");
  21. exit(-1);
  22. }
  23. ps->_a = temp;//赋址与结构体中
  24. ps->_capacity = newCapacity;//更新容量
  25. }
  26. ps->_a[ps->_top] = data;//数据入栈
  27. ps->_top++;//栈顶++
  28. }
  29. // 出栈
  30. void StackPop(Stack* ps)
  31. {
  32. assert(ps);
  33. assert(!StackEmpty(ps));//断言栈是否为空
  34. --ps->_top;//栈顶--
  35. }
  36. // 获取栈顶元素
  37. STDataType StackTop(Stack* ps)
  38. {
  39. assert(ps);
  40. assert(!StackEmpty(ps));
  41. return ps->_a[ps->_top-1];
  42. }
  43. // 获取栈中有效元素个数
  44. int StackSize(Stack* ps)
  45. {
  46. assert(ps);
  47. return ps->_top;
  48. }
  49. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  50. bool StackEmpty(Stack* ps)
  51. {
  52. assert(ps);
  53. return ps->_top==0;
  54. }
  55. // 销毁栈
  56. void StackDestroy(Stack* ps)
  57. {
  58. assert(ps);
  59. free(ps->_a);//清除数组地址
  60. ps->_a = NULL;
  61. ps->_top = ps->_capacity = 0;
  62. }

Test.c

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include "Stack.h"
  3. //进栈--出栈演示
  4. void TestStack()
  5. {
  6. Stack ps;
  7. StackInit(&ps);
  8. StackPush(&ps,5);
  9. StackPush(&ps,6);
  10. StackPush(&ps,7);
  11. // printf("%d ", StackTop(&ps));
  12. StackPop(&ps);
  13. // printf("%d ", StackTop(&ps));
  14. StackPop(&ps);
  15. while (!StackEmpty(&ps))
  16. {
  17. printf("%d ", StackTop(&ps));
  18. StackPop(&ps);
  19. }
  20. printf("\n");
  21. }
  22. int main()
  23. {
  24. TestStack();
  25. return 0;
  26. }

队列

队列的概念及结构

队列:

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

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

动态演示

 队列的实现

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

动态演示

 实现代码

实现步骤:

构建链式结构--结构体指针,数据

构建队列结构--头指针,尾指针

接口的实现--初始化队列 ,队尾入队列 ,队头出队列 ,获取队列头部元素,获取队列队尾元素 ,获取队列中有效元素个数 , 检测队列是否为空 , 销毁队列 。

主函数演示

Queue.h

  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. // 链式结构:表示队列
  6. typedef int QDataType;
  7. typedef struct QListNode
  8. {
  9. struct QListNode* _next;
  10. QDataType _data;
  11. }QNode;
  12. // 队列的结构
  13. typedef struct Queue
  14. {
  15. QNode* _front;
  16. QNode* _rear;
  17. QDataType _size;
  18. }Queue;
  19. // 初始化队列
  20. void QueueInit(Queue* q);
  21. // 队尾入队列
  22. void QueuePush(Queue* q, QDataType data);
  23. // 队头出队列
  24. void QueuePop(Queue* q);
  25. // 获取队列头部元素
  26. QDataType QueueFront(Queue* q);
  27. // 获取队列队尾元素
  28. QDataType QueueBack(Queue* q);
  29. // 获取队列中有效元素个数
  30. int QueueSize(Queue* q);
  31. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
  32. bool QueueEmpty(Queue* q);
  33. // 销毁队列
  34. void QueueDestroy(Queue* q);

Queue.c

  1. #include "Queue.h"
  2. // 初始化队列
  3. void QueueInit(Queue* q)
  4. {
  5. assert(q);
  6. q->_front = q->_rear = NULL;
  7. q->_size = 0;
  8. }
  9. // 队尾入队列
  10. void QueuePush(Queue* q, QDataType data)
  11. {
  12. assert(q);
  13. QNode* cur = (QNode*)malloc(sizeof(QNode));
  14. if (cur == NULL)
  15. {
  16. perror("malloc fail");
  17. exit(-1);
  18. }
  19. else
  20. {
  21. cur->_data = data;
  22. cur->_next = NULL;
  23. }
  24. if (q->_rear == NULL)
  25. {
  26. q->_front = q->_rear = cur;
  27. }
  28. else
  29. {
  30. q->_rear->_next = cur;
  31. q->_rear = cur;
  32. }
  33. q->_size++;
  34. }
  35. // 队头出队列
  36. void QueuePop(Queue* q)
  37. {
  38. assert(q);
  39. assert(!QueueEmpty(q));
  40. if (q->_front->_next==NULL)
  41. {
  42. free(q->_front);
  43. q->_front = q->_rear = NULL;
  44. }
  45. else
  46. {
  47. QNode* cur = q->_front;
  48. q->_front = q->_front->_next;
  49. free(cur);
  50. cur = NULL;
  51. }
  52. q->_size--;
  53. }
  54. // 获取队列头部元素
  55. QDataType QueueFront(Queue* q)
  56. {
  57. assert(q);
  58. assert(!QueueEmpty(q));
  59. return q->_front->_data;
  60. }
  61. // 获取队列队尾元素
  62. QDataType QueueBack(Queue* q)
  63. {
  64. assert(q);
  65. assert(!QueueEmpty(q));
  66. return q->_rear->_data;
  67. }
  68. // 获取队列中有效元素个数
  69. int QueueSize(Queue* q)
  70. {
  71. assert(q);
  72. return q->_size;
  73. }
  74. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
  75. bool QueueEmpty(Queue* q)
  76. {
  77. assert(q);
  78. return q->_front == NULL && q->_rear == NULL;
  79. }
  80. // 销毁队列
  81. void QueueDestroy(Queue* q)
  82. {
  83. assert(q);
  84. QNode* cur = q->_front;
  85. while (cur)
  86. {
  87. QNode* del = cur;
  88. cur = cur->_next;
  89. free(del);
  90. del = NULL;
  91. }
  92. q->_front = q->_rear = NULL;
  93. }

Test.c

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include "Queue.h"
  3. void TestQueue()
  4. {
  5. Queue q;
  6. QueueInit(&q);
  7. QueuePush(&q, 1);
  8. QueuePush(&q, 3);
  9. QueuePush(&q, 4);
  10. QueuePop(&q);
  11. printf("%d ", QueueFront(&q));
  12. // printf("%d ", QueueBack(&q));
  13. QueuePush(&q, 7);
  14. printf("%d ", QueueBack(&q));
  15. QueuePush(&q, 8);
  16. printf("%d ", QueueBack(&q));
  17. QueuePush(&q, 9);
  18. QueuePush(&q, 10);
  19. QueuePush(&q, 11);
  20. while (!QueueEmpty(&q))
  21. {
  22. printf("%d ", QueueFront(&q));
  23. QueuePop(&q);
  24. }
  25. QueueDestroy(&q);
  26. }
  27. int main()
  28. {
  29. TestQueue();
  30. return 0;
  31. }

循环队列

        另外扩展了解一下,实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型 时可以就会使用循环队列。环形队列可以使用数组实现,也可以使用循环链表实现。

 

 栈和队列面试题

括号匹配问题---链接

动态演示

 

 两种特殊错误情况

实现代码

  1. typedef char STDataType;
  2. typedef struct Stack
  3. {
  4. STDataType* _a;
  5. int _top; // 栈顶
  6. int _capacity; // 容量
  7. }Stack;
  8. // 初始化栈
  9. void StackInit(Stack* ps);
  10. // 入栈
  11. void StackPush(Stack* ps, STDataType data);
  12. // 出栈
  13. void StackPop(Stack* ps);
  14. // 获取栈顶元素
  15. STDataType StackTop(Stack* ps);
  16. // 获取栈中有效元素个数
  17. int StackSize(Stack* ps);
  18. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  19. bool StackEmpty(Stack* ps);
  20. // 销毁栈
  21. void StackDestroy(Stack* ps);
  22. // 初始化栈
  23. void StackInit(Stack* ps)
  24. {
  25. assert(ps);//断言传入地址是否为空
  26. ps->_a = NULL;
  27. ps->_capacity = ps->_top = 0;
  28. }
  29. // 入栈
  30. void StackPush(Stack* ps, STDataType data)
  31. {
  32. assert(ps);
  33. if (ps->_top == ps->_capacity)
  34. {
  35. int newCapacity = ps->_capacity == 0 ? 4 : ps->_capacity*2;//判断容量是否为空并设置增加容量数量
  36. STDataType* temp = (STDataType*)realloc(ps->_a, newCapacity*sizeof(STDataType));//增加容量
  37. if (temp == NULL)//判断地址是否开辟成功
  38. {
  39. perror("realloc fail");
  40. exit(-1);
  41. }
  42. ps->_a = temp;//赋址与结构体中
  43. ps->_capacity = newCapacity;//更新容量
  44. }
  45. ps->_a[ps->_top] = data;//数据入栈
  46. ps->_top++;//栈顶++
  47. }
  48. // 出栈
  49. void StackPop(Stack* ps)
  50. {
  51. assert(ps);
  52. assert(!StackEmpty(ps));//断言栈是否为空
  53. --ps->_top;//栈顶--
  54. }
  55. // 获取栈顶元素
  56. STDataType StackTop(Stack* ps)
  57. {
  58. assert(ps);
  59. assert(!StackEmpty(ps));
  60. return ps->_a[ps->_top-1];
  61. }
  62. // 获取栈中有效元素个数
  63. int StackSize(Stack* ps)
  64. {
  65. assert(ps);
  66. return ps->_top;
  67. }
  68. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  69. bool StackEmpty(Stack* ps)
  70. {
  71. assert(ps);
  72. return ps->_top==0;
  73. }
  74. // 销毁栈
  75. void StackDestroy(Stack* ps)
  76. {
  77. assert(ps);
  78. free(ps->_a);//清除数组地址
  79. ps->_a = NULL;
  80. ps->_top = ps->_capacity = 0;
  81. }
  82. bool isValid(char * s){
  83. Stack st;
  84. StackInit(&st);
  85. while(*s)
  86. {
  87. if(*s=='('||*s=='{'||*s=='[')
  88. {
  89. StackPush(&st,*s);
  90. }
  91. else
  92. {
  93. if(StackEmpty(&st))
  94. {
  95. StackDestroy(&st);
  96. return false;
  97. }
  98. char tem= StackTop(&st);
  99. StackPop(&st);
  100. if(*s=='}' && tem!='{' || *s==')' && tem!='(' || *s==']' && tem!='[')
  101. {
  102. StackDestroy(&st);
  103. return false;
  104. }
  105. }
  106. s++;
  107. }
  108. bool flag=StackEmpty(&st);
  109. StackDestroy(&st);
  110. return flag;
  111. }

用队列实现栈--链接

动态演示

 

 实现代码

  1. // 链式结构:表示队列
  2. typedef int QDataType;
  3. typedef struct QListNode
  4. {
  5. struct QListNode* _next;
  6. QDataType _data;
  7. }QNode;
  8. // 队列的结构
  9. typedef struct Queue
  10. {
  11. QNode* _front;
  12. QNode* _rear;
  13. QDataType _size;
  14. }Queue;
  15. // 初始化队列
  16. void QueueInit(Queue* q);
  17. // 队尾入队列
  18. void QueuePush(Queue* q, QDataType data);
  19. // 队头出队列
  20. void QueuePop(Queue* q);
  21. // 获取队列头部元素
  22. QDataType QueueFront(Queue* q);
  23. // 获取队列队尾元素
  24. QDataType QueueBack(Queue* q);
  25. // 获取队列中有效元素个数
  26. int QueueSize(Queue* q);
  27. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
  28. bool QueueEmpty(Queue* q);
  29. // 销毁队列
  30. void QueueDestroy(Queue* q);
  31. // 初始化队列
  32. void QueueInit(Queue* q)
  33. {
  34. assert(q);
  35. q->_front = q->_rear = NULL;
  36. q->_size = 0;
  37. }
  38. // 队尾入队列
  39. void QueuePush(Queue* q, QDataType data)
  40. {
  41. assert(q);
  42. QNode* cur = (QNode*)malloc(sizeof(QNode));
  43. if (cur == NULL)
  44. {
  45. perror("malloc fail");
  46. exit(-1);
  47. }
  48. else
  49. {
  50. cur->_data = data;
  51. cur->_next = NULL;
  52. }
  53. if (q->_rear == NULL)
  54. {
  55. q->_front = q->_rear = cur;
  56. }
  57. else
  58. {
  59. q->_rear->_next = cur;
  60. q->_rear = cur;
  61. }
  62. q->_size++;
  63. }
  64. // 队头出队列
  65. void QueuePop(Queue* q)
  66. {
  67. assert(q);
  68. assert(!QueueEmpty(q));
  69. if (q->_front->_next==NULL)
  70. {
  71. free(q->_front);
  72. q->_front = q->_rear = NULL;
  73. }
  74. else
  75. {
  76. QNode* cur = q->_front;
  77. q->_front = q->_front->_next;
  78. free(cur);
  79. cur = NULL;
  80. }
  81. q->_size--;
  82. }
  83. // 获取队列头部元素
  84. QDataType QueueFront(Queue* q)
  85. {
  86. assert(q);
  87. assert(!QueueEmpty(q));
  88. return q->_front->_data;
  89. }
  90. // 获取队列队尾元素
  91. QDataType QueueBack(Queue* q)
  92. {
  93. assert(q);
  94. assert(!QueueEmpty(q));
  95. return q->_rear->_data;
  96. }
  97. // 获取队列中有效元素个数
  98. int QueueSize(Queue* q)
  99. {
  100. assert(q);
  101. return q->_size;
  102. }
  103. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
  104. bool QueueEmpty(Queue* q)
  105. {
  106. assert(q);
  107. return q->_front == NULL && q->_rear == NULL;
  108. }
  109. // 销毁队列
  110. void QueueDestroy(Queue* q)
  111. {
  112. assert(q);
  113. QNode* cur = q->_front;
  114. while (cur)
  115. {
  116. QNode* del = cur;
  117. cur = cur->_next;
  118. free(del);
  119. del = NULL;
  120. }
  121. q->_front = q->_rear = NULL;
  122. }
  123. typedef struct {
  124. Queue q1;
  125. Queue q2;
  126. } MyStack;
  127. //创建队列形成的栈
  128. MyStack* myStackCreate() {
  129. MyStack* obj=(MyStack*)malloc(sizeof(MyStack));
  130. QueueInit(&obj->q1);
  131. QueueInit(&obj->q2);
  132. return obj;
  133. }
  134. //压栈
  135. void myStackPush(MyStack* obj, int x) {
  136. if(!QueueEmpty(&obj->q1))
  137. {
  138. QueuePush(&obj->q1,x);
  139. }
  140. else
  141. {
  142. QueuePush(&obj->q2,x);
  143. }
  144. }
  145. //出栈 QueuePop
  146. int myStackPop(MyStack* obj) {
  147. QNode* empty=&obj->q1;
  148. QNode* nonempty=&obj->q2;
  149. if(!QueueEmpty(&obj->q1))
  150. {
  151. empty=&obj->q2;
  152. nonempty=&obj->q1;
  153. }
  154. while(QueueSize(nonempty)>1)
  155. {
  156. QueuePush(empty,QueueFront(nonempty));
  157. QueuePop(nonempty);
  158. }
  159. int top=QueueFront(nonempty);
  160. QueuePop(nonempty);
  161. return top;
  162. }
  163. //栈顶值
  164. int myStackTop(MyStack* obj) {
  165. if(!QueueEmpty(&obj->q1))
  166. {
  167. return QueueBack(&obj->q1) ;
  168. }
  169. else
  170. {
  171. return QueueBack(&obj->q2);
  172. }
  173. }
  174. //判断栈为空
  175. bool myStackEmpty(MyStack* obj) {
  176. return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
  177. }
  178. //释放栈
  179. void myStackFree(MyStack* obj) {
  180. QueueDestroy(&obj->q1);
  181. QueueDestroy(&obj->q2);
  182. free(obj);
  183. obj==NULL;
  184. }
  185. /**
  186. * Your MyStack struct will be instantiated and called as such:
  187. * MyStack* obj = myStackCreate();
  188. * myStackPush(obj, x);
  189. * int param_2 = myStackPop(obj);
  190. * int param_3 = myStackTop(obj);
  191. * bool param_4 = myStackEmpty(obj);
  192. * myStackFree(obj);
  193. */

用栈实现队列--链接

动态演示

  实现代码

  1. typedef int STDataType;
  2. //#define N 10
  3. //typedef struct Stack
  4. //{
  5. // STDataType _a[N];
  6. // int _top; // 栈顶
  7. //}Stack;
  8. // 支持动态增长的栈
  9. typedef int STDataType;
  10. typedef struct Stack
  11. {
  12. STDataType* _a;
  13. int _top; // 栈顶
  14. int _capacity; // 容量
  15. }Stack;
  16. // 初始化栈
  17. void StackInit(Stack* ps);
  18. // 入栈
  19. void StackPush(Stack* ps, STDataType data);
  20. // 出栈
  21. void StackPop(Stack* ps);
  22. // 获取栈顶元素
  23. STDataType StackTop(Stack* ps);
  24. // 获取栈中有效元素个数
  25. int StackSize(Stack* ps);
  26. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  27. bool StackEmpty(Stack* ps);
  28. // 销毁栈
  29. void StackDestroy(Stack* ps);
  30. // 初始化栈
  31. void StackInit(Stack* ps)
  32. {
  33. assert(ps);//断言传入地址是否为空
  34. ps->_a = NULL;
  35. ps->_capacity = ps->_top = 0;
  36. }
  37. // 入栈
  38. void StackPush(Stack* ps, STDataType data)
  39. {
  40. assert(ps);
  41. if (ps->_top == ps->_capacity)
  42. {
  43. int newCapacity = ps->_capacity == 0 ? 4 : ps->_capacity*2;//判断容量是否为空并设置增加容量数量
  44. STDataType* temp = (STDataType*)realloc(ps->_a, newCapacity*sizeof(STDataType));//增加容量
  45. if (temp == NULL)//判断地址是否开辟成功
  46. {
  47. perror("realloc fail");
  48. exit(-1);
  49. }
  50. ps->_a = temp;//赋址与结构体中
  51. ps->_capacity = newCapacity;//更新容量
  52. }
  53. ps->_a[ps->_top] = data;//数据入栈
  54. ps->_top++;//栈顶++
  55. }
  56. // 出栈
  57. void StackPop(Stack* ps)
  58. {
  59. assert(ps);
  60. assert(!StackEmpty(ps));//断言栈是否为空
  61. --ps->_top;//栈顶--
  62. }
  63. // 获取栈顶元素
  64. STDataType StackTop(Stack* ps)
  65. {
  66. assert(ps);
  67. assert(!StackEmpty(ps));
  68. return ps->_a[ps->_top-1];
  69. }
  70. // 获取栈中有效元素个数
  71. int StackSize(Stack* ps)
  72. {
  73. assert(ps);
  74. return ps->_top;
  75. }
  76. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  77. bool StackEmpty(Stack* ps)
  78. {
  79. assert(ps);
  80. return ps->_top==0;
  81. }
  82. // 销毁栈
  83. void StackDestroy(Stack* ps)
  84. {
  85. assert(ps);
  86. free(ps->_a);//清除数组地址
  87. ps->_a = NULL;
  88. ps->_top = ps->_capacity = 0;
  89. }
  90. typedef struct {
  91. Stack push;
  92. Stack pop;
  93. } MyQueue;
  94. MyQueue* myQueueCreate() {
  95. MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
  96. StackInit(&obj->push);
  97. StackInit(&obj->pop);
  98. return obj;
  99. }
  100. void myQueuePush(MyQueue* obj, int x) {
  101. StackPush(&obj->push,x);
  102. }
  103. int myQueuePop(MyQueue* obj) {
  104. if(StackEmpty(&obj->pop))
  105. {
  106. while(!StackEmpty(&obj->push))
  107. {
  108. StackPush(&obj->pop,StackTop(&obj->push));
  109. StackPop(&obj->push);
  110. }
  111. }
  112. STDataType tem =StackTop(&obj->pop);
  113. StackPop(&obj->pop);
  114. return tem;
  115. }
  116. int myQueuePeek(MyQueue* obj) {
  117. if(StackEmpty(&obj->pop))
  118. {
  119. while(!StackEmpty(&obj->push))
  120. {
  121. StackPush(&obj->pop,StackTop(&obj->push));
  122. StackPop(&obj->push);
  123. }
  124. }
  125. return StackTop(&obj->pop);
  126. }
  127. bool myQueueEmpty(MyQueue* obj) {
  128. return StackEmpty(&obj->push)&&StackEmpty(&obj->pop);
  129. }
  130. void myQueueFree(MyQueue* obj) {
  131. StackDestroy(&obj->push);
  132. StackDestroy(&obj->pop);
  133. free(obj);
  134. }
  135. /**
  136. * Your MyQueue struct will be instantiated and called as such:
  137. * MyQueue* obj = myQueueCreate();
  138. * myQueuePush(obj, x);
  139. * int param_2 = myQueuePop(obj);
  140. * int param_3 = myQueuePeek(obj);
  141. * bool param_4 = myQueueEmpty(obj);
  142. * myQueueFree(obj);
  143. */

设计循环队列--链接

用数组更好还是链表

在考虑用谁更好时,有个问题已经来了,如何判断满和空

判断空只需要front==rear就为空

 判断满 有两个方法: 1.用size计数 2.增加一个空节点

这里如果用size的话我们发现实现循环还是需要加节点,那如果不加呢?

不加节点我们发现,先走的rear,如果满了rear与front就重复了到底是空还是满就不好判断。所以这里我们选择加节点。

当加了节点我们发现循环之后需要获取队列最后一个元素时,需要重新遍历或者加一个指向前面的指针

当我们决定用数组时我们需要注意什么呢?

 当rear进行循环时,rear+1会出现越界的问题,如何解决呢?

我们只需要(rear+1)%rear 即可,就可以进行循环。

动态演示

 实现代码

  1. typedef struct {
  2. int *a;
  3. int front;
  4. int rear;
  5. int N;
  6. } MyCircularQueue;
  7. MyCircularQueue* myCircularQueueCreate(int k) {
  8. MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  9. obj->a=(int*)malloc((k+1)*sizeof(int));
  10. obj->front=obj->rear=0;
  11. obj->N=k+1;
  12. return obj;
  13. }
  14. bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  15. return obj->front==obj->rear;
  16. }
  17. bool myCircularQueueIsFull(MyCircularQueue* obj) {
  18. return (obj->rear+1)%obj->N==obj->front;
  19. }
  20. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  21. if( myCircularQueueIsFull(obj))
  22. return false;
  23. obj->a[obj->rear]=value;
  24. obj->rear++;
  25. obj->rear %= obj->N;
  26. return true;
  27. }
  28. bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  29. if(myCircularQueueIsEmpty(obj))
  30. return false;
  31. obj->front++;
  32. obj->front %= obj->N;
  33. return true;
  34. }
  35. int myCircularQueueFront(MyCircularQueue* obj) {
  36. if(myCircularQueueIsEmpty(obj))
  37. return -1;
  38. else
  39. return obj->a[obj->front];
  40. }
  41. int myCircularQueueRear(MyCircularQueue* obj) {
  42. if(myCircularQueueIsEmpty(obj))
  43. return -1;
  44. else
  45. return obj->a[(obj->rear+obj->N-1)%obj->N];
  46. }
  47. void myCircularQueueFree(MyCircularQueue* obj) {
  48. free(obj->a);
  49. free(obj);
  50. }
  51. /**
  52. * Your MyCircularQueue struct will be instantiated and called as such:
  53. * MyCircularQueue* obj = myCircularQueueCreate(k);
  54. * bool param_1 = myCircularQueueEnQueue(obj, value);
  55. * bool param_2 = myCircularQueueDeQueue(obj);
  56. * int param_3 = myCircularQueueFront(obj);
  57. * int param_4 = myCircularQueueRear(obj);
  58. * bool param_5 = myCircularQueueIsEmpty(obj);
  59. * bool param_6 = myCircularQueueIsFull(obj);
  60. * myCircularQueueFree(obj);
  61. */

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/589291
推荐阅读
相关标签
  

闽ICP备14008679号