Практические примеры
Применение приоритетных очередей в реальном мире
1. Система планирования задач
#include <queue>
#include <string>
#include <iostream>
struct Task {
int priority;
std::string name;
// Пользовательское сравнение для приоритетной очереди
bool operator<(const Task& other) const {
return priority < other.priority;
}
};
class TaskScheduler {
private:
std::priority_queue<Task> taskQueue;
public:
void addTask(const std::string& name, int priority) {
taskQueue.push({priority, name});
}
void executeTasks() {
while (!taskQueue.empty()) {
Task currentTask = taskQueue.top();
taskQueue.pop();
std::cout << "Executing task: "
<< currentTask.name
<< " (Priority: "
<< currentTask.priority
<< ")\n";
}
}
};
Алгоритм планирования задач
graph TD
A[Add Tasks] --> B{Priority Queue}
B --> C[Highest Priority Task]
C --> D[Execute Task]
D --> E{More Tasks?}
E -->|Yes| C
E -->|No| F[Scheduling Complete]
2. Алгоритм Дейкстры для нахождения кратчайшего пути
#include <queue>
#include <vector>
#include <utility>
class Graph {
private:
std::vector<std::vector<std::pair<int, int>>> adjacencyList;
void dijkstraShortestPath(int start) {
std::priority_queue<
std::pair<int, int>,
std::vector<std::pair<int, int>>,
std::greater<std::pair<int, int>>
> pq;
std::vector<int> distances(adjacencyList.size(), INT_MAX);
pq.push({0, start});
distances[start] = 0;
while (!pq.empty()) {
int currentVertex = pq.top().second;
int currentDistance = pq.top().first;
pq.pop();
// Обработка соседних вершин
for (auto& neighbor : adjacencyList[currentVertex]) {
int nextVertex = neighbor.first;
int edgeWeight = neighbor.second;
if (currentDistance + edgeWeight < distances[nextVertex]) {
distances[nextVertex] = currentDistance + edgeWeight;
pq.push({distances[nextVertex], nextVertex});
}
}
}
}
};
Сравнение случаев использования приоритетных очередей
Случай использования |
Основное преимущество |
Временная сложность |
Планирование задач |
Выполнение задач с наивысшим приоритетом в первую очередь |
O(log n) |
Нахождение кратчайшего пути |
Эффективный поиск минимального пути |
O((V+E)log V) |
Событийное моделирование |
Обработка событий по приоритету |
O(log n) |
3. Событийно-ориентированное моделирование
#include <queue>
#include <functional>
class EventSimulator {
private:
std::priority_queue<
std::pair<double, std::function<void()>>,
std::vector<std::pair<double, std::function<void()>>>,
std::greater<std::pair<double, std::function<void()>>>
> eventQueue;
public:
void scheduleEvent(double time, std::function<void()> event) {
eventQueue.push({time, event});
}
void runSimulation() {
while (!eventQueue.empty()) {
auto currentEvent = eventQueue.top();
eventQueue.pop();
// Выполнение события в указанное время
currentEvent.second();
}
}
};
Основные выводы для учеников LabEx
- Приоритетные очереди решают сложные задачи упорядочивания.
- Гибкая реализация в различных областях.
- Понимание компромиссов в разных случаях использования.
В LabEx мы подчеркиваем практическое применение структур данных для решения реальных проблем.