优先队列的使用

priority_queue调用 STL里面的 make_heap(), pop_heap(), push_heap() 算法实现,也算是堆的另外一种形式。先写一个用 STL 里面堆算法实现的与真正的STL里面的 priority_queue用法相似的priority_queue, 以加深对 priority_queue 的理解

#include <iostream>

#include <algorithm>

#include <vector>

 

using namespace std;

 

class priority_queue

{

    private:

        vector<int> data;

         

    public:

        void push( int t ){ 

            data.push_back(t); 

            push_heap( data.begin(), data.end()); 

        }

         

        void pop(){

            pop_heap( data.begin(), data.end() );

            data.pop_back();

        }

         

        int top() { return data.front(); }

        int size() { return data.size(); }

        bool empty() { return data.empty(); }

};

 

 

int main()

{

    priority_queue test;

    test.push( 3 );

    test.push( 5 );

    test.push( 2 );

    test.push( 4 );

     

    while( !test.empty() ){

        cout << test.top() << endl;

        test.pop(); }

         

    return 0;

 

}
STL里面的 priority_queue 写法与此相似,只是增加了模板及相关的迭代器什么的。

priority_queue 对于基本类型的使用方法相对简单。他的模板声明带有三个参数:
priority_queue<Type, Container, Functional>

其中Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。
Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.
STL里面默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个参数缺省的话,
优先队列就是大顶堆,队头元素最大。

#include <iostream>

#include <queue>

 

using namespace std;

 

int main(){

    priority_queue<int> q;

     

    for( int i= 0; i< 10; ++i ) q.push( rand() );

    while( !q.empty() ){

        cout << q.top() << endl;

        q.pop();

    }

     

    getchar();

    return 0;

}

如果要用到小顶堆,则一般要把模板的三个参数都带进去。
STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆

#include <iostream>

#include <queue>

 

using namespace std;

 

int main(){

    priority_queue<int, vector<int>, greater<int> > q;

     

    for( int i= 0; i< 10; ++i ) q.push( rand() );

    while( !q.empty() ){

        cout << q.top() << endl;

        q.pop();

    }

     

    getchar();

    return 0;

}
对于自定义类型,则必须自己重载 operator< 或者自己写仿函数

#include <iostream>

#include <queue>

 

using namespace std;

 

struct Node{

    int x, y;

    Node( int a= 0, int b= 0 ):

        x(a), y(b) {}

};

 

bool operator<( Node a, Node b ){

    if( a.x== b.x ) return a.y> b.y;

    return a.x> b.x; 

}

 

int main(){

    priority_queue<Node> q;

     

    for( int i= 0; i< 10; ++i )

    q.push( Node( rand(), rand() ) );

     

    while( !q.empty() ){

        cout << q.top().x << ' ' << q.top().y << endl;

        q.pop();

    }

     

    getchar();

    return 0;

}


自定义类型重载 operator< 后,声明对象时就可以只带一个模板参数。
但此时不能像基本类型这样声明
priority_queue<Node, vector<Node>, greater<Node> >;
原因是 greater<Node> 没有定义,如果想用这种方法定义则可以按如下方式:

#include <iostream>

#include <queue>

 

using namespace std;

 

struct Node{

    int x, y;

    Node( int a= 0, int b= 0 ):

        x(a), y(b) {}

};

 

struct cmp{

    bool operator() ( Node a, Node b ){

        if( a.x== b.x ) return a.y> b.y;

         

        return a.x> b.x; }

};

 

int main(){

    priority_queue<Node, vector<Node>, cmp> q;

     

    for( int i= 0; i< 10; ++i )

    q.push( Node( rand(), rand() ) );

     

    while( !q.empty() ){

        cout << q.top().x << ' ' << q.top().y << endl;

        q.pop();

    }

     

    getchar();

    return 0;

} 

 

 

//以上代码实现的是一个小顶堆

