To be honest, the array in question is not really sorted like this: [0, 0, 5, 6, 9, 11].
It is a "zero tailed" array: [5, 6, 9, 11, 0, 0].
So to insert a value into that array it needs to know how many elements occupied are. In case when you provide this value into a method it would have O(log n) complexity. Otherwise, it needs to implement counting inside the inserting method.
/**
* @throws ArrayIndexOutOfBoundsException when the array is full and the value to be inserted is greater than the last element
*/
private static void insertToZeroTailedArray(int val, int[] arr) {
// an O(n) operation to count occupied elements
int elementsCount = 0;
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] != 0) {
elementsCount = i + 1;
break;
}
}
// binarySearch returns a negative position to insert if the value was not found
int index = Arrays.binarySearch(arr, 0, elementsCount, val);
if (index != 0) {
int pos = index < 0
? -index - 1 // val not found, it is need to be inserted at (-index)-1 position
: index; // val found but we are going to insert it again
// shift the array to right and drop last element because of the array bounds
System.arraycopy(arr, pos, arr, pos + 1, arr.length - pos - 1);
arr[pos] = val;
} else {
// the case when value is found at 0 position
System.arraycopy(arr, 0, arr, 1, arr.length - 1);
arr[0] = val;
}
}
An alternative way to do what you need with O(log n) complexity for a really sorted array:
private static void insertToReallySortedArray(int val, int[] arr) {
int index = Arrays.binarySearch(arr, val);
if (index != 0) {
int pos = index < 0 ? -index - 1 : index;
System.arraycopy(arr, pos, arr, pos + 1, arr.length - pos - 1);
arr[pos] = val;
} else {
System.arraycopy(arr, 0, arr, 1, arr.length - 1);
arr[0] = val;
}
}
Based on this great answer.
arr[k+1]=arr[k]; arr[i]=valare executed several times (for loop). Hence the output.System.arraycopyto move the tail and make space. It's faster and clearer.System.arraycopy