• C++(适配器):stack和queue的底层实现,以及优先级队列和仿函数


    stack和queue的接口比较简单,使用起来也十分方便,只需要注意一个先进先出、后进先出就可以

    1. void test_queue()
    2. {
    3. queue<int> qe;
    4. qe.push(1);
    5. qe.push(2);
    6. qe.push(3);
    7. qe.push(4);
    8. qe.push(5);
    9. while (!qe.empty())
    10. {
    11. cout << qe.front() << "-";
    12. qe.pop();
    13. }
    14. }
    1. void test_stack()
    2. {
    3. stack<int> st;
    4. st.push(1);
    5. st.push(2);
    6. st.push(3);
    7. st.push(4);
    8. while (!st.empty())
    9. {
    10. cout << st.top() << "-";
    11. st.pop();
    12. }
    13. cout << endl;
    14. }

    这是他们的使用比较简单,这里不再赘述。下面来讲他的底层实现,底层可以使用很多容器去实现他比如vector、只需要注意这两个适配器都不允许遍历。他的底层实现主要是来自于一个新的容器deque(双向队列)这是一个集合了vector和list的优点的容器,缺点就是遍历效率太低导致他无法代替vector。

    这里可以测试一下deque和vector遍历的效率

    1. void test_deque()
    2. {
    3. deque<int> d;
    4. vector<int> v;
    5. srand(time(nullptr));
    6. for (int i = 0; i < 10000; i++)
    7. {
    8. int randnums = rand();
    9. d.push_back(randnums);
    10. v.push_back(randnums);
    11. }
    12. size_t begin1 = clock();
    13. sort(d.begin(), d.end());
    14. size_t end1 = clock();
    15. size_t begin2 = clock();
    16. sort(v.begin(), v.end());
    17. size_t end2 = clock();
    18. cout << end1 - begin1<< endl;
    19. cout << end2 - begin2 << endl;
    20. }
    1. //队列的模拟实现
    2. template<class T, class Container>
    3. class queue
    4. {
    5. public:
    6. void push(const T& x)
    7. {
    8. _con.push_back(x);
    9. }
    10. void pop()
    11. {
    12. _con.pop_front();
    13. }
    14. bool empty()
    15. {
    16. return _con.empty();
    17. }
    18. size_t size()
    19. {
    20. return _con.size();
    21. }
    22. T& back()
    23. {
    24. return _con.back();
    25. }
    26. T& front()
    27. {
    28. return _con.front();
    29. }
    30. //栈的模拟实现
    31. template<class T, class Container>
    32. class stack
    33. {
    34. public:
    35. void push(const T& x)
    36. {
    37. _con.push_back(x);
    38. }
    39. void pop()
    40. {
    41. _con.pop_back();
    42. }
    43. size_t size()
    44. {
    45. return _con.size();
    46. }
    47. T& top()
    48. {
    49. return _con.back();
    50. }
    51. bool empty()
    52. {
    53. return _con.empty();
    54. }
    55. private:
    56. Container _con;
    57. };

    优先级队列和普通队列主要的不同就在于,出的顺序。优先级高的先出在优先级队列中,普通队列是先进先出。优先级队列的底层实现是一个堆,这样子方便弹出优先级高的数据,写一个堆主要是写向上调整函数和向下调整函数,其他地方都比较简单,下面是代码实现

    1. template<class T, class Container = vector,class Compare = less>
    2. class priority_queue
    3. {
    4. public:
    5. void Adjustup(int child)
    6. {
    7. Compare com;
    8. int parent = (child - 1) / 2;
    9. while (child>0)
    10. {
    11. if (com(_con[parent], _con[child]))
    12. {
    13. swap(_con[child], _con[parent]);
    14. child = parent;
    15. parent = (child - 1) / 2;
    16. }
    17. else
    18. break;
    19. }
    20. }
    21. void Adjustdown(int parent)
    22. {
    23. size_t child = parent * 2 + 1;
    24. Compare cmp;
    25. while (child < _con.size())
    26. {
    27. if (child + 1 < _con.size () && cmp(_con[child],_con[child+1]))
    28. child++;
    29. if (cmp(_con[parent] , _con[child]))
    30. {
    31. swap(_con[child], _con[parent]);
    32. parent = child;
    33. child = parent * 2 + 1;
    34. }
    35. else
    36. break;
    37. }
    38. }
    39. void push(const T& x)
    40. {
    41. _con.push_back(x);
    42. Adjustup(_con.size() - 1);
    43. }
    44. void pop()
    45. {
    46. swap(_con[0], _con[_con.size() - 1]);
    47. _con.pop_back();
    48. Adjustdown(0);
    49. }
    50. T& top()
    51. {
    52. return _con[0];
    53. }
    54. size_t size()
    55. {
    56. return _con.size();
    57. }
    58. bool empty()
    59. {
    60. return _con.empty();
    61. }
    62. private:
    63. Container _con;
    64. };

    仿函数主要是写一个类重载operator()(参数)函数,使得这个类的实例化对象可以像函数一样去使用,这就是仿函数,例如

    1. template<class T>
    2. struct less
    3. {
    4. bool operator()(T& e1, T& e2)
    5. {
    6. return e1 < e2;
    7. }
    8. };
    9. template<class T>
    10. struct greater
    11. {
    12. bool operator()(T& e1, T& e2)
    13. {
    14. return e1 > e2;
    15. }
    16. };

    这两个类实例化的对象就是调整大堆和小堆的关键,他还在排序算法中被使用

    1. void test_sort()
    2. {
    3. vector<int> v;
    4. v.push_back(1);
    5. v.push_back(4);
    6. v.push_back(3);
    7. v.push_back(6);
    8. v.push_back(7);
    9. //默认升序
    10. sort(v.begin(), v.end());
    11. for (auto nums : v)
    12. {
    13. cout << nums << " ";
    14. }
    15. cout << endl;
    16. //调成降序
    17. sort(v.begin(), v.end(), greater<int>());
    18. for (auto nums : v)
    19. {
    20. cout << nums << " ";
    21. }
    22. }

  • 相关阅读:
    达梦数据库常用SQL之生成启用自增列表插入功能及insert插入语句
    女同桌找我要表情包,还好我会Python,分分钟给她下载几十个G...
    听说转行软件测试只能自学,培训机构是个坑?
    电脑文件数据恢复有哪些方法?电脑怎么恢复已删除的文件数据?
    【VCSA 8】安装vCenter Server Appliance(VCSA) 8.0
    操作系统复习:死锁
    Arduino驱动LIS2DH三轴加速度传感器(惯性测量传感器篇)
    聚观早报 | iPhone14或于9月23日上市;腾讯发布Max 二代机器人
    10 创建型模式-原型模式
    绘制核密度估计图
  • 原文地址:https://blog.csdn.net/2301_77312705/article/details/134453137