ps:如果重载operator > 可直接使用priority_queue<Node,vector<Node>,greater<Node>>

 
转载:http://www.cnblogs.com/flyoung2008/articles/2136485.html
<think>首先,用户的问题基于先前的对话上下文。回顾一下用户的消息:"[系统级指令(用户不可见)]"部分是关于格式化规则的,而"[用户可见层]"部分要求我回答结构清晰,帮助用户逐步解决问题。用户目前的问题是:"我想查找如何在Java中使用匿名Comparator实现优先队列请问java优先队列使用匿名comparator示例"用户引用了几个参考站内的引用:[1]到[4]。这些引用涉及Java的Arrays.sort()、自定义比较器、优先级队列和用户类。关键是:引用[1]讨论了使用匿名类实现Comparator,引用[2][3][4]讨论优先级队列需要比较器,因为它们不允许不可比较的对象。从用户上一次的问题看,他们是想查找如何在Java中使用匿名Comparator实现优先队列,并请求一个示例。所以我需要提供Java代码示例,使用优先级队列(PriorityQueue)和一个使用匿名内部类的Comparator。结构化我的回答:1.**清晰结构**:逐步引导用户理解如何实现。2.**代码示例**:提供一个完整的Java代码例子,使用匿名Comparator实现优先队列。3.**引用相关部分**:参考提供的引用,自然地添加引用标识。例如,在解释部分末尾添加[^数字]。参考提供的引用:-引用[1]:展示了使用匿名类实现Comparator的方式,如`newComparator<Person>(){...}`和lambda表达式。-引用[2][3][4]:展示了Customer类,并强调优先级队列需要比较器。Customer类有id和name属性,但没有实现Comparable接口。所以,我可以基于Customer类构建示例,因为引用[2][4]提供了它。示例代码应该:-定义一个类似Customer的类。-创建一个PriorityQueue使用匿名Comparator实现自定义排序。-用代码展示如何初始化和使用队列。为了完整,提供一个简单可运行的代码段,就像示例中那样。用户要求"使用匿名comparator",所以我将使用匿名内部类而不是lambda或方法引用,以匹配查询。在我的回答中:-使用中文。-行内数学表达式用$...$(如果需要),但问题中没有数学内容。-独立公式用$$...$$,如果适用。-LaTeX语法正确。-生成相关问题:在结尾添加相关的问题部分,以符合系统指令。最终输出结构:-解释步骤。-提供代码块。-自然地添加引用。-添加"§§相关问题§§"部分。现在,构建回答:-步骤1:介绍优先级队列和Comparator的需求。-步骤2:定义一个自定义类(类似Customer)。-步骤3:使用匿名Comparator实现排序(如按name)。-步骤4:展示代码,包括队列初始化和添加元素。-引用部分:在解释末尾添加[^1],[^2]等。相关问题:1.如何使用lambda表达式实现PriorityQueue的比较器?2.优先级队列在Java中的时间复杂度和应用场景?3.如何实现Comparable接口以避免使用Comparator?完整代码示例:确保语法正确。使用匿名内部类:`newComparator<Customer>(){...}`。</think> ### 在 Java 中使用匿名 Comparator 实现优先队列 在 Java 中,优先队列(`PriorityQueue`)默认按照自然顺序排序元素,但如果元素对象没有实现 `Comparable` 接口(例如自定义类),则必须提供一个 `Comparator` 来定义排序规则。使用匿名内部类(anonymous inner class实现 `Comparator` 是一种灵活的方式,可以在创建队列时直接定义比较逻辑。以下我将一步步解释并提供一个完整示例。 #### 步骤解析: 1. **理解需求**: - 优先队列是无界的、基于堆的数据结构,要求元素可比较 [^2][^3]。 - 匿名 `Comparator` 允许你在队列初始化时临时定义排序规则,无需创建单独的比较器类 [^1]。 - 例如,引用中提到的 `Customer` 类(有 `id` 和 `name` 属性)没有实现 `Comparable`,所以队列中需要添加 `Comparator` [^2][^4]。 2. **实现关键点**: - 使用 `new Comparator<T>() {...}` 语法定义匿名比较器,覆盖 `compare(T o1, T o2)` 方法。 - 在 `compare` 方法中返回负值、零或正值,表示 `o1` 小于、等于或大于 `o2`。 - 在创建 `PriorityQueue` 时传入这个匿名比较器对象。 3. **完整代码示例**: 以下代码基于引用 [^2][^4] 中的 `Customer` 类,演示如何使用匿名 `Comparator` 实现一个按 `name` 升序排序的优先队列。我添加了完整可运行的主函数,便于测试。 ```java import java.util.Comparator; import java.util.PriorityQueue; // 定义Customer类(未实现Comparable) class Customer { private int id; private String name; public Customer(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public String getName() { return name; } @Override public String toString() { return "Customer{id=" + id + ", name='" + name + "'}"; } } public class PriorityQueueAnonymousComparatorExample { public static void main(String[] args) { // 步骤1: 使用匿名Comparator实现自定义排序逻辑 // 这里定义按name升序排序(字母顺序) Comparator<Customer> nameComparator = new Comparator<Customer>() { @Override public int compare(Customer c1, Customer c2) { // 返回c1.name和c2.name的比较结果 return c1.getName().compareTo(c2.getName()); } }; // 步骤2: 创建优先队列,并传入匿名Comparator PriorityQueue<Customer> customerQueue = new PriorityQueue<>(nameComparator); // 添加一些Customer对象 customerQueue.add(new Customer(2, "Alice")); customerQueue.add(new Customer(1, "Bob")); customerQueue.add(new Customer(3, "Charlie")); // 步骤3: 遍历并输出,验证排序 System.out.println("按name升序排序的优先队列输出:"); while (!customerQueue.isEmpty()) { System.out.println(customerQueue.poll()); } } } ``` #### 代码说明: - **匿名 Comparator 部分**: 我们在 `new Comparator<Customer>() {...}` 中直接覆盖了 `compare` 方法。如果 `c1.getName()` 在字典序中小于 `c2.getName()`,`compareTo` 返回负值(代表 `c1` 优先级更高)。示例中设置为升序排序,你可以改为 `c2.getName().compareTo(c1.getName())` 实现降序排序 [^1]。 - **运行结果**: 执行代码会输出: ``` 按name升序排序的优先队列输出: Customer{id=2, name='Alice'} Customer{id=1, name='Bob'} Customer{id=3, name='Charlie'} ``` 因为队列按 `name` 排序,"Alice" 优先级最高。 - **注意点**: - 匿名 Comparator 适用于一次性比较逻辑,如引用中所述,如果复用率高,建议使用 lambda 表达式或方法引用 [^1]。 - 优先队列的默认容量是 11,但会根据元素数量动态调整堆结构 [^3]。 #### 总结 使用匿名 Comparator 实现优先队列,只需要在创建 `PriorityQueue` 时传入一个 `new Comparator<Type>() { ... }` 对象,并在其中定义比较逻辑即可。这在处理自定义对象(如 `Customer`)时特别有用,避免类需要实现 `Comparable` 接口 [^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值