• STL-stack、queue和priority_queue的模拟实现


    目录

    一、容器适配器

    (一)什么是适配器

    (二)stack和queue的底层结构

    二、Stack

    三、queue

    四、deque双端队列

    (一)优点

    (二)缺陷

    五、优先级队列

    (一)介绍

    (二)仿函数

    (三)模拟实现一

    (四)模拟实现(带compare)


    一、容器适配器

    (一)什么是适配器

    适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口

    (二)stack和queue的底层结构

    • stack和queue没有迭代器

    Container 也是一个模板参数,它用于指定在 stack 内部使用的容器类型。默认情况下,它使用了一个 deque(双端队列)作为内部容器,但你也可以自定义一个不同类型的容器来替代它 。

    二、Stack

    • 模拟实现stack,stack是先进后出
    1. #pragma once
    2. #include
    3. #include
    4. using namespace std;
    5. namespace Imitate_stack
    6. {
    7. template <class T, class Container = 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. const T& top()
    20. {
    21. return _con.back();//用于返回双端队列的最右端(尾部)元素,但不会从队列中删除该元素
    22. }
    23. bool empty()
    24. {
    25. return _con.empty();
    26. }
    27. size_t size()
    28. {
    29. return _con.size();
    30. }
    31. private:
    32. Container _con;
    33. };
    34. }

    三、queue

    • queue是先进先出
    1. #pragma once
    2. #include
    3. #include
    4. using namespace std;
    5. namespace Imitate_stack
    6. {
    7. template <class T, class Container = deque >
    8. class queue
    9. {
    10. public:
    11. void push(const T& x)//尾插
    12. {
    13. _con.push_back(x);
    14. }
    15. void pop()//头删
    16. {
    17. _con.pop_front();
    18. }
    19. const T& back()//得到尾部数据
    20. {
    21. return _con.back();
    22. }
    23. const T& front()//得到头部数据
    24. {
    25. return _con.front();
    26. }
    27. bool empty()
    28. {
    29. return _con.empty();
    30. }
    31. size_t size()
    32. {
    33. return _con.size();
    34. }
    35. private:
    36. Container _con;
    37. };
    38. }

    四、deque双端队列

    (一)优点

    是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1)

    • 与vector比较,头插效率高,不需要搬移元素
    • 与list比较,空间利用率比较高

    (二)缺陷

    • 下标的随机访问不如vector
    • 中间插入、删除速度不如list
    • 不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到
      某段小空间的边界,导致效率低下

    五、优先级队列

    (一)介绍

    1. priority_queue<int> first;//建立大根堆
    2. priority_queue<int> first(data.begin(), data.end());//建立大根堆
    3. priority_queue<int, vector<int>, greater<int>> second;//建立小根堆
    1. #include
    2. #include
    3. using namespace std;
    4. int main()
    5. {
    6. priority_queue<int> first;//建立大根堆
    7. first.push(56);
    8. first.push(12);
    9. first.push(67);
    10. first.push(1);
    11. first.push(78);
    12. first.push(6);
    13. while (!first.empty())//78 67 56 12 6 1
    14. {
    15. cout << first.top() << " ";
    16. first.pop();
    17. }
    18. return 0;
    19. }
    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. int main()
    6. {
    7. vector<int>data = {56,12,67,1,78,6};
    8. priority_queue<int> first(data.begin(), data.end());//建立大根堆
    9. while (!first.empty())//78 67 56 12 6 1
    10. {
    11. cout << first.top() << " ";
    12. first.pop();
    13. }
    14. return 0;
    15. }
    1. #include
    2. #include
    3. using namespace std;
    4. int main()
    5. {
    6. priority_queue<int, vector<int>, greater<int>> second;//建立小根堆
    7. second.push(56);
    8. second.push(12);
    9. second.push(67);
    10. second.push(1);
    11. second.push(78);
    12. second.push(6);
    13. while (!second.empty())//1 6 12 56 67 78
    14. {
    15. cout << second.top() << " ";
    16. second.pop();
    17. }
    18. return 0;
    19. }

    (二)仿函数

    1. #include
    2. using namespace std;
    3. template<class T>
    4. class Less
    5. {
    6. public:
    7. bool operator()(const T& x, const T& y)
    8. {
    9. return x < y;
    10. }
    11. };
    12. template<class T>
    13. class greater
    14. {
    15. public:
    16. bool operator()(const T& x, const T& y)
    17. {
    18. return x > y;
    19. }
    20. };
    21. int main()
    22. {
    23. Less<int> less1;//函数对象
    24. cout << less1(1, 3) << endl;
    25. Less<double> less2;
    26. cout << less1(4.5, 3.5) << endl;
    27. return 0;
    28. }

    (三)模拟实现一

    1. //PriorityQueue.h
    2. #pragma once
    3. #include
    4. #include
    5. using namespace std;
    6. namespace Imitate_priorityQueue
    7. {
    8. template<class T, class Container = vector>
    9. class priority_queue
    10. {
    11. public:
    12. void adjust_up(int child)//向上调整
    13. {
    14. int parent = (child - 1) / 2;
    15. while (child >0 )
    16. {
    17. if (_con[child] > _con[parent])//建立大根堆
    18. {
    19. swap(_con[child], _con[parent]);
    20. child = parent;
    21. parent = (child - 1) / 2;
    22. }
    23. else
    24. {
    25. break;
    26. }
    27. }
    28. }
    29. void adjust_down(int parent)//向下调整
    30. {
    31. int child = parent * 2 + 1;
    32. while (child < _con.size())
    33. {
    34. if (child + 1 < _con.size() && _con[child] < _con[child + 1])//开始默认右孩子大
    35. {
    36. ++child;
    37. }
    38. if (_con[child] > _con[parent])
    39. {
    40. swap(_con[child], _con[parent]);
    41. parent=child;
    42. child = parent * 2 + 1;
    43. }
    44. else
    45. {
    46. break;
    47. }
    48. }
    49. }
    50. void push(const T& x)
    51. {
    52. _con.push_back(x);
    53. adjust_up(_con.size() - 1);
    54. }
    55. void pop()
    56. {
    57. swap(_con[0], _con[_con.size() - 1]);
    58. _con.pop_back();
    59. adjust_down(0);
    60. }
    61. const T& top()const
    62. {
    63. return _con.front();
    64. }
    65. bool empty()const
    66. {
    67. return _con.empty();
    68. }
    69. private:
    70. Container _con;
    71. };
    72. }
    1. //test.cpp
    2. #include"PriorityQueue.h"
    3. int main()
    4. {
    5. Imitate_priorityQueue::priority_queue<int, vector<int>> q;
    6. q.push(89);
    7. q.push(1);
    8. q.push(45);
    9. q.push(14);
    10. q.push(11);
    11. q.push(19);
    12. while (!q.empty())//89 45 19 14 11 1
    13. {
    14. cout << q.top() << " ";
    15. q.pop();
    16. }
    17. return 0;
    18. }

    (四)模拟实现(带compare)

    1. //PriorityQueue.h
    2. #pragma once
    3. #include
    4. #include
    5. using namespace std;
    6. namespace Imitate_priorityQueue
    7. {
    8. 比较方式
    9. template<class T>
    10. struct less
    11. {
    12. bool operator()(const T& x, const T& y)
    13. {
    14. return x < y;
    15. }
    16. };
    17. //比较方式
    18. template<class T>
    19. struct greater
    20. {
    21. bool operator()(const T& x, const T& y)
    22. {
    23. return x > y;
    24. }
    25. };
    26. template<class T, class Container = vector, class Compare = less>
    27. class priority_queue
    28. {
    29. public:
    30. void adjust_up(int child)//向上调整
    31. {
    32. int parent = (child - 1) / 2;
    33. while (child >0 )
    34. {
    35. if (_com(_con[parent],_con[child]))
    36. {
    37. swap(_con[child], _con[parent]);
    38. child = parent;
    39. parent = (child - 1) / 2;
    40. }
    41. else
    42. {
    43. break;
    44. }
    45. }
    46. }
    47. void adjust_down(int parent)//向下调整
    48. {
    49. int child = parent * 2 + 1;
    50. while (child < _con.size())
    51. {
    52. if (child + 1 < _con.size() && _com(_con[child] , _con[child + 1]))//开始默认右孩子大
    53. {
    54. ++child;
    55. }
    56. if (_com(_con[parent], _con[child]))
    57. {
    58. swap(_con[child], _con[parent]);
    59. parent=child;
    60. child = parent * 2 + 1;
    61. }
    62. else
    63. {
    64. break;
    65. }
    66. }
    67. }
    68. void push(const T& x)
    69. {
    70. _con.push_back(x);
    71. adjust_up(_con.size() - 1);
    72. }
    73. void pop()
    74. {
    75. swap(_con[0], _con[_con.size() - 1]);
    76. _con.pop_back();
    77. adjust_down(0);
    78. }
    79. const T& top()const
    80. {
    81. return _con.front();
    82. }
    83. bool empty()const
    84. {
    85. return _con.empty();
    86. }
    87. private:
    88. Container _con;
    89. Compare _com;
    90. };
    91. }
    1. #include"PriorityQueue.h"
    2. int main()
    3. {
    4. Imitate_priorityQueue::priority_queue<int, vector<int>, greater<int>> q;
    5. q.push(89);
    6. q.push(1);
    7. q.push(45);
    8. q.push(14);
    9. q.push(11);
    10. q.push(19);
    11. while (!q.empty())
    12. {
    13. cout << q.top() << " ";
    14. q.pop();
    15. }
    16. return 0;
    17. }

  • 相关阅读:
    eslint+prettier配置流程
    [附源码]JAVA毕业设计旅游景点展示平台的设计与实现(系统+LW)
    八、PL/SQL 记录
    C语言数组相关问题深度理解
    apache poi excel export
    啥样的python语法值得收藏?
    南大通用GBase8s 常用SQL语句(256)
    SpringMVC ---- SpringMVC的视图
    Remote access minikube cluster远程访问minikube k8s集群
    乘法逆元、模运算
  • 原文地址:https://blog.csdn.net/m0_63783532/article/details/132954618