一、问题概述
优先级队列的定义:
优先级队列不同于普通的队列,普通的队列具有先进先出的原则,而优先级队列是选择优先级最高的先出队。那么,如何模拟实现优先级队列呢?在这里,我们将较大的值作为优先级较高的。
二、解决思路
(1)用插入排序的思想,将它们按由大到小(也可由小到大)排好序,再push到队列中,那么队列中的队首元素便是优先级最高的,取其front,便可得到优先级最高的值。
此时,push的时间复杂度为(O(1)),pop的时间复杂度为(O(N)),Top的时间复杂度为(O(1)).
(2)用选择排序的思想,选择出值最大的那个元素,将其push到队列中,再取次大的,push到队列中,依次下去,将所有值push到队列中,那么队列中的队首元素便是优先级最高的,取其front,便可得到优先级最高的值。
此时,push的时间复杂度为(O(N)),pop的时间复杂度为(O(1)),Top的时间复杂度为(O(N)).
那么,根据时间复杂度来看,两种算法哪一个更好呢?
解析一下:(如果不考虑取Top(),比较插入排序和选择排序)
插入排序:push时间复杂度为(O(1)),pop时如果无序的话,它是O(N),但是如果本身是有序的话,pop的时间复杂度就为(O(1)),它是可变的,分最好最坏;
但是选择排序就不一样了,它的push的复杂度永远都为(O(N)),pop的时间复杂度为(O(1));
综上所述,插入排序的思想实现优先级队列更好。
下面把两种优先级队列都实现一下吧~~
三、实现代码
//插入排序实现优先级队列
#pragma once
#include<iostream>
using namespace std;
#include<queue>
#include<assert.h>template<typename T>
T QueuePriority(T *arr1,size_t size)
{assert(arr1);queue<T> q;T arr2[7] = {0};arr2[0] = arr1[0];for(size_t i = 1; i < size; ++i){if(arr2[i-1] <= arr1[i]){arr2[i] = arr1[i];}else{size_t j = 0;for(j = i-1; j >= 0; --j){if(arr2[j] > arr1[i]){arr2[j+1] = arr2[j];}else{break;}}arr2[j+1] = arr1[i];}}for(int k = size-1; k >= 0; k--){q.push(arr2[k]);}return q.front();
}void FunTest()
{int arr1[] = {1,3,5,4,2,6,0};char arr2[] = {'a','d','b','c'};size_t size = sizeof(arr1)/sizeof(arr1[0]);size_t size1 = sizeof(arr2)/sizeof(arr2[0]);cout<<QueuePriority<int>(arr1,size)<<endl;cout<<QueuePriority<char>(arr2,size1)<<endl;
}int main()
{FunTest();return 0;
}
//用选择排序实现优先级队列
#pragma once
#include<iostream>
using namespace std;
#include<queue>
#include<assert.h>template<typename T>
T QueuePriority(T *arr1,size_t size)
{assert(arr1);queue<T> q;for(size_t i = 0; i < size; ++i){T max = i; for(size_t j = i+1;j < size; ++j){if(arr1[max] < arr1[j]){max = j;}}swap(arr1[max],arr1[i]);q.push(arr1[i]);}return q.front();
}void FunTest()
{int arr1[] = {1,3,5,4,2,6,0};char arr2[] = {'a','d','b','c'};size_t size = sizeof(arr1)/sizeof(arr1[0]);size_t size1 = sizeof(arr2)/sizeof(arr2[0]);cout<<QueuePriority<int>(arr1,size)<<endl;cout<<QueuePriority<char>(arr2,size1)<<endl;
}int main()
{FunTest();return 0;
}