Compare commits

...

8 Commits

31 changed files with 899 additions and 230 deletions

View File

@ -16,7 +16,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '21'
java-version: '11'
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v3
- name: Gradle build

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
# Ignore Gradle build output directory
build
bin

1
.idea/gradle.xml generated
View File

@ -10,6 +10,7 @@
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/clients" />
<option value="$PROJECT_DIR$/module4" />
<option value="$PROJECT_DIR$/module5" />
</set>
</option>
</GradleProjectSettings>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/module4/Pricenton1.module4.test.iml" filepath="$PROJECT_DIR$/.idea/modules/module4/Pricenton1.module4.test.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$/../../../module4/src/test" dumb="true">
<sourceFolder url="file://$MODULE_DIR$/../../../module4/src/test/java" isTestSource="true" />
</content>
</component>
</module>

View File

@ -1,4 +1,8 @@
{
"java.compile.nullAnalysis.mode": "automatic",
"jdk.java.onSave.organizeImports": true
"jdk.java.onSave.organizeImports": true,
"java.configuration.updateBuildConfiguration": "interactive",
"cSpell.words": [
"hithomelabs"
]
}

View File

@ -1,10 +1,18 @@
#Data Structures
# Data Structures
1. Stacks:
- Linear data structure
- Can have various implementations
- Should support (LIFO)
- Primitive implementation (Using arrays of primitive data types)
- Other implementations (Using linked lists)
2. Queues:
1. Stacks:
- [API](../module4/src/main/java/com/hithomelabs/princeton1/module4/Stack.java)
- [Sample client](../clients/src/main/java/com/hithomelabs/clients/ArrayStackClient.java)
- Linear data structure
- Can have various implementations
- Should support (LIFO)
- [Primitive implementation](../module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayStack.java) (Using arrays of primitive data types)
- [Other implementations](../module4/src/main/java/com/hithomelabs/princeton1/module4/LinkedStack.java) (Using linked lists)
2. Queues:
- [API](../module4/src/main/java/com/hithomelabs/princeton1/module4/Queue.java)
- [sample Client](../clients/src/main/java/com/hithomelabs/clients/LinkedQueueClient.java)
- Linear data structure.
- Can have various implementations.
- Should support FIFO.
- [Primitive implementation](../module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayQueue.java) (Using array of primitive data types)
- Other implementation ([using linked lists](../module4/src/main/java/com/hithomelabs/princeton1/module4/LinkedQueue.java))

View File

