Sort排序+STL队列+优先队列小结

    Sort排序:

        普通数组:

                          sort排序比qsort排序简单多了,这里只对sort排序做了总结。

        头文件:   #include<algorithm> using namespace std ;

                         sort(数组名,数组名+元素个数) ;例如:int/char/double  a[ 1000 ] ; 假设里面已经赋了n个值,sort(a,a+n);这是从小到大排序。 sort(数组名,数组名+元素个数,cmp) ;int/char/double  cmp(int/char/double  a ,int/char/double  b ){    return  a > b ;    }从大到小排序。

       结构体排序:

       直接上代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
struct zhang
{
    int x,y;
}t[1000];
bool cmp(zhang a,zhang b)
{
    return a.x > b.x ;//按x从大到小排序 "<"从小到大排序 同普通数组
    // strcmp(a.s,b.s) > 0 ? 1 : 0 ; // 比较字符串,大于0 降序,反之升序
}
int main()
{
     for(int i=0;i<10;i++)
       scanf("%d%d",&t[i].x,&t[i].y);
       sort(t,t+9,cmp);
    for(int i=0;i<9;i++)
      printf("%d %d\n",t[i].x,t[i].y);
    return 0;
}

 

  STL队列:

      概念:  Queue队列容器是一个先进先出的线性存储表,元素的插入只能在队尾,元素的删除只能在队首。

使用Queue需要声明头文件“#include <queue>  + using namespace std ”;

   基本运算:     

                 queue<int>q;申请q的队列

                 q.push():入队,即插入元素

                 q.pop():出队,即删除元素

                 q.front():读取队首元素

                 q.back():读取队尾元素

                 q.empty():判断队列是否为空,是返回 1 ,不是返回 0 。

                 q.size():队列当前元素有多少

STL 栈 :

   概念: 栈和队列其实差不多,栈是后进先出的一种线性存储表。使用时需要申明头文件“#include<stack> + using namespace std ”。不管栈还是队列在做题时运行完一定要记得清空。

基本运算:

        stack<int>s ;申请栈

        s.push( ) : 入栈,即插入元素

        s.pop( ) : 出栈,即删除元素

        s.top( ) : 读取队首元素(此处与队列不同)

        s.empty( ) : 判断队列是否为空,是返回 1 ,不是返回 0 。

        s.size( ) : 栈当前元素有多少

  优先队列:

    概念:  优先队列和STL队列不同之处就是优先队列可以按照优先级出队(可以进行排序),在优先队列中,优先级高的元素先出队列。标准库默认使用元素类型的 < 操作符来确定它们之间的优先级关系。如果不写结构体默认为大的优先,如果想让小的先出队:priority_queue<int, vector<int>, greater<int> >qi2;

    基本运算:头文件#include<queue> using namespace std;

#include<stdio.h>
#include<queue>
using namespace std;
struct zhang  
{  
   int x,y,z;  
     friend bool operator<(const zhang &a,const zhang &b)//operator后 " < " 很重要!!
    {  
            return a.x < b.x ;//从大到小出队 " > " 从小到大出队 
    }  
  
};  
priority_queue<zhang>q;//尽量把这个放进int main()里
zhang current,next; 

比较多个数出队:

#include<stdio.h>
#include<queue>
using namespace std;
struct zhang  
{  
   int x,y,z;  
     friend bool operator<(const zhang &a,const zhang &b)
    {  
        if(a.x!=b.x)
             return a.x < b.x ;//从大到小出队 " > " 从小到大出队(和普通排序相反) 
        else if(a.y!=b.y)
             return a.y > b.y ;//从大到小出队
        else 
             return a.z < b.z ;
    }  
  
};  
priority_queue<zhang>q;
zhang current,next; 


不比较优先级:

#include<stdio.h>
#include<queue>
using namespace std;
struct zhang
{
   int x,y,z;
};
queue<zhang>q;
zhang current,next;

deque(双端队列)

简介:

         deque  双端队列容器 ( double - ended queue ) 与 vector 非常相似,deque 内部的数据机制和执行性能与 vector 不同,一般来说,当考虑到容器元素的内存分配策略和操作的性能时 ,deque 相对于 vector 较为有优势。deque 双端队列采用分块的线性结构来存储数据,具有高效的删除首位元素的函数,由于 deque 容器是以 deque 块为单位进行内存的分配,并使用了二级的 Map 进行管理,因此不容易实现类似于 vector 的 capacity 和 reverse 函数,而且 deque 容器也不需要这样的获取和调整容大小的函数。

