C++优先队列用法

开发工具

  Priority Queue

  优先队列和一般的队列(queue)不同之处在于,优先队列里的元素具有权值,在出队列时总是权值最大的元素出列,本质是一个heap。

  C++ Define

  template <class Type, class Container= vector <Type>, class Compare= less <typename Container ::value_type>>

  class priority_queue

  Parameters

  常用的Member Functions

  Requirements

  #include<queue>using namespace std;Simple Test

  empty() and push()

  #include<queue>

  #include<iostream>

  using namespace std;

  int main(){

  priority_queue <int> q;

  if(q.empty())

  cout << "the priority_queue is empty." << l;

  q.push(20);

  if(!q.empty())

  cout << "the priority_queue is not empty." << l;

  return 0;

  }

  the priority_queue is empty.

  the priority_queue is not empty.

  size()

  #include<queue>

  #include<iostream>

  using namespace std;

  int main(){

  priority_queue <int> q;

  cout << "q.size is " << q.size() <<l;

  q.push(20);

  q.push(30);

  cout << "q.size is " << q.size() <<l;

  return 0;

  }

  q.size is 0

  q.size is 2

  pop() and top()

  #include<queue>

  #include<iostream>

  using namespace std;

  int main(){

  priority_queue <int> q;

  q.push(20);

  q.push(30);

  q.push(19);

  cout << "q.size is " << q.size() << l;

  cout << "Queue q's current top is " << q.top() << l;

  q.pop();

  cout << "Queue q pops the top element." << l;

  cout << "Queue q's current top is " << q.top() << l;

  cout << "q.size is " << q.size() << l;

  return 0;

  }

  q.size is 3

  Queue q's current top is 30

  Queue q pops the top element.

  Queue q's current top is 20

  q.size is 2

  Advanced

  元素排序

  默认情况下,优先队列内部是一个大根堆,元素从大到小从队首排至队尾。

  #include<queue>

  #include<iostream>

  using namespace std;

  int main(){

  priority_queue <int> q; //相当于 priority_queue < int, vector<int>, less<int> > q;

  q.push(20);

  q.push(30);

  q.push(7);

  q.push(5);

  q.push(12);

  q.push(0);

  q.push(32);

  cout << "output order is :";

  while( !q.empty() ){

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

  q.pop();

  }

  return 0;

  }

  output order is :32 30 20 12 7 5 0

  可以将队列声明参数Compare对应的less改成greater,此时内部大根堆变成小根堆,元素从小到大排列

  output order is :0 5 7 12 20 30 32

  运算符重载

  在实际使用中,我们往往需要对结构体数组/类按照某一个成员的值进行排序,比如想对学生所有科目中的语文成绩进行排序,那么就需要重载比较操作符函数,即参数Compare所指向的函数。

  compare可以选择greater或者less,C++ 11定义两者分别为:

  less

  template <class T> struct less {

  bool operator() (const T& x, const T& y) const {return x < y;}

  typedef T first_argument_type;

  typedef T second_argument_type;

  typedef bool result_type;

  };

  greater

  template <class T> struct greater {

  bool operator() (const T& x, const T& y) const {return x > y;}

  typedef T first_argument_type;

  typedef T second_argument_type;

  typedef bool result_type;

  };

  一般而言,排序时greater对应从大到小顺序,less对应从小到大顺序。但是在优先级队列里,less对应的是从大到小出队列,greater对应从小到大出队列,在前面示例的简单元素排序中可以看到刚好相反,这么实现的具体原因暂不探究。

  在自定义结构体优先级时,可以使用以下两种方式:

  //方式一:以成员函数的形式

  #include<queue>

  #include<iostream>

  using namespace std;

  struct Student{

  //简单起见,只定义两个成绩变量

  int num;

  int math;

  Student(int n, int m){

  num = n;

  math = m;

  }

  bool operator< (const Student &s) const { //这里const不能漏,会报错(codeblocks)

  return math > s.math;

  }

  };

  int main(){

  priority_queue < Student, vector<Student>, less<Student> > q;

  q.push(Student(7,80));

  q.push(Student(6,30));

  q.push(Student(3,45));

  q.push(Student(2,100));

  q.push(Student(5,76));

  q.push(Student(10,34));

  cout << "数学成绩排序为:" ;

  while( !q.empty() ){

  cout<< q.top().math << " ";

  q.pop();

  }

  return 0;

  }

  //方式二:以结构体形式

  #include<queue>

  #include<iostream>

  using namespace std;

  struct Student{

  //简单起见,只定义两个成绩变量

  int num;

  int math;

  Student(int n, int m){

  num = n;

  math = m;

  }

  };

  struct cmp{

  bool operator ()(const Student s1, const Student s2){

  return s1.math < s2.math;

  }

  };

  int main(){

  priority_queue < Student, vector<Student>, cmp > q; //这里要用结构体cmp替换原来的less/greater

  q.push(Student(7,80));

  q.push(Student(6,30));

  q.push(Student(3,45));

  q.push(Student(2,100));

  q.push(Student(5,76));

  q.push(Student(10,34));

  cout << "数学成绩排序为:" ;

  while( !q.empty() ){

  cout<< q.top().math << " ";

  q.pop();

  }

  return 0;

  }

  输出结果均为:

  数学成绩排序为:100 80 76 45 34 30

  注意

  针对方式一,如果在声明中compare选择greater,则在结构体中重载函数名必须对应为operator >,即重载运算符>;同理,less对应operator <,即重载运算符<, 即:

  //greater ----- operator>

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

  bool operator> (const Student &s) const {}

  //less ----- operator<

  priority_queue < Student, vector<Student>, less<Student> > q;

  bool operator< (const Student &s) const {}

  针对方式二,重载运算符必须是(), 即:

  bool operator ()(const Student s1, const Student s2) {}

  否则会报错。

  但是,最终排序结果只与return语句中的运算符有关,即:

  //如果你想让元素从大到小出列,则return中运算符应为'<'

  return math < s.math;

   //如果你想让元素从小到大出列,则return中运算符应为'>' r

  eturn math > s.math

  山东掌趣网络科技

标签: 开发工具