import java.util.ArrayList;
import java.util.Collection;
public class MaxHeap
{
private ArrayList<Student> students;
public MaxHeap(int capacity)
{
students = new ArrayList<Student>(capacity);
}
public MaxHeap(Collection<Student> collection)
{
students = new ArrayList<Student>(collection);
for(int i = size()/2; i >= 0; i--)
{
maxHeapify(i);
}
}
public Student getMax()
{
if(size() < 1)
{
throw new IndexOutOfBoundsException("No maximum value: the heap is empty.");
}
return students.get(0);
}
public Student extractMax()
{
Student value = getMax();
students.set(0,students.get(size()-1));
students.remove(size()-1);
maxHeapify(0);
return value;
}
public void insert(Student elt)
{
private int lastOne;
if (lastOne == students.length)
throw new heapException("heap is full");
else {
// I'm stuck here
}
}
As I understand, I Insert the element at last. Then compare it with its parent.
If parent is greater than this latest insertion, return the element.
Else swap parent and this child
private int parent(int index)
{
return (index - 1)/2;
}
private int left(int index)
{
return 2 * index + 1;
}
private int right(int index)
{
return 2 * index + 2;
}
private int size()
{
return students.size();
}
private void swap(int from, int to)
{
Student val = students.get(from);
students.set(from, students.get(to));
students.set(to, val);
}
private void maxHeapify(int index)
{
int left = left(index);
int right = right(index);
int largest = index;
if (left < size() && students.get(left).compareTo(students.get(largest)) > 0)
{
largest = left;
}
if (right < size() && students.get(right).compareTo(students.get(largest)) > 0)
{
largest = right;
}
if (largest != index)
{
swap(index, largest);
maxHeapify(largest);
}
}
}
Thank you everybody, now i can make a children and parent node, but How can add insert method ? I think about while or if statement. But cannot fingure out...
Think about what a heap is ... a COMPLETE tree.
0
1 2
3 4
So the children of index 0 are index 1 and 2, the children of index 1 are 3 and 4, the children of index 2 are 5 and 6. See a pattern?
EDIT: also you should use generics for a heap, that is the reason why you are supposed to use an ArrayList in java and not a standard array. A generic heap will allow an argument to be past to determine the type so the structure is more flexible.
In a 0-based binary heap, given a node at index i:
The left child is at index (i * 2) + 1
The right child is at index (i * 2) + 2
The parent is at index (i - 1)/2
To insert, you add the item as the last item in the array, and then you move it up the heap, continually comparing with the parent. Like this:
public void insert(Student elt)
{
students.add(elt);
int i = students.size()-1;
while (i > 0)
{
int p = parent(i);
if (students[i] >= students[p])
{
// item is not smaller than parent, so we're done
break;
}
// swap child and parent items
swap(p, i);
// and then move up one level
i = p;
}
}
Related
I'm trying to implement a Max-heap with with two methods insert and extract_max.
But the extract_max is currently not working correctly as it's not extracting the largest integer in the Heap, which i assume is because of heapify. I've been trying to debug for hours but can't figure out where it goes wrong. Any input would be highly appreciated.
class Heap {
int heap_array[];
int n_elems = 0;
int capacity;
// Constructor
Heap(int _capacity) {
capacity = _capacity;
heap_array = new int[capacity];
}
/**
* Private method for maintaining the heap.
* #param i, index of the element to heapify from
**/
private void heapify(int i) {
int left = 2*i + 1;
int right = 2*i+ 2;
int largest = i;
//if left ≤ heap_length[A] and A[left] > A[largest] then:
if (left <= n_elems && heap_array[left] > heap_array[largest]) {
largest = left;
//System.out.println("largest = left");
}
//if right ≤ heap_length[A] and A[right] > A[largest] then:
if (right <= n_elems && heap_array[right] > heap_array[largest]) {
//System.out.println("largest = right");
largest = right;
}
//if largest ≠ i then:
if (largest != i) {
int swap = heap_array[i];
heap_array[i] = heap_array[largest];
heap_array[largest] = swap;
// Recursively heapify the affected sub-tree
heapify(largest);
}
}
/**
* Add an element to the heap and ensure the heap property
* Throws an exception if trying to add elements to a full heap.
* #param x Element to add
*/
public void insert(int x) throws Exception {
if(is_full()) {
throw new Exception("The heap is full");
} else {
// Insert the element at end of Heap
heap_array[n_elems++] = x;
//n_elems++;
// Heapify from root
heapify(0);
}
}
public int extract_max() throws Exception {
//Get the largest
// Get the last element
int root = heap_array[0];
int lastElement = heap_array[n_elems];
// Replace root with first element
heap_array[0] = lastElement;
// Decrease size of heap by 1
n_elems--;
// heapify the root node
heapify(0);
// return new size of Heap
return root;
}
public int capacity() {
return capacity;
}
public int size() {
return n_elems;
}
public boolean is_empty() {
return n_elems == 0;
}
public boolean is_full() {
return n_elems == capacity;
}
public void print() {
for(int i = 0; i < n_elems; i++) {
System.out.println(heap_array[i]);
}
}
/**
* Remove and return largest element, and maintain the heap property.
* Throws an exception if trying to extract an element from an empty heap.
*/
/**
* For convenience, a small program to test the code.
* There are better ways of doing this kind of testing!
* #throws Exception
*
*/
static public void main(String args[]) throws Exception { // A simple test program
// Declare two heaps. Both should work nicely!
Heap h1 = new Heap(100);
Heap h2 = new Heap(10);
int data[] = {1, 4, 10, 14, 7, 9, 3, 8, 16};
//
// Insert 1 element to heap 1, and several to heap 2.
//
h2.insert(9);
h2.insert(10);
h2.insert(8);
h2.insert(11);
h2.insert(12);
h2.insert(15);
System.out.println("Size " + h2.size());
h2.print();
System.out.println("Max " + h2.extract_max());
}
}
The first problem is that your insert isn't correct. Just adding to the end and calling heapify(0) doesn't do you any good. heapify is going to examine the root element and its two children, decide that the root is the largest item, and exit, doing nothing. As a result, you're just adding things to the list sequentially.
To insert into a max-heap, you do the following:
Add the new item to the end of the heap.
Move the item up the heap to its proper position.
So insert should look like this:
public void insert(int x) throws Exception {
if(is_full()) {
throw new Exception("The heap is full");
}
// Insert the element at end of Heap
heap_array[n_elems++] = x;
// now sift it up
int current = nelems-1;
int parent = (current-1)/2;
while (current > 0 && heap_array[current] > heap_array[parent]) {
int swap = heap_array[parent];
heap_array[parent] = heap_array[current];
heap_array[current] = swap;
current = parent;
parent = (current-1)/2;
}
}
I think you also have a problem in extract_max. You have:
int lastElement = heap_array[n_elems];
But the last element is actually at index n_elems-1]. I think you want:
int lastElement = heap_array[n_elems-1];
That makes sense because if n_elems == 1, then the only item in the heap will be the root, at heap_array[0];
I was wondering if it is possible to find the closest lower element in a non-empty sorted array for an element that may be there or may not be there. Elements can be repeated also any number of times. All elements of the array +ve.
For example, if we had the values [2,5,6,7,7,8,9] and we are looking for the element closest lower to 6, it should return 5, because 5 is the biggest number in the array, that is smaller than 6.
Similarly, if we're looking for the element closest lower to 9, it should return 8, because 8 is the biggest number in the array, that is smaller than 9.
And if the closest lower element is not found, return -1 like if we're looking for the element closest lower to 1, it should return -1, because there is no such element which can be lower than 1. Here -1 represents that there's no such value is present in the array which is closest lower to the element
I have tried this below code. Is it all right? If I'm missing something, please help me. Java code will be more helpful.
static int find(int[] a, int target)
{
int n = a.length;
if(target <= a[0])
return -1;
if(target > a[n-1])
return a[n-1];
int i=0,j=n,mid=0;
while(i<j)
{
mid = (i+j)/2;
if(target <= a[mid])
{
if( mid >0 & target> a[mid-1] )
{
return a[mid-1];
}
j= mid;
}
else
{
if( mid<(n-1) & target > a[mid+1] )
{
return a[mid+1];
}
i= mid+1;
}
}
return mid;
}
Using streams:
import java.util.stream.IntStream;
public class FindNearestLowestValue {
public final static void main(String[] args) {
int[] array = {2,5,6,7,7,8,9};
int searchVal = 6;
// reverse the order so the first element of the filtered stream is the result
System.out.println(
IntStream.range(0, array.length)
.map(i -> array[array.length - 1 - i])
.filter(n -> n < searchVal)
.findFirst().orElse(-1)
);
}
}
There exists a standard binarySearch function.
static int find(int[] a, int target) {
int position = Arrays.binarySearch(a, target);
if (position >= 0) {
System.out.println("Found at index " + position);
} else {
int insertIndex = ~position;
System.out.println("Insert position at index " + insertIndex);
position = insertIndex;
}
return position;
}
When not found it delives the ones-complement of the insert position, as shown above. This means when the result is negative, the item is not found.
It does more or less what you did, but on not finding, it cleverly return a negative: ~ insert position (or -insert position - 1).
/**
* Search the next smaller array element.
* #param a the array sorted in ascending order.
* #param target the value to keep below.
* #return the greatest smaller element, or -1.
*/
static int findNextSmaller(int[] a, int target) {
int i= Arrays.binarySearch(a, target);
if (i >= 0) {
--i;
while (i>= 0 && a[i] == target) {
--i;
}
} else {
i = ~i;
--i;
}
return i == -1 ? -1 : a[i];
}
Or, as int is discrete:
static int findNextSmaller(int[] a, int target) {
int i= Arrays.binarySearch(a, target - 1);
if (i >= 0) {
return target - 1;
}
i = ~i;
--i;
return i == -1 ? -1 : a[i];
}
I am working on a project in which I have to sort an array of Integer objects by using Comparable.
My add method takes an item of type E. If my size variable (which tracks the elements in my array theData[]) is = 0 (which it is initialized to), I simply put the item in theData[0].
If it is not, I use item.compareTo to compare the item against each item already in the array. If the result of compareTo is < 0 for a number in the array, I shift everything at that number and after to the right, and insert the item before it.
If compareTo returns a 0, meaning the item is equal to the number in the array, I do nothing as I don't want duplicates in the array.
If none of the compareTo statements in the loop return a -1 or a 0, I put the item in theData[size], the end of the array, as it must be larger than all the other numbers.
However, this doesn't work. Any time I make a new Set and add a few numbers to it, then try to print out the contents of my set using a for loop,I keep getting a java.lang.ArrayIndexOutOfBoundsException: 10 error for this line:
theData[j + 1] = theData[j];
I've tried starting from scratch and re-writing my loop with different logic, and each time I keep hitting this wall. I know I must either be shifting incorrectly or not increasing the size of the array correctly with my reallocate method, but I can't wrap my head around it.
import java.util.*;
public class Set<E extends Comparable<E>> {
String s;
String name;
private static final int INITIAL_CAPACITY = 10;
private E[] theData;
private int size = 0;
private int capacity = INITIAL_CAPACITY;
#SuppressWarnings("unchecked")
public Set() {
theData = (E[]) new Comparable[capacity];
}
public Set(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void add(E item) {
if (size == capacity) {
reallocate();
}
if (size == 0) { // If size is 0, add item to theData[0]
theData[size] = item;
size++;
return;
}
else { // Else compare the item to every item in loop.
for (int i = 0; i < size; i++) {
int result = item.compareTo(theData[i]);
if (result < 0) {
for (int j = 0; j < size; j++) { //If item is less than a number, shift everything
theData[j + 1] = theData[j]; //after that index to the right, and add item
theData[j] = item;
}
}
if (result == 0) {
return;
}
else { //If item is not less than or equal to any
theData[size] = item; //numbers in the array, add it to the end
size++;
}
}
}
}
/*
* if (size>=1){ int result = item.compareTo(theData[size-1]); if(result<0){
* E temp = theData[size-1]; theData[size-1] = item; theData[size] = temp; }
* if(result>1){ return; } }
*/
public E get(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException(index);
}
return theData[index];
}
public int size() {
return size;
}
private void reallocate() {
capacity = 2 * capacity;
theData = Arrays.copyOf(theData, capacity);
}
}
Edit: The driver method I'm using to test it -
public class Driver {
String one = "two";
public static void main(String[] args){
Set<Integer> one = new Set<Integer>();
one.add(63);
one.add(20);
one.add(127);
one.add(10);
one.add(26);
one.add(15);
for(int i = 0; i < one.size(); i++){
System.out.println(one.get(i));
}
}
}
When j == size - 1, theData[j+1] will take you out of the array.
You want to loop to one before the end instead.
for (int j = 0; j < size - 1; j++) { //If item is less than a number, shift everything
theData[j + 1] = theData[j]; //after that index to the right, and add item
theData[j] = item;
}
So I've also taken a look at the logic you've got for the insertion, and it doesn't make a lick of sense. Why do you delay the insertion at all? If you've got the room, just add it!
Next, the double loops are essentially implementing bubble sort, but there's a fatal flaw with it: you don't ever complete the swap; you only overwrite your values repeatedly. You're also not comparing in the right direction; you want to swap if the value on the left is larger than the value on the right, since you're starting from the beginning of the array.
So, with that...this is what an implementation would have the form of...
public void add(E item) {
if (size == capacity) {
reallocate();
}
theData[size++] = item;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - 1; j++) {
if (theData[j].compareTo(theData[j + 1]) > 0) {
// perform the swap (you need an extra variable!
}
}
}
}
I leave implementing the swap as an exercise for the reader.
First, in your shift loop, you are inserting the new item in every position instead of shifting then inserting in [i] because you copy theData[j] to the next position, but always assign item to theData[j], is that right?
Second, you are starting from the beginning of array since j starts with 0. J should start with i.
Third and main bug, you verify if result < 0 then you verify IF result == 0, change for a ELSE IF so the else don't get executed even when result < 0
shift elements to right can be done from right to left, like:
for (int j = size; j > i; j--) { // If item is less than a
// number, shift
// everything
theData[j] = theData[j - 1]; // after that index to the
// right, and add item
}
size++;
theData[i] = item;
break;// after insert the number, we can just break the for loop
once the new number is inserted, break the for loop, else, the size variable will not be correct
else { // If item is not less than or equal to any
theData[size] = item; // numbers in the array, add it to the end
size++;
break;
}
I have a 2d grid of integers.
grid[][];
Suppose I am given an element randomly from the 2d array. My aim is to return its adjacent grid elements.
For that I am creating an ArrayList
ArrayList<int[][]> adjacentSidesList = new ArrayList<int[][]>();
I would have to go for quite a few number of cases and in each case the number of the adjacentSides would be different. So my choice of data structure is an ArrayList
But when I would add an element to the list
adjacentSidesList.add(grid[row][column+1]);
I understand this is wrong because I am adding the value of the grid element to the ArrayList and not the element itself. Does anyone have any idea on how to store the arrayElements in the arrayList and not the value stored in them ??
Any alternate method is also welcome with the reasons why the method is better
Thanks in Advance
Your grid object is a two-dimensional integer array. grid[row][column+1] is an integer, located in the respective indexes in your grid.
adjacentSidesList.add(grid[row][column+1]);
will not work, because you want to add an int to a list of ArrayList of two-dimensional int arrays. I believe you want to store numbers and you want to know what are those numbers. I wonder about the definition of neighbor. I will suppose here that the neighbor is the element located up, down, left or right to the current element, or, to put it more scientifically, the elements being located exactly at a distance of 1 from the current element in Taxicab-geometry.
The first problem is that a point might be at the margin of your space, which would mean they do not have a neighbor. The next problem is a general formula for the neighbors. I believe your numbers should be aware of their position, therefore we should define the following class:
public class GridHandler {
private static GridHandler[][] grid;
private int i;
private int j;
private int value;
public static void init(int[][] input) {
int rowNumber = input.length;
int columnNumber = input[0].length;
grid = new GridHandler[rowNumber][columnNumber];
for (int r = 0; r < rowNumber; r++) {
for (c = 0; c < columnNumber; c++) {
grid[r][c] = new GridHandler(r, c, input[r][c]);
}
}
}
public static GridHandler[][] getGrid() {
return grid;
}
public GridHandler(int i, int j, int value) {
this.i = i;
this.j = j;
this.value = value;
grid[i][j] = this;
}
public int getValue() {
return value;
}
public void setValue(value) {
this.value = value;
}
public int getLeftValue() throws ArrayIndexOutOfBoundsException {
if (j == 0) {
throw new ArrayIndexOutOfBoundsException("Left edge");
}
return grid[i][j - 1].getValue();
}
public int getUpValue() throws ArrayIndexOutOfBoundsException {
if (i == 0) {
throw new ArrayIndexOutOfBoundsException("Up edge");
}
return grid[i - 1][j].getValue();
}
public int getRightValue() throws ArrayIndexOutOfBoundsException {
if (j == grid[0].length - 1) {
throw new ArrayIndexOutOfBoundsException("Right edge");
}
return grid[i][j + 1].getValue();
}
public int getDownValue() throws ArrayIndexOutOfBoundsException {
if (i == grid.length - 1) {
throw new ArrayIndexOutOfBoundsException("Down edge");
}
return grid[i + 1][j].getValue();
}
}
Now, if you use that class, each element will be aware of their neighbors. You can initialize the whole thing like this:
GridHandler.init(grid);
I hope this helps.
You could create a new class which will hold row and column index of 2D array element like:
class Index {
private int row;
private int column;
//getter and setters
}
Now when you want to store the data in list, you store the index object and when you have to access the element, you can access it like:
Index index = adjacentSidesList.get(0);
int element = grid[index.getRow()][index.getColumn()];
I need to keep top N(< 1000) integers while trying to add values from a big list of integers(around a million sized lazy list). I want to be try adding values to a collection but that needs to keep only the top N(highest values) integers. Is there any preferred data structure to use for this purpose ?
I'd suggest to use some sorted data structure, such as TreeSet. Before insertion, check the number of items in the set, and if it reached 1000, remove the smallest number if it's smaller than the newly added number, and add the new number.
TreeSet<Integer> set = ...;
public void add (int n) {
if (set.size () < 1000) {
set.add (n);
} else {
Integer first = set.first();
if (first.intValue() < n) {
set.pollFirst();
set.add (n);
}
}
}
Google Guava MinMaxPriorityQueue class.
You can also use custom sorting by using a comparator (Use orderedBy(Comparator<B> comparator) method).
Note: This collection is NOT a sorted collection.
See javadoc
Example:
#Test
public void test() {
final int maxSize = 5;
// Natural order
final MinMaxPriorityQueue<Integer> queue = MinMaxPriorityQueue
.maximumSize(maxSize).create();
queue.addAll(Arrays.asList(10, 30, 60, 70, 20, 80, 90, 50, 100, 40));
assertEquals(maxSize, queue.size());
assertEquals(new Integer(50), Collections.max(queue));
System.out.println(queue);
}
Output:
[10, 50, 40, 30, 20]
One efficient solution is a slightly tweaked array-based priority queue using a binary min-heap.
First N integers are simply added to the heap one by one or you can build it from array of first N integers (slightly faster).
After that, compare the incoming integer with the root element (which is MIN value found so far). If the new integer is larger that that, simply replace the root with this new integer and perform down-heap operation (i.e. trickle down the new integer until both its children are smaller or it becomes a leaf). The data structure guarantees you will always have N largest integers so far with average addition time of O(log N).
Here is my C# implementation, the mentioned method is named "EnqueueDown". The "EnqueueUp" is a standard enqueue operation that expands the array, adds new leaf and trickles it up.
I have tested it on 1M numbers with max heap size of 1000 and it runs under 200 ms:
namespace ImagingShop.Research.FastPriorityQueue
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
public sealed class FastPriorityQueue<T> : IEnumerable<Tuple<T, float>>
{
private readonly int capacity;
private readonly Tuple<T, float>[] nodes;
private int count = 0;
public FastPriorityQueue(int capacity)
{
this.capacity = capacity;
this.nodes = new Tuple<T, float>[capacity];
}
public int Capacity => this.capacity;
public int Count => this.count;
public T FirstNode => this.nodes[0].Item1;
public float FirstPriority => this.nodes[0].Item2;
public void Clear()
{
this.count = 0;
}
public bool Contains(T node) => this.nodes.Any(tuple => Equals(tuple.Item1, node));
public T Dequeue()
{
T nodeHead = this.nodes[0].Item1;
int index = (this.count - 1);
this.nodes[0] = this.nodes[index];
this.count--;
DownHeap(index);
return nodeHead;
}
public void EnqueueDown(T node, float priority)
{
if (this.count == this.capacity)
{
if (priority < this.nodes[0].Item2)
{
return;
}
this.nodes[0] = Tuple.Create(node, priority);
DownHeap(0);
return;
}
int index = this.count;
this.count++;
this.nodes[index] = Tuple.Create(node, priority);
UpHeap(index);
}
public void EnqueueUp(T node, float priority)
{
int index = this.count;
this.count++;
this.nodes[index] = Tuple.Create(node, priority);
UpHeap(index);
}
public IEnumerator<Tuple<T, float>> GetEnumerator()
{
for (int i = 0; i < this.count; i++) yield return this.nodes[i];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DownHeap(int index)
{
while (true)
{
int indexLeft = (index << 1);
int indexRight = (indexLeft | 1);
int indexMin = ((indexLeft < this.count) && (this.nodes[indexLeft].Item2 < this.nodes[index].Item2))
? indexLeft
: index;
if ((indexRight < this.count) && (this.nodes[indexRight].Item2 < this.nodes[indexMin].Item2))
{
indexMin = indexRight;
}
if (indexMin == index)
{
break;
}
Flip(index, indexMin);
index = indexMin;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Flip(int indexA, int indexB)
{
var temp = this.nodes[indexA];
this.nodes[indexA] = this.nodes[indexB];
this.nodes[indexB] = temp;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void UpHeap(int index)
{
while (true)
{
if (index == 0)
{
break;
}
int indexParent = (index >> 1);
if (this.nodes[indexParent].Item2 <= this.nodes[index].Item2)
{
break;
}
Flip(index, indexParent);
index = indexParent;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
The basic implementation is taken from "Cormen, Thomas H. Introduction to algorithms. MIT press, 2009."
In Java 1.7 one may use java.util.PriorityQueue. To keep the top N items you need to use reverse comparator, e.g. for integers you order them descending. In this manner the smallest number is always on top and could be removed if to many items in queue.
package eu.pawelsz.example.topn;
import java.util.Comparator;
import java.util.PriorityQueue;
public class TopN {
public static <E> void add(int keep, PriorityQueue<E> priorityQueue, E element) {
if (keep == priorityQueue.size()) {
priorityQueue.poll();
}
priorityQueue.add(element);
}
public static void main(String[] args) {
int N = 4;
PriorityQueue<Integer> topN = new PriorityQueue<>(N, new Comparator<Integer>() {
#Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
add(N, topN, 1);
add(N, topN, 2);
add(N, topN, 3);
add(N, topN, 4);
System.out.println("smallest: " + topN.peek());
add(N, topN, 8);
System.out.println("smallest: " + topN.peek());
add(N, topN, 5);
System.out.println("smallest: " + topN.peek());
add(N, topN, 2);
System.out.println("smallest: " + topN.peek());
}
}
// this Keep Top Most K Instance in Queue
public static <E> void add(int keep, PriorityQueue<E> priorityQueue, E element) {
if(priorityQueue.size()<keep){
priorityQueue.add(element);
}
else if(keep == priorityQueue.size()) {
priorityQueue.add(element); // size = keep +1 but
Object o = (Object)topN.toArray()[k-1];
topN.remove(o); // resized to keep
}
}
The fastest way is likely a simple array items = new Item[N]; and a revolving cursor int cursor = 0;. The cursor points to the insertion point of the next element.
To add a new element use the method
put(Item newItem) { items[cursor++] = newItem; if(cursor == N) cursor = 0; }
when accessing this structure you can make the last item added appear at index 0 via a small recalculation of the index, i.e.
get(int index) { return items[ cursor > index ? cursor-index-1 : cursor-index-1+N ]; }
(the -1 is because cursor always point at the next insertion point, i.e. cursor-1 is the last element added).
Summary: put(item) will add a new item. get(0) will get the last item added, get(1) will get the second last item, etc.
In case you need to take care of the case where n < N elements have been added you just need to check for null.
(TreeSets will likely be slower)
Your Question is answered here:
Size-limited queue that holds last N elements in Java
To summerize it:
No there is no data structure in the default java sdk, but Apache commons collections 4 has a CircularFifoQueue.