• C++从零开始的打怪升级之路(day38)


    这是关于一个普通双非本科大一学生的C++的学习记录贴

    在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料

    那么开启正题

    今天分享的是关于适配器了解以及一些简单适配器实现

    1.容器适配器

    1.1什么是适配器

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

    也就是我们常说的复用

    1.2deque

    虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和queue只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque

    deque又叫双端队列,大致性质就是一个指针数组,每个指针对应一段空间,如果数据存满了需要再存数据,只需再开一个指针,如果需要扩容也只是指针数组需要扩容,但是deque的迭代器相当复杂,有四个指针,这里不展开分析

    明明我们有vector和list,为什么需要deque这个容器呢

    deque的优点:支持随机访问,头插头删效率高,这很好得弥补了list和vector的不足,那deque可以取而代之吗,答案显而易见,我们来看deque的缺点

    deque的缺点:【】效率低,由于迭代器复杂,和本身复杂的结构,使deque的大量随机访问效率低,大概是vector时间的4~5倍,但是在stack,queue中并没有体现到他的缺陷,因此STL中的默认容器选择了它

    2.stack的模拟实现

    根据stack先进后出的性质我们可以借助vector或者deque模拟实现

    1. namespace wkl
    2. {
    3. template<class T, class Container = deque>
    4. class stack
    5. {
    6. public:
    7. stack()
    8. {
    9. ;
    10. }
    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. size_t size()
    24. {
    25. return _con.size();
    26. }
    27. bool empty()
    28. {
    29. return _con.empty();
    30. }
    31. private:
    32. Container _con;
    33. };
    34. void Test_stack()
    35. {
    36. stack<int> st;
    37. st.push(1);
    38. st.push(2);
    39. st.push(3);
    40. st.push(4);
    41. while (!st.empty())
    42. {
    43. cout << st.top() << " ";
    44. st.pop();
    45. }
    46. cout << endl;
    47. }
    48. }

    这是模拟实现代码,以及测试性质函数

    3.queue的模拟实现

    根据queue先进后出的性质我们可以借助list或者deque模拟实现

    1. namespace wkl
    2. {
    3. template<class T, class Container = deque>
    4. class queue
    5. {
    6. public:
    7. queue()
    8. {
    9. ;
    10. }
    11. void push(const T& x)
    12. {
    13. _con.push_back(x);
    14. }
    15. void pop()
    16. {
    17. _con.pop_front();
    18. }
    19. T& back()
    20. {
    21. return _con.back();
    22. }
    23. T& front()
    24. {
    25. return _con.front();
    26. }
    27. size_t size()
    28. {
    29. return _con.size();
    30. }
    31. bool empty()
    32. {
    33. return _con.empty();
    34. }
    35. private:
    36. Container _con;
    37. };
    38. void Test_queue()
    39. {
    40. queue<int> q;
    41. q.push(1);
    42. q.push(2);
    43. q.push(3);
    44. q.push(4);
    45. while (!q.empty())
    46. {
    47. cout << q.front() << " ";
    48. q.pop();
    49. }
    50. cout << endl;
    51. }
    52. }

    这是模拟实现代码,以及测试性质函数

    4.priority_queue

    4.1仿函数

    在了解priority_queue之前我们需要先了解仿函数

    我们来看下面的代码

    1. namespace wkl
    2. {
    3. template<class T>
    4. struct less
    5. {
    6. bool operator()(const T& x1, const T& x2)
    7. {
    8. return x1 < x2;
    9. }
    10. };
    11. void Test_less()
    12. {
    13. less<int> l;
    14. cout << l(1, 2) << endl;
    15. }
    16. }

    cout << l(1, 2) << endl;这一行代码看起来很像函数调用,但实际上不是的

    他是根据对象的operator()对()进行重载,再调用函数,因为看起来像函数,因此被称为仿函数

    仿函数属于STL的四大容器之一

    4.2priority_queue的模拟实现

    优先级队列也是一种适配器,优先级队列的底层实际上是由堆来实现的,我们这里用vector来模拟实现

    1. namespace wkl
    2. {
    3. //仿函数 函数对象 (对象可以和函数一样调用)
    4. template<class T>
    5. struct less
    6. {
    7. bool operator()(const T& x1, const T& x2)
    8. {
    9. return x1 < x2;
    10. }
    11. };
    12. template<class T>
    13. struct greater
    14. {
    15. bool operator()(const T& x1, const T& x2)
    16. {
    17. return x1 > x2;
    18. }
    19. };
    20. template<class T, class Container = vector, class Comapre = less>
    21. class priority_queue //默认是大堆
    22. {
    23. public:
    24. Comapre com;
    25. void AdjustUp(int child)
    26. {
    27. int parent = (child - 1) / 2;
    28. while (child > 0)
    29. {
    30. //if (_con[child] > _con[parent])
    31. if (com(_con[parent], _con[child]))
    32. {
    33. swap(_con[child], _con[parent]);
    34. child = parent;
    35. parent = (child - 1) / 2;
    36. }
    37. else
    38. {
    39. break;
    40. }
    41. }
    42. }
    43. void push(const T& x)
    44. {
    45. _con.push_back(x);
    46. AdjustUp(_con.size() - 1);
    47. }
    48. void AdjustDown(int root)
    49. {
    50. Comapre com;
    51. int parent = root;
    52. int child = parent * 2 + 1;
    53. while (child < _con.size())
    54. {
    55. //if (child + 1 < _con.size() && _con[child + 1] > _con[child])
    56. if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
    57. {
    58. ++child;
    59. }
    60. //if (_con[child] > _con[parent])
    61. if (com(_con[parent], _con[child]))
    62. {
    63. swap(_con[child], _con[parent]);
    64. parent = child;
    65. child = parent * 2 + 1;
    66. }
    67. else
    68. {
    69. break;
    70. }
    71. }
    72. }
    73. void pop()
    74. {
    75. swap(_con[0], _con[_con.size() - 1]);
    76. _con.pop_back();
    77. AdjustDown(0);
    78. }
    79. T& top()
    80. {
    81. return _con[0];
    82. }
    83. size_t size()
    84. {
    85. return _con.size();
    86. }
    87. bool empty()
    88. {
    89. return _con.empty();
    90. }
    91. private:
    92. Container _con;
    93. };
    94. void Test_priority_queue()
    95. {
    96. priority_queue<int> pq;
    97. pq.push(9);
    98. pq.push(3);
    99. pq.push(7);
    100. pq.push(0);
    101. while (!pq.empty())
    102. {
    103. cout << pq.top() << " ";
    104. pq.pop();
    105. }
    106. cout << endl;
    107. }
    108. }

    这是模拟实现代码,以及测试性质函数

     新手写博客,有不对的位置希望大佬们能够指出,也谢谢大家能看到这里,让我们一起学习进步吧!!

  • 相关阅读:
    Flink 1.13 源码解析——TaskManager启动流程概览
    验证周期--一个结构化的流程
    springboot使用nacos
    字符串压缩(三)之短字符串压缩
    deepin(深度)系统下qt5.12.0的程序打包发布给其他linux机器使用
    QGIS提取两条线元素的交点
    模拟卷Leetcode【普通】341. 扁平化嵌套列表迭代器
    计算机毕业设计ssm+vue基本微信小程序的一起考研学习系统
    java毕业设计水利施工安全检测系统设mybatis+源码+调试部署+系统+数据库+lw
    基于bp神经网络的pid算法,基于单神经元的pid控制
  • 原文地址:https://blog.csdn.net/2301_80764270/article/details/136370229