操作:

       创建:

         deque<类型>对象名;

         deque<int>q ;  // 创建一个空的deque对象; 

          deque<int>q(20) //创建具有n个元素的deque对象;

          deque<int>q(20 ,5) ;// 创建一个具有n个元素的deque对象,每个元素具有初始值(这里为 5);

          deque<int> q(20 ,5) ; deque<int> p(q) ; //拷贝对象

           int a[10] = {1 ,2 ,3} ,deque<int> q(a ,a+3) ; // 拷贝区间的元素

    插入:

           q.push_front()  ; // 在头部插入元素

           q.push_back() ; // 在尾部插入元素

    删除:

            q.pop_front() ; // 删除头部元素

            q.pop_back() ; // 删除尾部元素

             q.erase(q.begin() + x)  ;// 删除某个位置的元素

             q.clear() ; // 清空容器

     遍历:

            deque<int>::iterator i ,j ; // 遍历器

     交换:

             q.swap(p) ; // 两个容器的元素交换

     vector的功能deque差不多都延续过来了,这里不再介绍。

            


 

    















  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,我可以为您解答这个问题。 0-1背包问题是动态规划问题中的一个经典问题,其目的是在给定一组物品和一个背包容量的情况下,选择一些物品放入背包中,使得背包中物品的总价值最大。而分支限界法是一种搜索算法,它可以通过优先队列来维护搜索状态空间中的结点,从而提高搜索效率。 下面是使用C++ STL最小堆来实现已搜索的解状态空间结点的优先级队列的代码: ```c++ #include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; // 物品结构体 struct Item { int weight; // 物品重量 int value; // 物品价值 }; // 结点结构体 struct Node { int level; // 结点所在层数 int profit; // 当前背包中物品的总价值 int weight; // 当前背包中物品的总重量 vector<bool> solution; // 当前背包中物品的选择情况 double bound; // 当前结点的价值上界 bool operator<(const Node& other) const { // 重载小于号,用于STL最小堆排序 return bound < other.bound; } }; // 计算结点的价值上界 double calc_bound(const vector<Item>& items, const Node& node, int capacity) { double bound = node.profit; int weight = node.weight; int level = node.level; while (level < items.size() && weight + items[level].weight <= capacity) { bound += items[level].value; weight += items[level].weight; level++; } if (level < items.size()) { bound += (capacity - weight) * items[level].value / (double)items[level].weight; } return bound; } // 分支限界法求解0-1背包问题 int knapsack(const vector<Item>& items, int capacity) { // 按照单位重量的价值从大到小排序 vector<int> indices(items.size()); iota(indices.begin(), indices.end(), 0); sort(indices.begin(), indices.end(), [&items](int i, int j) { return items[i].value * 1.0 / items[i].weight > items[j].value * 1.0 / items[j].weight; }); // 初始化根结点 Node root = {0, 0, 0, vector<bool>(items.size(), 0), 0}; root.bound = calc_bound(items, root, capacity); // 初始化最小堆 priority_queue<Node> Q; Q.push(root); // 开始搜索 int max_profit = 0; while (!Q.empty()) { Node cur = Q.top(); Q.pop(); if (cur.bound < max_profit) { continue; } if (cur.level == items.size()) { max_profit = max(max_profit, cur.profit); continue; } // 选择当前物品 Node left = cur; left.level++; left.weight += items[indices[left.level - 1]].weight; left.profit += items[indices[left.level - 1]].value; left.solution[indices[left.level - 1]] = true; if (left.weight <= capacity) { left.bound = calc_bound(items, left, capacity); if (left.bound > max_profit) { Q.push(left); } } // 不选择当前物品 Node right = cur; right.level++; right.bound = calc_bound(items, right, capacity); if (right.bound > max_profit) { Q.push(right); } } return max_profit; } int main() { vector<Item> items = {{10, 60}, {20, 100}, {30, 120}}; int capacity = 50; int max_profit = knapsack(items, capacity); cout << "Max Profit: " << max_profit << endl; return 0; } ``` 在这个代码中,我们定义了一个`Item`结构体来存储物品的重量和价值信息,还定义了一个`Node`结构体来存储搜索状态空间中的结点信息。在`Node`结构体中,我们还重载了小于号运算符,这是为了让我们可以使用STL的最小堆来维护搜索结点的优先级。 在`calc_bound`函数中,我们计算了当前结点的价值上界,这是通过贪心的思路来计算的。具体来说,我们首先将当前结点的背包填满,然后尝试将下一个物品放入背包中,直到背包装不下为止。最后,我们将装不下的部分按照单位重量的价值比例来进行计算,从而得到当前结点的价值上界。 在`knapsack`函数中,我们使用了一个最小堆来维护搜索结点的优先级。在每一次循环中,我们取出最小堆中的顶部结点,然后根据当前结点的状态进行分支限界搜索。具体来说,我们分别考虑选择当前物品和不选择当前物品两种情况,然后计算子结点的价值上界,并将符合条件的子结点压入最小堆中。如果当前结点的价值上界小于已搜索到的最大价值,则可以剪枝,继续搜索下一个结点。 最后,在`main`函数中,我们定义了一个简单的0-1背包问题实例,然后调用`knapsack`函数求解,最终输出结果。 希望这个解答能够帮助到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值