• C++stack&queue


    目录

    一、stack

    1.1 简要介绍

    1.2 小试身手

    1.3 模拟实现

    二、queue

    2.1 简要介绍

    2.2 小试身手        

    2.3 模拟实现

    三、deque

    3.1 简要介绍

    3.2 分析底层        

    四、priority_queue

    4.1 简要介绍

    4.2 小试身手

    4.3 模拟实现

    五、仿函数/函数对象 

    5.1 简要介绍        



    一、stack

    1.1 简要介绍

            鉴于读者如果阅读到本文,应该对上述函数(empty、size、push_back等)基本用法和功能有一定了解,因此不再赘述。读者可以在queue - C++ Reference (cplusplus.com)查询详细内容        

    1.2 小试身手

    150. 逆波兰表达式求值icon-default.png?t=N7T8https://leetcode.cn/problems/evaluate-reverse-polish-notation/参考解法:

    1. class Solution {
    2. public:
    3. int evalRPN(vector& tokens) {
    4. stack<int> st;
    5. for (auto& s : tokens)
    6. {
    7. if (s == "+" || s == "-" || s == "*" || s == "/")
    8. {
    9. int right = st.top();
    10. st.pop();
    11. int left = st.top();
    12. st.pop();
    13. switch(s[0])
    14. {
    15. case '+':
    16. st.push(left+right);
    17. break;
    18. case '-':
    19. st.push(left-right);
    20. break;
    21. case '*':
    22. st.push(left*right);
    23. break;
    24. case '/':
    25. st.push(left/right);
    26. break;
    27. default:
    28. break;
    29. }
    30. }
    31. else
    32. {
    33. st.push(stoi(s));
    34. }
    35. }
    36. return st.top();
    37. }
    38. };

            

    1.3 模拟实现

    1. #pragma once
    2. #include
    3. //#include
    4. namespace myContainer
    5. {
    6. template<class T, class Container = vector> // 复用vector
    7. //template> // 复用deque
    8. class stack
    9. {
    10. public:
    11. void push(const T& x)
    12. {
    13. _con.push_back(x);
    14. }
    15. void pop()
    16. {
    17. _con.pop_back();
    18. }
    19. T& top()
    20. {
    21. return _con.back();
    22. }
    23. const T& top()const
    24. {
    25. return _con.back();
    26. }
    27. size_t size()const
    28. {
    29. return _con.size();
    30. }
    31. bool empty()const
    32. {
    33. return _con.empty();
    34. }
    35. private:
    36. Container _con;
    37. };
    38. }

    效果演示:

            

            


    二、queue

    2.1 简要介绍

            

    2.2 小试身手        

    102. 二叉树的层序遍历icon-default.png?t=N7T8https://leetcode.cn/problems/binary-tree-level-order-traversal/参考解法:

    1. class Solution {
    2. public:
    3. vectorint>> levelOrder(TreeNode* root) {
    4. queue q;
    5. int levelSize = 0;
    6. if (root)
    7. {
    8. q.push(root);
    9. levelSize = 1;
    10. }
    11. vectorint>> vv;
    12. while (!q.empty())
    13. {
    14. vector<int> v;
    15. while (levelSize--)
    16. {
    17. TreeNode* front = q.front();
    18. q.pop();
    19. v.push_back(front->val);
    20. if (front->left)
    21. {
    22. q.push(front->left);
    23. }
    24. if (front->right)
    25. {
    26. q.push(front->right);
    27. }
    28. }
    29. vv.push_back(v);
    30. // 队列中的数据个数就是下一层的数据个数
    31. levelSize = q.size();
    32. }
    33. return vv;
    34. }
    35. };

            

    2.3 模拟实现

    1. #pragma once
    2. #include
    3. namespace myContainer
    4. {
    5. template<class T, class Container = deque>
    6. class queue
    7. {
    8. public:
    9. void push(const T& x)
    10. {
    11. _con.push_back(x);
    12. }
    13. void pop()
    14. {
    15. _con.pop_front();
    16. }
    17. T& front()
    18. {
    19. return _con.front();
    20. }
    21. T& back()
    22. {
    23. return _con.back();
    24. }
    25. const T& front()const
    26. {
    27. return _con.front();
    28. }
    29. const T& back()const
    30. {
    31. return _con.back();
    32. }
    33. size_t size()const
    34. {
    35. return _con.size();
    36. }
    37. bool empty()const
    38. {
    39. return _con.empty();
    40. }
    41. private:
    42. Container _con;
    43. };
    44. }

    效果演示:

            

            


    三、deque

    deque -- 双队列        

    3.1 简要介绍

            deque结合了vector和list两者的优势并融合起来,同时必然地,deque比不过vector和list的优势区间,deque就好比一个六边形战士,杂而不精。deque的用法与vector和list几乎相同,这里不再赘述。先前我们模拟实现stack和queue的时候也都可以复用deque。      

    3.2 分析底层        

            

            


    四、priority_queue

    priority_queue -- 优先级队列

    4.1 简要介绍

    我们可以看到,优先级队列的底层实际上是vector,但是数据的排列方式更像是堆

    使用演示:

    4.2 小试身手

    215. 数组中的第K个最大元素icon-default.png?t=N7T8https://leetcode.cn/problems/kth-largest-element-in-an-array/参考解法:

    1. class Solution {
    2. public:
    3. int findKthLargest(vector<int>& nums, int k) {
    4. priority_queue<int> pq(nums.begin(), nums.end());
    5. while (--k)
    6. pq.pop();
    7. return pq.top();
    8. }
    9. };

            

    4.3 模拟实现

    1. template<class T>
    2. class Less
    3. {
    4. public:
    5. bool operator()(const T& x, const T& y)
    6. {
    7. return x < y;
    8. }
    9. };
    10. template<class T>
    11. class Greater
    12. {
    13. public:
    14. bool operator()(const T& x, const T& y)
    15. {
    16. return x > y;
    17. }
    18. };
    19. // class Less 和 class Greater 都是函数对象,具体知识参考后文
    20. namespace my_pq
    21. {
    22. template<class T, class Container = vector, class Compare = Less>
    23. class priority_queue
    24. {
    25. public:
    26. priority_queue()
    27. {}
    28. template <class InputIterator>
    29. priority_queue(InputIterator first, InputIterator last)
    30. :_con(first, last)
    31. {
    32. for (int i = (_con.size() - 2) / 2; i >= 0; --i)
    33. {
    34. adjust_down(i);
    35. }
    36. }
    37. void adjust_up(int child)
    38. {
    39. int parent = (child - 1) / 2;
    40. while (child > 0)
    41. {
    42. if (com(_con[parent], _con[child]))
    43. {
    44. swap(_con[child], _con[parent]);
    45. child = parent;
    46. parent = (child - 1) / 2;
    47. }
    48. else
    49. {
    50. break;
    51. }
    52. }
    53. }
    54. void adjust_down(int parent)
    55. {
    56. size_t child = parent * 2 + 1;
    57. while (child < _con.size())
    58. {
    59. if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
    60. {
    61. ++child;
    62. }
    63. if (com(_con[parent], _con[child]))
    64. {
    65. swap(_con[child], _con[parent]);
    66. parent = child;
    67. child = parent * 2 + 1;
    68. }
    69. else
    70. {
    71. break;
    72. }
    73. }
    74. }
    75. void push(const T& x)
    76. {
    77. _con.push_back(x);
    78. adjust_up(_con.size() - 1);
    79. }
    80. void pop()
    81. {
    82. swap(_con[0], _con[_con.size() - 1]);
    83. _con.pop_back();
    84. adjust_down(0);
    85. }
    86. const T& top()
    87. {
    88. return _con[0];
    89. }
    90. bool empty()
    91. {
    92. return _con.empty();
    93. }
    94. size_t size()
    95. {
    96. return _con.size();
    97. }
    98. private:
    99. Container _con;
    100. Compare com;
    101. };
    102. }

    效果演示:
            

            


    五、仿函数/函数对象 

    5.1 简要介绍        

            仿函数实际上并不是函数,只是使用起来与函数非常相似,故称为仿函数。本质上它是一个函数对象,我们通过一段代码来了解一下        

            借助模板和仿函数,我们就可以减少函数指针的使用,当然它也可以作为函数参数,为其它函数所用

    void qsort (void* base, size_t num, size_t size,
                int (*compar)(const void*,const void*));        
            这样的函数指针谁也不喜欢用
    

    我们还可以把仿函数用在其它类中,例如上面模拟实现的 priority_queue


  • 相关阅读:
    Docker——作为非运维人员,数据卷我们需要了解哪些?
    基于内容的个性化推荐算法
    GAN笔记:利普希茨连续(Lipschitz continuity)
    React 函数组件导出自定义方法的办法说明
    springboot整合返回数据统一封装
    【正点原子STM32连载】 第四十二章 IIC实验 摘自【正点原子】APM32F407最小系统板使用指南
    Centos7如何配置实现网卡的切换
    【计算机方向】通信、算法、自动化、机器人、电子电气、计算机工程、控制工程、计算机视觉~~~~~合集!!!
    UE5如何实现语言本地化管理(中英文切换)
    集合篇---Queue集合
  • 原文地址:https://blog.csdn.net/weixin_72501602/article/details/133560319