-
Notifications
You must be signed in to change notification settings - Fork 1
/
Heap3Sort.java
159 lines (143 loc) · 4.23 KB
/
Heap3Sort.java
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
157
158
159
/**
*
*/
package it.unicam.cs.asdl2122.pt1;
import java.util.List;
/**
* Classe che implementa un algoritmo di ordinamento basato su uno heap
* ternario. Usa una variante dei metodi di un MaxHeap ternario in modo da
* implementare l'algoritmo utilizzando solo un array (arraylist) e alcune
* variabili locali di appoggio (implementazione cosiddetta "in loco" o "in
* place", si veda <a href="https://it.wikipedia.org/wiki/Algoritmo_in_loco">...</a>)
*
* Uno heap ternario è uno heap in cui ogni nodo ha tre figli e non due, come in
* uno heap binario. La strategia di rappresentazione e i metodi d'inserimento
* / estrazione del minimo / heapify devono essere adattati al caso di tre
* figli, ma algoritmica-mente sono analoghi.
*
* Lo heap ternario deve essere pensato in modo che accetti elementi ripetuti e
* non accetti elementi null.
*
* @author Luca Tesei (Template)
*
*/
public class Heap3Sort<E extends Comparable<E>> implements SortingAlgorithm<E> {
private int dim;
private int count;
@Override
public SortingAlgorithmResult<E> sort(List<E> l) {
dim = l.size();
this.buildMaxHeap(l);
//mette la radice come ultimo elemento dell' array e corregge
//di nuovo i valori del maxHeap
for(dim=l.size()-1;dim>=0;dim--){
swap(l, 0, dim);
heapify(l,0);
}
return new SortingAlgorithmResult<>(l, count);
}
/**
* Corregge i valori scambiandoli di posizione per tornare ad avere un maxheap.
*
* @param l
* array da ordinare.
*
* @param i
* root di un nodo.
*/
private void heapify(List<E> l, int i) {
int max = i;
if(this.getFirstChildNode(i) < dim && l.get(this.getFirstChildNode(i)).compareTo(l.get(max)) >= 0)
{
max = this.getFirstChildNode(i);
}
if(this.getSecondChildNode(i) < dim && l.get(this.getSecondChildNode(i)).compareTo(l.get(max)) >= 0)
{
max = this.getSecondChildNode(i);
}
if(this.getThirdChildNode(i) < dim && l.get(this.getThirdChildNode(i)).compareTo(l.get(max)) >= 0)
{
max = this.getThirdChildNode(i);
}
if(max != i)
{
swap(l, i, max);
heapify(l, max);
count++;
}
}
@Override
public String getName() {
return "Heap3Sort";
}
/*
* L'indice del primo, secondo e terzo di un nodo in posizione i. Si noti
* che la posizione 0 è significativa e contiene sempre la radice dello
* heap.
*/
/**
* Restituisce il primo figlio
*
* @param pos
* posizione del elemento padre.
*
* @return ritorna la posizione del figlio.
*/
private int getFirstChildNode(int pos)
{
return (3*pos) + 1;
}
/**
* Restituisce il secondo figlio
*
* @param pos
* posizione del elemento padre.
*
* @return ritorna la posizione del figlio.
*/
private int getSecondChildNode(int pos)
{
return ((3*pos) + 1)+1;
}
/**
* Restituisce il terzo figlio
*
* @param pos
* posizione del elemento padre.
*
* @return ritorna la posizione del figlio.
*/
private int getThirdChildNode(int pos)
{
return ((3*pos) + 1)+2;
}
/**
* Scambia gli elementi tramite le posizioni date
*
* @param l
* lista di elementi su cui effettuare lo scambio.
*
* @param i
* posizione del primo elemento da scambiare.
*
* @param j
* posizione del secondo elemento da scambiare.
*/
private void swap(List<E> l, int i, int j)
{
E element = l.get(i); //posizione i-esima
l.set(i, l.get(j)); //sostituisce elemento gli elementi
l.set(j, element); //esegue il set dell'elemento di appoggio
}
/**
* Mette gli elementi in ordine in modo che ci sia un maxHeap di partenza.
*
* @param l
* array da ordinare.
*/
private void buildMaxHeap(List<E> l)
{
for (int i = l.size() / 3; i >= 0; i--)
heapify(l, i);
}
}