@ -13,6 +13,12 @@ dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
implementation project(':module4')
implementation project(':module5')
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
}
}
test {

View File

@ -1,4 +1,4 @@
package com.hithomelabs.clients;
package com.hithomelabs.clients.module4;
import com.hithomelabs.princeton1.module4.ArrayQueue;
import com.hithomelabs.princeton1.module4.Queue;

View File

@ -1,4 +1,4 @@
package com.hithomelabs.clients;
package com.hithomelabs.clients.module4;
import com.hithomelabs.princeton1.module4.ArrayStack;
import com.hithomelabs.princeton1.module4.Stack;

View File

@ -1,4 +1,4 @@
package com.hithomelabs.clients;
package com.hithomelabs.clients.module4;
import com.hithomelabs.princeton1.module4.LinkedQueue;
import com.hithomelabs.princeton1.module4.Queue;

View File

@ -1,4 +1,4 @@
package com.hithomelabs.clients;
package com.hithomelabs.clients.module4;
import com.hithomelabs.princeton1.module4.LinkedStack;

View File

@ -0,0 +1,28 @@
package com.hithomelabs.clients.module5;
import com.hithomelabs.princeton1.module5.Insertion;
import com.hithomelabs.princeton1.module5.Apple;
import com.hithomelabs.princeton1.module5.Orange;
public class InsertionClient {
public static void main(String[] args){
Apple[] apples = new Apple[3];
Orange[] oranges = new Orange[3];
Insertion<Apple> insertion = new Insertion<>();
apples[0] = new Apple(3);
apples[1] = new Apple(5);
apples[2] = new Apple(4);
insertion.sort(apples);
//* * Sample output
for (int i = 0; i < apples.length; i++)
System.out.println(apples[i]);
}
}

View File

@ -0,0 +1,66 @@
package com.hithomelabs.clients.module5;
import com.hithomelabs.princeton1.module5.Selection;
import java.util.ArrayList;
public class SelectionClient {
public static void main(String[] args){
Apple[] apples = new Apple[3];
Orange[] oranges = new Orange[3];
Selection<Apple> selection = new Selection<Apple>();
apples[0] = new Apple(3);
apples[1] = new Apple(5);
apples[2] = new Apple(4);
selection.sort(apples);
//* * Sample output
for (int i = 0; i < apples.length; i++)
System.out.println(apples[i]);
oranges[0] = new Orange(4);
oranges[1] = new Orange(1);
// * Should give runtime exception as ClassCastException is a runtime exception
//selection.sort(oranges);
Selection<Orange> selection2 = new Selection<Orange>();
// * Should result in a compile time exception, as casting to Orange will fail
//selection2.sort(apples);
}
private static class Orange{
private int size;
Orange(int size){
this.size = size;
}
@Override
public String toString() {
return "An orange of size "+size;
}
}
private static class Apple implements Comparable<Apple>{
private int size;
Apple(int size){
this.size = size;
}
@Override
public String toString() {
return "An apple of size "+size;
}
@Override
public int compareTo(Apple that) {
if (this.size < that.size) return -1;
else if (this.size == that.size)return 0;
else return 1;
}
}
}

View File

@ -0,0 +1,29 @@
package com.hithomelabs.clients.module5;
import com.hithomelabs.princeton1.module5.Apple;
import com.hithomelabs.princeton1.module5.Shell;
import java.util.Arrays;
import java.util.Random;
public class ShellClient {
public static void main(String[] args) {
int size = 100;
Apple[] apples = new Apple[size];
Shell<Apple> shell = new Shell<Apple>();
for (int i = 0; i < apples.length; i++) {
apples[i] = new Apple(new Random().nextInt(1000));
}
Apple[] applesCopy = Arrays.copyOf(apples, size);
shell.sort(apples);
shell.insertionSort(applesCopy);
//* * Sample output
for (int i = 0; i < apples.length; i++)
System.out.println(apples[i]);
}
}

View File

@ -1,103 +1,98 @@
package com.hithomelabs.princeton1.module4;
import javax.annotation.Nonnull;
import java.util.Iterator;
import javax.annotation.Nonnull;
public class ArrayQueue<E> extends Queue<E>{
<<<<<<< Updated upstream
@Override
public boolean isEmpty() {
return false;
=======
// insertion from tail, removal from head
public static final int DEFAULT_CAPACITY = 10;
private int capacity;
private int tail;
private int head;
private int size;
private E[] arr;
public ArrayQueue(){
this(DEFAULT_CAPACITY);
}
public ArrayQueue(int capacity){
this.capacity = capacity;
arr = (E[]) new Object[this.capacity];
size = 0;
}
private E[] queueArray = (E[]) new Object[1];
private int startPtr = 0;
private int endPtr = 0;
@Override
public boolean isEmpty() {
return size == 0;
return startPtr >= endPtr;
>>>>>>> Stashed changes
}
@Override
public E dequeue() {
if(isEmpty())
<<<<<<< Updated upstream
return null;
=======
if(isEmpty()){
return null;
else{
E element = arr[head];
// Garbage collection
arr[head] = null;
head = (head+1)%capacity;
size = size - 1;
if(capacity >= 40 && size < capacity/4){
capacity = capacity/2;
resize(capacity, capacity*2);
}
return element;
}
E currentValue = queueArray[startPtr];
queueArray[startPtr++] = null;
if(size() < queueArray.length/4){
changeArraySize(queueArray.length/2);
}
return currentValue;
>>>>>>> Stashed changes
}
@Override
public void enqueue(E element) {
// We plan capacity expansion if needed
if (size == capacity){
capacity = capacity * 2;
resize(capacity, capacity/2);
}
arr[tail] = element;
tail = (tail + 1) % capacity;
++size;
}
<<<<<<< Updated upstream
// When resize takes place always the original array is full, so copy the complete array as is
private void resize(int capacity, int oldCapacity) {
E[] resizedArr = (E[]) new Object[capacity];
for(int i = 0; i < size; i++) {
resizedArr[i] = arr[head];
// halving because capacity has now doubled
arr[head] = null;
head = (head + 1) % oldCapacity;
=======
queueArray[endPtr++] = element;
if(endPtr >= queueArray.length){
changeArraySize(queueArray.length*2);
}
arr = resizedArr;
// When resizing takes place, we bring the head to 0 and the tail to size
// tail is where new inserts will be made and head will be where elements will be removed
tail = size;
head = 0;
>>>>>>> Stashed changes
}
@Override
public int size() {
return size;
<<<<<<< Updated upstream
return 0;
}
@Override
@Nonnull
public Iterator<E> iterator() {
return new Iterator<E>() {
int counter = size;
int pointer = head;
@Override
public boolean hasNext() {
return counter != 0;
}
return null;
=======
return endPtr - startPtr;
}
@Override
public E next() {
E element = arr[pointer];
pointer = (pointer + 1)% capacity;
--counter;
return element;
}
};
private void changeArraySize(int targetSize){
E[] tempArray = queueArray;
int oldArraySize = tempArray.length;
queueArray = (E[]) new Object[targetSize];
int j = 0;
for(int i=startPtr; i<endPtr; i++)
queueArray[j++]=tempArray[i];
endPtr = size();
startPtr = 0;
}
@Nonnull
@Override
public Iterator<E> iterator() {
return new QueueArrayIterator();
}
private class QueueArrayIterator implements Iterator<E>{
private int iteratorIndex = startPtr;
@Override
public boolean hasNext() {
return iteratorIndex<endPtr;
}
@Override
public E next() {
return queueArray[iteratorIndex++];
}
>>>>>>> Stashed changes
}
}

View File

@ -1,98 +1,96 @@
package com.hithomelabs.princeton1.module4;
import javax.annotation.Nonnull;
import java.util.Iterator;
import javax.annotation.Nonnull;
// Concrete implementation of stack using arrays
// Creating a generic stack of type E
public class ArrayStack<E> extends Stack<E> {
<<<<<<< Updated upstream
@Override
public boolean isEmpty() {
return false;
=======
// Capacity and size are two variables, capacity determines total capacity of array, capacity defaults at 10
// Everytime size == capacity, capacity = 2 * capacity
private static final int DEFAULT_CAPACITY = 10;
private int capacity;
private int size;
private E[] arr;
public ArrayStack(int capacity){
this.capacity = capacity;
arr = (E[]) new Object[this.capacity];
}
// Constructor chaining, default constructor will call parametrised constructor with default initial capacity 10
public ArrayStack(){
this(DEFAULT_CAPACITY);
}
E[] stackArray = (E[]) new Object[1];
private int index = 0;
private int arrayLength = stackArray.length;
@Override
public boolean isEmpty() {
return size == 0;
return index == 0;
>>>>>>> Stashed changes
}
private void changeCapacity(int newCapacity){
E[] resizedArr = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++)
resizedArr[i] = arr[i];
arr = resizedArr;
}
private void incrementSize(){
if (size == capacity){
capacity = 2 * capacity;
changeCapacity(capacity);
}
}
// Push always happens at the end of the stack
// Say the size of the stack is 1, new element gets inserted at 1
@Override
public void push(E element) {
// Lazy approach, we assume size to always be lesser than capacity
incrementSize();
arr[size++] = element;
<<<<<<< Updated upstream
=======
if(index == arrayLength){
changeArraySize(arrayLength*2);
}
stackArray[index] = element;
index++;
>>>>>>> Stashed changes
}
@Override
public E pop() {
if (isEmpty())
<<<<<<< Updated upstream
return null;
=======
if(index == 0){
return null;
else{
E e = arr[--size];
arr[size] = null;
checkResize();
return e;
}
}
private void checkResize() {
if (size < capacity / 4 && capacity >= 40){
capacity = capacity / 2;
changeCapacity(capacity);
index--;
if(index < arrayLength/4){
changeArraySize(arrayLength/2);
}
E temp = stackArray[index];
stackArray[index] = null;
return temp;
>>>>>>> Stashed changes
}
@Override
public int size() {
return size;
<<<<<<< Updated upstream
return 0;
}
@Override
@Nonnull
public Iterator<E> iterator() {
return new Iterator<E>() {
return null;
=======
return index;
}
int current = 0;
@Nonnull
@Override
public Iterator<E> iterator() {
return new StackIterator();
}
@Override
public boolean hasNext() {
return current != size;
}
private void changeArraySize(int intendedSize){
E[] tempArray = stackArray;
int oldArraySize = stackArray.length;
stackArray = (E[]) new Object[intendedSize];
arrayLength = stackArray.length;
System.arraycopy(tempArray, 0, stackArray, 0, Math.min(oldArraySize, arrayLength));
}
@Override
public E next() {
E element = arr[current];
current = current + 1;
return element;
}
};
private class StackIterator implements Iterator<E>{
private int iteratorIndex = 0;
@Override
public boolean hasNext() {
return stackArray[iteratorIndex] != null;
}
@Override
public E next() {
return stackArray[iteratorIndex++];
}
>>>>>>> Stashed changes
}
}

View File

@ -4,71 +4,99 @@ import javax.annotation.Nonnull;
import java.util.Iterator;
public class LinkedQueue<E> extends Queue<E>{
<<<<<<< Updated upstream
@Override
public boolean isEmpty() {
return false;
=======
Node head;
Node tail;
int size;
Node<E> start = null;
Node<E> end = null;
private class Node{
E value;
Node next;
static private class Node<E>{
E data;
Node<E> next;
Node(E value){
this.value = value;
private Node(E element){
data=element;
next=null;
}
}
@Override
public boolean isEmpty() {
return size==0;
return start == null;
>>>>>>> Stashed changes
}
@Override
public E dequeue() {
if(isEmpty())
<<<<<<< Updated upstream
return null;
=======
if(isEmpty()) {
return null;
E element = head.value;
// Only a single element is present
if (head == tail){
tail = null;
}
head = head.next;
--size;
return element;
E currentValue = start.data;
start = start.next;
return currentValue;
>>>>>>> Stashed changes
}
@Override
public void enqueue(E element) {
Node newNode = new Node(element);
<<<<<<< Updated upstream
=======
Node<E> new_node = new Node<E>(element);
if(isEmpty())
head = newNode;
start = new_node;
else
tail.next = newNode;
tail = newNode;
++size;
end.next = new_node;
end = new_node;
>>>>>>> Stashed changes
}
@Override
public int size() {
return size;
<<<<<<< Updated upstream
return 0;
}
@Override
@Nonnull
public Iterator<E> iterator() {
return new Iterator<E>() {
Node current = head;
@Override
public boolean hasNext() {
return current != tail;
}
return null;
=======
int size = 0;
Node<E> sizePtr = start;
while (sizePtr != null) {
sizePtr = sizePtr.next;
size++;
}
return size;
}
@Override
public E next() {
E element = current.value;
current = current.next;
return element;
}
};
@Nonnull
@Override
public Iterator<E> iterator() {
return new LinkedQueueIterator();
}
private class LinkedQueueIterator implements Iterator<E>{
Node<E> traversePtr = start;
@Override
public boolean hasNext() {
return traversePtr != null;
}
@Override
public E next() {
E currentValue = traversePtr.data;
traversePtr = traversePtr.next;
return currentValue;
}
>>>>>>> Stashed changes
}
}

View File

@ -1,72 +1,105 @@
package com.hithomelabs.princeton1.module4;
import javax.annotation.Nonnull;
import java.util.Iterator;
// Creating a concrete linked Implementation of Stack
public class LinkedStack<E> extends Stack<E>{
// No need for an explicit constructor as size will be initialized to 0 and root to null
private int size;
private Node first;
// By default instance variables are package private
private class Node{
E value;
Node next;
}
// Will return true if size is 0
<<<<<<< Updated upstream
@Override
public boolean isEmpty() {
return (this.size == 0);
return false;
=======
static class Node<E>{
E data;
Node<E> next;
Node(E data) {
this.data = data;
this.next = null;
}
}
Node<E> head = null;
Node<E> endPtr = null;
int stackLength = 0;
@Override
public boolean isEmpty() {
return head == null;
>>>>>>> Stashed changes
}
// Adds an element to the start of a linked list
@Override
public void push(E element) {
Node newNode = new Node();
newNode.value = element;
newNode.next = first;
first = newNode;
this.size = this.size + 1;
<<<<<<< Updated upstream
=======
Node<E> new_node = new Node<E>(element);
if(stackLength == 0)
head = new_node;
else
endPtr.next = new_node;
endPtr = new_node;
stackLength++;
>>>>>>> Stashed changes
}
@Override
public E pop() {
if (this.isEmpty())
<<<<<<< Updated upstream
return null;
=======
if(stackLength == 0)
return null;
else{
Node toBePopped = first;
first = first.next;
this.size = this.size - 1;
return toBePopped.value;
}
if(stackLength == 1)
head = null;
Node<E> secondLastPtr = head;
while(secondLastPtr!=null && secondLastPtr.next != endPtr && secondLastPtr.next!=null)
secondLastPtr = secondLastPtr.next;
E currentValue = endPtr.data;
endPtr.next = null;
endPtr = secondLastPtr;
stackLength--;
return currentValue;
>>>>>>> Stashed changes
}
@Override
public int size() {
return this.size;
<<<<<<< Updated upstream
return 0;
=======
return stackLength;
>>>>>>> Stashed changes
}
@Nonnull
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
// Internal classes can access outer objects
Node current = first;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public E next() {
E element = current.value;
current = current.next;
return element;
}
};
<<<<<<< Updated upstream
return null;
}
=======
return new LinkedlistIterator();
}
private class LinkedlistIterator implements Iterator<E>{
Node<E> iteratorPtr = head;
@Override
public boolean hasNext() {
return iteratorPtr.next != null;
}
@Override
public E next() {
E currentValue = iteratorPtr.data;
iteratorPtr = iteratorPtr.next;
return currentValue;
}
}
>>>>>>> Stashed changes
}

View File

@ -0,0 +1,76 @@
package com.hithomelabs.princeton1.module4;
import java.util.Iterator;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class ArrayQueueTest {
private Queue<Integer> queue;
@BeforeEach
void setUp() {
queue = new ArrayQueue<Integer>();
}
@AfterEach
void tearDown() {
queue = null;
}
@Test
@DisplayName("Empty queue must return size zero")
public void testEmptyQueueSize(){
assertEquals(0, queue.size());
}
@Test
@DisplayName("Enqueuing must work as expected")
public void testEnqueue(){
queue.enqueue(1);
queue.enqueue(2);
assertEquals(2,queue.size());
Iterator<Integer> iterator = queue.iterator();
assertEquals(1, iterator.next());
assertEquals(2, iterator.next());
}
@Test
@DisplayName("Dequeueing must work as expected")
public void testDequeue(){
queue.enqueue(1);
queue.enqueue(2);
assertEquals(1, queue.dequeue());
queue.enqueue(3);
assertEquals(2, queue.size());
assertEquals(2, queue.dequeue());
assertEquals(3, queue.dequeue());
assertEquals(0, queue.size());
assertNull(queue.dequeue());
}
@Test
@DisplayName("Testing resizable array and iterator")
public void testResize(){
for(int i = 0; i < 21; i++)
queue.enqueue(i);
for(int i = 0; i < 13; i++){
queue.dequeue();
}
assertEquals(13, queue.dequeue());
assertEquals(7,queue.size());
Integer[] arr = new Integer[queue.size()];
Iterator<Integer> iterator = queue.iterator();
int count = 0;
while(iterator.hasNext()){
arr[count++] = iterator.next();
}
assertArrayEquals(new Integer[]{14, 15, 16, 17, 18, 19, 20}, arr);
}
}

View File

@ -0,0 +1,85 @@
package com.hithomelabs.princeton1.module4;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.Iterator;
import static org.junit.jupiter.api.Assertions.*;
class ArrayStackTest {
private Stack<String> stack;
@BeforeEach
void setUp() {
stack = new ArrayStack<String>();
}
@AfterEach
void tearDown() {
stack = null;
}
@Test
@DisplayName("Empty stack must return size zero")
public void testEmptyStackSize(){
assertEquals(0, stack.size());
}
@Test
@DisplayName("Push must work as expected")
public void testEnqueue(){
stack.push("Hello");
stack.push("World");
assertEquals(2,stack.size());
Iterator<String> iterator = stack.iterator();
assertEquals("Hello", iterator.next());
assertEquals("World", iterator.next());
}
@Test
@DisplayName("Pop must work as expected")
public void testDequeue(){
stack.push("hello");
stack.push("world");
assertEquals("world", stack.pop());
stack.push("I");
assertEquals(2, stack.size());
assertEquals("I", stack.pop());
assertEquals("hello", stack.pop());
assertEquals(0, stack.size());
assertNull(stack.pop());
}
@Test
@DisplayName("Testing resizable array and iterator")
public void testResize(){
stack.push("Hello");
stack.push("world");
stack.push("I");
stack.push("am");
stack.push("testing");
stack.push("my");
stack.push("implementation");
stack.push("of");
stack.push("Stacks");
stack.push("Data");
stack.push("Structure");
assertEquals("Structure", stack.pop());
int counter = 6;
while(counter-- > 0)
stack.pop();
assertEquals(4,stack.size());
String[] arr = new String[stack.size()];
Iterator<String> iterator = stack.iterator();
int count = 0;
while(iterator.hasNext()){
arr[count++] = iterator.next();
}
assertArrayEquals(new String[]{"Hello", "world", "I", "am"}, arr);
}
}

View File

@ -0,0 +1,76 @@
package com.hithomelabs.princeton1.module4;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.Iterator;
import static org.junit.jupiter.api.Assertions.*;
class LinkedQueueTest {
private Queue<Integer> queue;
@BeforeEach
void setUp() {
queue = new LinkedQueue<>();
}
@AfterEach
void tearDown() {
queue = null;
}
@Test
@DisplayName("Empty queue must return size zero")
public void testEmptyQueueSize(){
assertEquals(0, queue.size());
}
@Test
@DisplayName("Enqueuing must work as expected")
public void testEnqueue(){
queue.enqueue(1);
queue.enqueue(2);
assertEquals(2,queue.size());
Iterator<Integer> iterator = queue.iterator();
assertEquals(1, iterator.next());
assertEquals(2, iterator.next());
}
@Test
@DisplayName("Dequeueing must work as expected")
public void testDequeue(){
queue.enqueue(1);
queue.enqueue(2);
assertEquals(1, queue.dequeue());
queue.enqueue(3);
assertEquals(2, queue.size());
assertEquals(2, queue.dequeue());
assertEquals(3, queue.dequeue());
assertEquals(0, queue.size());
assertNull(queue.dequeue());
}
@Test
@DisplayName("Testing resizable array and iterator")
public void testResize(){
for(int i = 0; i < 21; i++)
queue.enqueue(i);
for(int i = 0; i < 13; i++){
queue.dequeue();
}
assertEquals(13, queue.dequeue());
assertEquals(7,queue.size());
Integer[] arr = new Integer[queue.size()];
Iterator<Integer> iterator = queue.iterator();
int count = 0;
while(iterator.hasNext()){
arr[count++] = iterator.next();
}
assertArrayEquals(new Integer[]{14, 15, 16, 17, 18, 19, 20}, arr);
}
}

23
module5/build.gradle Normal file
View File

@ -0,0 +1,23 @@
plugins {
id 'java'
}
group = 'com.hithomelabs.princeton1.module5'
version = 'unspecified'
repositories {
mavenCentral()
}
dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
}
}
test {
useJUnitPlatform()
}

View File

@ -0,0 +1,16 @@
package com.hithomelabs.princeton1.module5;
public abstract class AbstractCustomSorts<E> {
public abstract void sort(E[] arr);
// TODO: Implement this method
public void exch(E[] arr, int j, int i) {
}
// TODO: Implement this method
public boolean less(Comparable<E> e1, E e2) {
return e1.compareTo(e2) < 0;
}
}

View File

@ -0,0 +1,37 @@
package com.hithomelabs.princeton1.module5;
import java.util.Objects;
public class Apple implements Comparable<Apple> {
private int size;
public Apple(int size) {
this.size = size;
}
@Override
public boolean equals(Object obj) {
if(this == obj) return true;
if (obj == null || this.getClass() != obj.getClass())
return false;
Apple that = (Apple) obj;
return Objects.equals(this.size, that.size);
}
@Override
public int hashCode() {
return Objects.hash(size);
}
@Override
public String toString() {
return "An apple of size " + size;
}
@Override
public int compareTo(Apple that) {
if (this.size < that.size) return -1;
else if (this.size == that.size) return 0;
else return 1;
}
}

View File

@ -0,0 +1,9 @@
package com.hithomelabs.princeton1.module5;
public class Insertion<E> extends AbstractCustomSorts<E> {
@Override
public void sort(E[] arr) {
}
}

View File

@ -0,0 +1,14 @@
package com.hithomelabs.princeton1.module5;
public class Orange {
private int size;
public Orange(int size) {
this.size = size;
}
@Override
public String toString() {
return "An orange of size " + size;
}
}

View File

@ -0,0 +1,13 @@
package com.hithomelabs.princeton1.module5;
/*
* * Selection sort "selects" the smallest element and swaps it with arr[0] of the array
* * Then proceeds to do the same swapping arr[i] with arr[i:arr.length-1]
*/
public class Selection<E> extends AbstractCustomSorts<E>{
@Override
public void sort(E[] arr) {
}
}

View File

@ -0,0 +1,43 @@
package com.hithomelabs.princeton1.module5;
public class Shell<E> extends AbstractCustomSorts<E> {
// * * sample metadata class to compare no. of sorts and compares, shell sort vs insertion sort
private class MetaData{
int compares;
int swaps;
}
/*
* * We will be performing h sort
* * Suppose or function to determine subsequent values of h is:
* * h(i+1) = 3*h(i) + 1; h = 1, 4, 13, 40, 121, ....
* * h will never be perfectly divisible by 3; further dividing h[i]/3 will give h[i-1]
* * We want to h-sort using larges value of h smaller than N, followed by smaller values of h
* * If N = 100, we h-sort by 40, meaning every 40th element will be in order
* * Then we h-sort by 13, meaning every 40th and every 13th element will be in order and every 40th element will be in order
* * Finally, when h will come out as 1, it will be same as insertion sort, however by that time the array will almost be sorted
* * Insertion sort for an almost sorted array is linear time.
* * As a case study we implement both insertion sort and selection sort for an array of 1000 nos.
* * And check number of compares and no. of exchanges in each case
*/
@Override
public void sort(E[] arr) {
}
private int hsort(E[] arr, int h, MetaData metadata) {
return 0;
}
/*
! sample implementation of insertion sort as h-sort of h = 1
* Will just be comparing the number of saps taken across both implementations
*/
public void insertionSort(E[] arr){
MetaData metaData = new MetaData();
int h = 1;
h = hsort(arr, h, metaData);
System.out.println("Array sorted (insertion sort) with " + metaData.compares + " compares and " + metaData.swaps + " swaps");
}
}

View File

@ -0,0 +1,63 @@
package com.hithomelabs.princeton1.module5;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Random;
import static org.junit.jupiter.api.Assertions.*;
class SortTest {
private ArrayList<Apple> apples;
private AbstractCustomSorts<Apple> sortingAlgorithm;
private Random random;
@BeforeEach
void setUp() {
apples = new ArrayList<Apple>();
//sortingAlgorithm = new Selection<Apple>();
random = new Random();
}
private void testSort(AbstractCustomSorts<Apple> sortingAlgorithm) {
for (int i = 0; i < 100; i++)
apples.add(new Apple(random.nextInt(100)));
Apple[] arr = apples.toArray(new Apple[apples.size()]);
apples.sort(null);
Apple[] sorted = apples.toArray(new Apple[apples.size()]);
sortingAlgorithm.sort(arr);
assertArrayEquals(sorted, arr);
}
@Test
@DisplayName("Testing Insertion sort functionality")
public void testInsertionSort() {
sortingAlgorithm = new Insertion<Apple>();
testSort(sortingAlgorithm);
}
@Test
@DisplayName("Testing Selection sort functionality")
public void testSelectionSort() {
sortingAlgorithm = new Selection<Apple>();
testSort(sortingAlgorithm);
}
@Test
@DisplayName("Testing Shell sort functionality")
public void testShellSort() {
sortingAlgorithm = new Shell<>();
testSort(sortingAlgorithm);
}
@AfterEach
void tearDown() {
sortingAlgorithm = null;
apples = null;
}
}

View File

@ -13,4 +13,5 @@ plugins {
rootProject.name = 'Pricenton1'
include('module4')
include 'clients'
include 'module5'