Как реализовать приоритет очереди, используя двоичную кучу с тай-брейкером?
Я должен реализовать приоритетную очередь, используя двоичную кучу в C для университетского назначения. Программа должна получить n значений из ввода, когда значение равно 0, она должна напечатать идентификационный номер (таким образом, если задача, которая была добавлена как 5-й элемент, имеет наивысший приоритет 7, вывести "5") и удалить задачу с наивысшим приоритетом из очереди, а при значении>0 следует добавить новый узел. Для реализации идентификаторов и приоритетов я использовал массивы структур.
Задача была бы довольно простой, если бы не тот факт, что она должна также печатать более низкие идентификаторы, если приоритет элементов одинаков... Я провел исследование, но единственный совет, который мне удалось найти, - это изменить фрагменты типичных функций кучи (insertkey, heapify) для поиска идентификатора элемента. Я пытался сделать это, но я понятия не имею, что пошло не так - элементы все еще не отсортированы так, как я хочу, чтобы они были. Буду благодарен за любые советы и подсказки!
Код:
#include <stdio.h>
#define SIZE 99999
int heapsize = 0;
int count = 0;
struct pqueue
{
int priority;
int id;
};
struct pqueue A[SIZE];
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void initializearray()
{
for(int i=0; i<SIZE; i++)
{
A[i].priority = 0;
A[i].id = 0;
}
}
void printheap(); //prototype of debugging function
int left(int i)
{
return (i * 2) + 1;
}
int right(int i)
{
return (i * 2) + 2;
}
int parent(int i)
{
return ((i - 1) / 2);
}
void insertkey(int z)
{
heapsize++;
int i = heapsize - 1;
A[i].priority = z;
count++;
A[i].id = count;
while (i != 0 && A[parent(i)].priority < A[i].priority)
{
swap(&A[i].priority, &A[parent(i)].priority);
swap(&A[i].id, &A[parent(i)].id);
i = parent(i);
}
i = heapsize-1;
while(i != 0 && A[parent(i)].priority == A[i].priority && A[parent(i)].id > A[i].id )
{
swap(&A[i].priority, &A[parent(i)].priority);
swap(&A[i].id, &A[parent(i)].id);
i = parent(i);
}
// printheap();
}
void maxheapify(int i)
{
int l = left(i);
int r = right(i);
int largest;
if (l <= heapsize && A[l].priority >= A[i].priority)
{
largest = l;
if(A[l].priority == A[i].priority)
{
if(A[l].id < A[i].id)
{
largest = l;
}
else
{
largest = i;
}
}
}
else
{
largest = i;
}
if (r <= heapsize && A[r].priority >= A[largest].priority)
{
largest = r;
if(A[r].priority == A[largest].priority)
{
if(A[r].id < A[largest].id)
{
largest = r;
}
}
}
if (largest != i)
{
swap(&A[i].priority, &A[largest].priority);
swap(&A[i].id, &A[largest].id);
maxheapify(largest);
}
}
int extractmax()
{
int max = A[0].id;
A[0].priority = A[heapsize-1].priority;
A[0].id = A[heapsize-1].id;
heapsize--;
//printheap();
maxheapify(0);
return max;
}
void printheap() // debug function
{
for(int i = 0; i < heapsize; i++)
{
printf("prio %d id %d \n", A[i].priority, A[i].id);
}
}
int main()
{
int n;
int z;
initializearray();
scanf("%d", &n);
for(int i=0; i<n; i++)
{
scanf("%d", &z);
if(z != 0)
{
insertkey(z);
}
else
{
int local = extractmax();
if(local != 0 && heapsize+1 != 0)
{
printf("%d\n", local);
// printheap();
}
}
}
return 0;
}
Пример ввода:
7
3 0 0 2 8 8 0
Выход:
1
3
Пример ввода (здесь возникает проблема:)
10
1 1 1 1 2 0 0 0 0 0
Выход:
5
3
2
4
1
Ожидаемый результат:
5
1
2
3
4
Спасибо за ваше время!
1 ответ
Вместо того, чтобы включать логику непосредственно в реализацию кучи, напишите функцию сравнения, которая рассматривает идентификатор, если приоритеты совпадают:
int pqless(const struct pqueue *a, const struct pqueue *b)
{
if (a->priority < b->priority) return 1;
if (a->priority > b->priority) return 0;
return (a->id > b->id);
}
Эта функция возвращает true, если a
приоритет меньше b
"S. Если оба приоритета равны, он возвращает истину, если a
Идентификатор меньше, чем b
"S.
Теперь обновите свой код кучи. Где бы вы ни сравнивали приоритеты в исходном коде, теперь просто вызовите функцию:
void insertkey(int z)
{
int i = heapsize++;
A[i].priority = z;
A[i].id = ++count;
while (i != 0 && pqless(&A[parent(i)], &A[i])) {
swap(&A[i].priority, &A[parent(i)].priority);
swap(&A[i].id, &A[parent(i)].id);
i = parent(i);
}
}
void maxheapify(int i)
{
int l = left(i);
int r = right(i);
int largest = i;
if (l <= heapsize && !pqless(&A[l], &A[i])) largest = l;
if (r <= heapsize && !pqless(&A[r], &A[largest]))largest = r;
if (largest != i) {
swap(&A[i].priority, &A[largest].priority);
swap(&A[i].id, &A[largest].id);
maxheapify(largest);
}
}