-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap.c
156 lines (127 loc) · 4.38 KB
/
heap.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include "heap.h"
/*
Função: buildHeap
- Responsável por transformar a área de memória na estrutura de dados "heap".
Parâmetros:
- RAM: Área de memória disponível para o método de ordenação
- size: Tamanho da área de memória
Retorno:
- Nenhum
*/
void buildHeap(tRAM *RAM, int size, long *compCounter)
{
int i, idxLargest, idxParent, idxTarget, idxLChild, idxRChild, swaps;
tStudent aux;
for (i = 0; i < size / 2;)
{
/*Índice do filho à esquerda*/
idxLChild = 2 * i + 1;
/*Índice do filho à direita*/
idxRChild = 2 * i + 2;
swaps = 0;
if (idxLChild >= 0 && idxLChild < size &&
idxRChild >= 0 && idxRChild < size)
{
/*Índices de ambos os filhos fazem parte do vetor*/
if (RAM->student[idxLChild].grade < RAM->student[idxRChild].grade)
/*Filho à esquerda é menor que filho à direita*/
idxLargest = idxRChild;
else
/*Filho à direita é menor que filho à esquerda*/
idxLargest = idxLChild;
(*compCounter)++;
}
else
/*Índice do filho à direito está além dos limites do vetor
(utiliza índice do filho à esquerda)*/
idxLargest = idxLChild;
if (RAM->student[i].grade < RAM->student[idxLargest].grade)
{
/*Troca pai com seu maior filho*/
aux = RAM->student[i];
RAM->student[i] = RAM->student[idxLargest];
RAM->student[idxLargest] = aux;
/*Verifica a necessidade de realizar trocas no sentido oposto
(caso a propriedade do "heap" tenha sido violada após a troca)*/
idxTarget = i;
idxParent = (idxTarget - 1) / 2;
(*compCounter)++;
while (RAM->student[idxTarget].grade > RAM->student[idxParent].grade)
{
/*Pai é menor que filho - continua troca*/
aux = RAM->student[idxTarget];
RAM->student[idxTarget] = RAM->student[idxParent];
RAM->student[idxParent] = aux;
/*Atualiza índices utilizados nas comparações*/
idxTarget = idxParent;
idxParent = (idxTarget - 1) / 2;
/*Controla o incremento da variável de laço "i"*/
swaps++;
(*compCounter)++;
}
}
if (swaps == 0)
/*Variável "i" não deve ser incrementada caso valor de RAM->student[i]
tenha sido alterado. Isso é necessário para que a propriedade do "heap"
seja mantida.*/
i++;
}
}
/*
Função: rebuildHeap
- Responsável por reconstruir a estrutura de dados "heap".
Parâmetros:
- RAM: Área de memória disponível para o método de ordenação
- size: Tamanho da área de memória
Retorno:
- Nenhum
*/
void rebuildHeap(tRAM *RAM, int size, long *compCounter)
{
int idxNewRoot, idxMinor, idxLChild, idxRChild;
tStudent aux;
idxNewRoot = 0;
while (2 * idxNewRoot + 1 < size)
{
idxLChild = 2 * idxNewRoot + 1;
idxRChild = 2 * idxNewRoot + 2;
if (idxLChild >= 0 && idxLChild < size &&
idxRChild >= 0 && idxRChild < size)
{
//children's indexes are inside array
if (RAM->student[idxLChild].priority > RAM->student[idxRChild].priority)
//right child's priority is less than left child's priority
idxMinor = idxRChild;
else if (RAM->student[idxLChild].priority < RAM->student[idxRChild].priority)
//left child's priority is less than right child's priority
idxMinor = idxLChild;
else if (RAM->student[idxLChild].grade < RAM->student[idxRChild].grade)
//prioridades iguais (guarda o índice do estudante com a menor nota)
idxMinor = idxRChild;
else
//prioridades iguais (guarda o índice do estudante com a menor nota)
idxMinor = idxLChild;
(*compCounter)++;
}
else
//right child index is beyond array's bounds
idxMinor = idxLChild;
(*compCounter)++;
//compares with parent (idxNewRoot)
if (RAM->student[idxMinor].grade < RAM->student[idxNewRoot].grade &&
RAM->student[idxNewRoot].priority == 0)
break;
(*compCounter)++;
if (RAM->student[idxMinor].priority < RAM->student[idxNewRoot].priority ||
(RAM->student[idxMinor].grade > RAM->student[idxNewRoot].grade &&
RAM->student[idxMinor].priority == RAM->student[idxNewRoot].priority))
{
aux = RAM->student[idxNewRoot];
RAM->student[idxNewRoot] = RAM->student[idxMinor];
RAM->student[idxMinor] = aux;
idxNewRoot = idxMinor;
}
else
idxNewRoot++;
}
}