import
java.util.ArrayList;
import
java.util.Collections;
import
java.util.List;
public
class
GrailSort {
public
static
List<Integer> grailSort(List<Integer> arr)
{
int
blockSize = (
int
)Math.sqrt(arr.size());
int
numBlocks
= (arr.size() + blockSize -
1
) / blockSize;
List<List<Integer> > blocks =
new
ArrayList<>(
numBlocks);
for
(
int
i =
0
; i < numBlocks; i++) {
blocks.add(
new
ArrayList<>(Collections.nCopies(
blockSize,
0
)));
Collections.copy(
blocks.get(i),
arr.subList(i * blockSize,
Math.min((i +
1
) * blockSize,
arr.size())));
for
(
int
j =
1
; j < blockSize; j++) {
int
key = blocks.get(i).get(j);
int
k = j -
1
;
while
(k >=
0
&& blocks.get(i).get(k) > key) {
blocks.get(i).set(k +
1
,
blocks.get(i).get(k));
k--;
}
blocks.get(i).set(k +
1
, key);
}
}
List<Integer> pointers
=
new
ArrayList<>(Collections.nCopies(
numBlocks,
0
));
List<Integer> result
=
new
ArrayList<>();
while
(
true
) {
int
minVal
= Integer.MAX_VALUE;
int
minIdx = -
1
;
for
(
int
i =
0
; i < numBlocks; i++) {
if
(pointers.get(i)
< blocks.get(i)
.size()
&& blocks.get(i).get(pointers.get(i))
< minVal) {
minVal = blocks.get(i).get(
pointers.get(i));
minIdx = i;
}
}
if
(minIdx == -
1
) {
break
;
}
result.add(minVal);
pointers.set(minIdx, pointers.get(minIdx) +
1
);
}
return
result;
}
public
static
void
main(String[] args)
{
List<Integer> arr = List.of(
7
,
7
,
4
,
1
,
5
,
3
,
2
,
0
);
System.out.print(
"Input : "
);
for
(
int
x : arr) {
System.out.print(x +
" "
);
}
System.out.println();
List<Integer> result = grailSort(arr);
System.out.print(
"Output: "
);
for
(
int
x : result)
System.out.print(x +
" "
);
}
}