kruti-working-branch #14
@ -6,23 +6,11 @@ import javax.annotation.Nonnull;
|
|||||||
|
|
||||||
public class ArrayQueue<E> extends Queue<E>{
|
public class ArrayQueue<E> extends Queue<E>{
|
||||||
|
|
||||||
// insertion from tail, removal from head
|
private E[] queueArray = (E[]) new Object[5];
|
||||||
public static final int DEFAULT_CAPACITY = 10;
|
private int startPtr;
|
||||||
private int capacity;
|
private int endPtr;
|
||||||
private int tail;
|
|
||||||
private int head;
|
|
||||||
private int size;
|
private int size;
|
||||||
private E[] arr;
|
private int queueArrayLength = queueArray.length;
|
||||||
|
|
||||||
public ArrayQueue(){
|
|
||||||
this(DEFAULT_CAPACITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayQueue(int capacity){
|
|
||||||
this.capacity = capacity;
|
|
||||||
arr = (E[]) new Object[this.capacity];
|
|
||||||
size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
@ -31,49 +19,25 @@ public class ArrayQueue<E> extends Queue<E>{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E dequeue() {
|
public E dequeue() {
|
||||||
if(isEmpty())
|
if(isEmpty()){
|
||||||
return null;
|
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 % queueArrayLength];
|
||||||
|
queueArray[startPtr++ % queueArrayLength] = null;
|
||||||
|
size--;
|
||||||
|
if(size() < queueArrayLength/4){
|
||||||
|
changeArraySize(queueArrayLength/2);
|
||||||
|
}
|
||||||
|
return currentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enqueue(E element) {
|
public void enqueue(E element) {
|
||||||
// We plan capacity expansion if needed
|
queueArray[endPtr++ % queueArrayLength] = element;
|
||||||
if (size == capacity){
|
size++;
|
||||||
capacity = capacity * 2;
|
if(size == queueArrayLength){
|
||||||
resize(capacity, capacity/2);
|
changeArraySize(queueArrayLength*2);
|
||||||
}
|
}
|
||||||
arr[tail] = element;
|
|
||||||
tail = (tail + 1) % capacity;
|
|
||||||
++size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -81,24 +45,37 @@ public class ArrayQueue<E> extends Queue<E>{
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void changeArraySize(int targetSize){
|
||||||
@Nonnull
|
E[] tempArray = queueArray;
|
||||||
public Iterator<E> iterator() {
|
int oldArraySize = tempArray.length;
|
||||||
return new Iterator<E>() {
|
queueArray = (E[]) new Object[targetSize];
|
||||||
int counter = size;
|
int j = 0;
|
||||||
int pointer = head;
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return counter != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
for(int i=0; i<size; i++)
|
||||||
hitanshu marked this conversation as resolved
Outdated
|
|||||||
public E next() {
|
queueArray[j++]=tempArray[(startPtr+i)%oldArraySize];
|
||||||
E element = arr[pointer];
|
endPtr = size();
|
||||||
pointer = (pointer + 1)% capacity;
|
startPtr = 0;
|
||||||
--counter;
|
queueArrayLength = queueArray.length;
|
||||||
return element;
|
}
|
||||||
}
|
|
||||||
};
|
@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 % queueArrayLength < endPtr % queueArrayLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
hitanshu marked this conversation as resolved
hitanshu
commented
Iterator does not account for wrapping Iterator does not account for wrapping
|
|||||||
|
return queueArray[iteratorIndex++ % queueArrayLength];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,93 +6,68 @@ import javax.annotation.Nonnull;
|
|||||||
// Creating a generic stack of type E
|
// Creating a generic stack of type E
|
||||||
public class ArrayStack<E> extends Stack<E> {
|
public class ArrayStack<E> extends Stack<E> {
|
||||||
|
|
||||||
// Capacity and size are two variables, capacity determines total capacity of array, capacity defaults at 10
|
E[] stackArray = (E[]) new Object[1];
|
||||||
// every time size == capacity, capacity = 2 * capacity
|
private int index = 0;
|
||||||
private static final int DEFAULT_CAPACITY = 10;
|
private int arrayLength = stackArray.length;
|
||||||
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 parametrized constructor with default initial capacity 10
|
|
||||||
public ArrayStack(){
|
|
||||||
this(DEFAULT_CAPACITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return size == 0;
|
return index == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
@Override
|
||||||
public void push(E element) {
|
public void push(E element) {
|
||||||
// Lazy approach, we assume size to always be lesser than capacity
|
if(index == arrayLength){
|
||||||
incrementSize();
|
changeArraySize(arrayLength*2);
|
||||||
arr[size++] = element;
|
}
|
||||||
|
stackArray[index] = element;
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E pop() {
|
public E pop() {
|
||||||
if (isEmpty())
|
if(index == 0){
|
||||||
return null;
|
return null;
|
||||||
else{
|
|
||||||
E e = arr[--size];
|
|
||||||
arr[size] = null;
|
|
||||||
checkResize();
|
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
}
|
index--;
|
||||||
|
if(index < arrayLength/4){
|
||||||
private void checkResize() {
|
changeArraySize(arrayLength/2);
|
||||||
if (size < capacity / 4 && capacity >= 20){
|
|
||||||
capacity = capacity / 2;
|
|
||||||
changeCapacity(capacity);
|
|
||||||
}
|
}
|
||||||
|
E temp = stackArray[index];
|
||||||
|
stackArray[index] = null;
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
return size;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@Override
|
||||||
public Iterator<E> iterator() {
|
public Iterator<E> iterator() {
|
||||||
return new Iterator<E>() {
|
return new StackIterator();
|
||||||
|
}
|
||||||
|
|
||||||
int current = 0;
|
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
|
private class StackIterator implements Iterator<E>{
|
||||||
public boolean hasNext() {
|
private int iteratorIndex = 0;
|
||||||
return current != size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E next() {
|
public boolean hasNext() {
|
||||||
E element = arr[current];
|
return stackArray[iteratorIndex] != null;
|
||||||
current = current + 1;
|
}
|
||||||
return element;
|
|
||||||
}
|
@Override
|
||||||
};
|
public E next() {
|
||||||
|
return stackArray[iteratorIndex++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,70 +5,76 @@ import java.util.Iterator;
|
|||||||
|
|
||||||
public class LinkedQueue<E> extends Queue<E>{
|
public class LinkedQueue<E> extends Queue<E>{
|
||||||
|
|
||||||
Node head;
|
Node<E> start = null;
|
||||||
Node tail;
|
Node<E> end = null;
|
||||||
int size;
|
|
||||||
|
|
||||||
private class Node{
|
static private class Node<E>{
|
||||||
E value;
|
E data;
|
||||||
Node next;
|
Node<E> next;
|
||||||
|
|
||||||
Node(E value){
|
private Node(E element){
|
||||||
this.value = value;
|
data=element;
|
||||||
|
next=null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return size==0;
|
return start == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E dequeue() {
|
public E dequeue() {
|
||||||
if(isEmpty())
|
if(isEmpty())
|
||||||
return null;
|
return null;
|
||||||
E element = head.value;
|
E currentValue = start.data;
|
||||||
// Only a single element is present
|
start = start.next;
|
||||||
if (head == tail){
|
if(isEmpty())
|
||||||
tail = null;
|
end = null;
|
||||||
hitanshu marked this conversation as resolved
Outdated
hitanshu
commented
Case where only 1 element in queue, end pointer is dangling. Case where only 1 element in queue, end pointer is dangling.
|
|||||||
}
|
return currentValue;
|
||||||
head = head.next;
|
|
||||||
--size;
|
|
||||||
return element;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enqueue(E element) {
|
public void enqueue(E element) {
|
||||||
Node newNode = new Node(element);
|
Node<E> new_node = new Node<E>(element);
|
||||||
if(isEmpty())
|
if(isEmpty())
|
||||||
head = newNode;
|
start = new_node;
|
||||||
else
|
else
|
||||||
tail.next = newNode;
|
end.next = new_node;
|
||||||
tail = newNode;
|
end = new_node;
|
||||||
++size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
|
int size = 0;
|
||||||
|
Node<E> sizePtr = start;
|
||||||
|
while (sizePtr != null) {
|
||||||
|
sizePtr = sizePtr.next;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@Override
|
||||||
public Iterator<E> iterator() {
|
public Iterator<E> iterator() {
|
||||||
return new Iterator<E>() {
|
return new LinkedQueueIterator();
|
||||||
Node current = head;
|
}
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return current != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private class LinkedQueueIterator implements Iterator<E>{
|
||||||
public E next() {
|
|
||||||
E element = current.value;
|
Node<E> traversePtr = start;
|
||||||
current = current.next;
|
|
||||||
return element;
|
@Override
|
||||||
}
|
public boolean hasNext() {
|
||||||
};
|
return traversePtr != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
|
E currentValue = traversePtr.data;
|
||||||
|
traversePtr = traversePtr.next;
|
||||||
|
return currentValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,72 +1,71 @@
|
|||||||
package com.hithomelabs.princeton1.module4;
|
package com.hithomelabs.princeton1.module4;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
// Creating a concrete linked Implementation of Stack
|
// Creating a concrete linked Implementation of Stack
|
||||||
public class LinkedStack<E> extends Stack<E>{
|
public class LinkedStack<E> extends Stack<E>{
|
||||||
|
|
||||||
// No need for an explicit constructor as size will be initialized to 0 and root to null
|
static class Node<E>{
|
||||||
private int size;
|
E data;
|
||||||
private Node first;
|
Node<E> next;
|
||||||
|
|
||||||
// By default instance variables are package private
|
Node(E data) {
|
||||||
private class Node{
|
this.data = data;
|
||||||
E value;
|
this.next = null;
|
||||||
Node next;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will return true if size is 0
|
Node<E> head = null;
|
||||||
hitanshu marked this conversation as resolved
hitanshu
commented
Why do you need two pointers, both insertion and deletion happen at head Why do you need two pointers, both insertion and deletion happen at head
|
|||||||
|
int stackLength = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return (this.size == 0);
|
return head == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds an element to the start of a linked list
|
|
||||||
@Override
|
@Override
|
||||||
public void push(E element) {
|
public void push(E element) {
|
||||||
Node newNode = new Node();
|
Node<E> new_node = new Node<E>(element);
|
||||||
newNode.value = element;
|
new_node.next = head;
|
||||||
newNode.next = first;
|
head = new_node;
|
||||||
first = newNode;
|
stackLength++;
|
||||||
this.size = this.size + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E pop() {
|
public E pop() {
|
||||||
if (this.isEmpty())
|
if(stackLength == 0)
|
||||||
return null;
|
return null;
|
||||||
else{
|
E currentValue = head.data;
|
||||||
Node toBePopped = first;
|
head = head.next;
|
||||||
first = first.next;
|
return currentValue;
|
||||||
this.size = this.size - 1;
|
|
||||||
return toBePopped.value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
return this.size;
|
return stackLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Iterator<E> iterator() {
|
public Iterator<E> iterator() {
|
||||||
return new Iterator<E>() {
|
return new LinkedlistIterator();
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,14 @@ public abstract class AbstractCustomSorts<E> {
|
|||||||
|
|
||||||
public abstract void sort(E[] arr);
|
public abstract void sort(E[] arr);
|
||||||
|
|
||||||
|
// TODO: Implement this method
|
||||||
public void exch(E[] arr, int j, int i) {
|
public void exch(E[] arr, int j, int i) {
|
||||||
E temp = arr[i];
|
E temp = arr[i];
|
||||||
arr[i] = arr[j];
|
arr[i] = arr[j];
|
||||||
arr[j] = temp;
|
arr[j] = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Implement this method
|
||||||
public boolean less(Comparable<E> e1, E e2) {
|
public boolean less(Comparable<E> e1, E e2) {
|
||||||
return e1.compareTo(e2) < 0;
|
return e1.compareTo(e2) < 0;
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,15 @@
|
|||||||
package com.hithomelabs.princeton1.module5;
|
package com.hithomelabs.princeton1.module5;
|
||||||
|
|
||||||
public class Insertion<E> extends AbstractCustomSorts<E> {
|
public class Insertion<E> extends AbstractCustomSorts<E> {
|
||||||
|
@Override
|
||||||
public void sort(E[] arr){
|
public void sort(E[] arr) {
|
||||||
if (arr == null) return;
|
for(int i=1; i<arr.length; i++){
|
||||||
else{
|
int k = i;
|
||||||
int N = arr.length;
|
for(int j=i-1; j>=0 && less((Comparable<E>) arr[k], arr[j]); j--){
|
||||||
// * * swap arr[i] with each element greater to it's left
|
exch(arr, k, j);
|
||||||
for (int i = 1; i < N; i++){
|
k = j;
|
||||||
int j = i;
|
|
||||||
while(j >= 1 && less((Comparable<E>)arr[j], arr[j-1])){
|
|
||||||
exch(arr, j, j-1);
|
|
||||||
j = j-1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,23 +1,20 @@
|
|||||||
package com.hithomelabs.princeton1.module5;
|
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>{
|
public class Selection<E> extends AbstractCustomSorts<E>{
|
||||||
|
@Override
|
||||||
/*
|
public void sort(E[] arr) {
|
||||||
* * Selection sort "selects" the smallest element and swaps it with arr[0] of the array
|
for (int i = 0; i < arr.length; i++) {
|
||||||
* * Then proceeds to do the same swapping arr[i] with arr[i:arr.length-1]
|
|
||||||
*/
|
|
||||||
public void sort(E[] arr){
|
|
||||||
if (arr == null) return;
|
|
||||||
Comparable<E>[] arr1 = (Comparable<E>[]) arr;
|
|
||||||
for(int i = 0; i < arr1.length - 1; i++){
|
|
||||||
int minIndex = i;
|
int minIndex = i;
|
||||||
for(int j = i+1; j < arr.length; j ++){
|
for(int j = i+1; j < arr.length; j++){
|
||||||
if (less((Comparable<E>) arr[j], arr[minIndex])) minIndex = j;
|
if(less((Comparable<E>) arr[j], arr[minIndex]))
|
||||||
|
minIndex = j;
|
||||||
}
|
}
|
||||||
exch(arr, i, minIndex);
|
exch(arr, i, minIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,32 +25,37 @@ public class Shell<E> extends AbstractCustomSorts<E> {
|
|||||||
@Override
|
@Override
|
||||||
public void sort(E[] arr) {
|
public void sort(E[] arr) {
|
||||||
MetaData metaData = new MetaData();
|
MetaData metaData = new MetaData();
|
||||||
int N = arr.length;
|
|
||||||
int h = 1;
|
int h = 1;
|
||||||
// * * Calculates the largest value of h greater than n
|
while(3*h + 1 < arr.length){
|
||||||
while (3 * h + 1 < N) {
|
h = 3*h + 1;
|
||||||
h = 3 * h + 1;
|
|
||||||
}
|
}
|
||||||
while (h >= 1) {
|
while(h>=1){
|
||||||
h = hsort(arr, h, metaData);
|
hsort(arr, h, metaData);
|
||||||
h = h / 3;
|
h= h/3;
|
||||||
}
|
}
|
||||||
|
// for(int i=arr.length/10; i>=0; i--){
|
||||||
|
// hsort(arr, 3*i+1, metaData);
|
||||||
|
// }
|
||||||
System.out.println("Array sorted (shell sort) with " + metaData.compares + " compares and " + metaData.swaps + " swaps");
|
System.out.println("Array sorted (shell sort) with " + metaData.compares + " compares and " + metaData.swaps + " swaps");
|
||||||
}
|
}
|
||||||
|
|
||||||
private int hsort(E[] arr, int h, MetaData metadata) {
|
private void hsort(E[] arr, int h, MetaData metadata) {
|
||||||
int N = arr.length;
|
for(int i=h; i<arr.length; i=i+1){
|
||||||
for(int i = h; i < N; i++){
|
int k = i;
|
||||||
int j = i;
|
for(int j=i-h; j>=0; j=j-h){
|
||||||
++metadata.compares;
|
metadata.compares++;
|
||||||
while(j >= h && less((Comparable<E>) arr[j], arr[j-h])){
|
if(less((Comparable<E>) arr[k], arr[j])){
|
||||||
++metadata.swaps;
|
exch(arr, k, j);
|
||||||
exch(arr, j, j-h);
|
k = j;
|
||||||
j = j - h;
|
metadata.swaps++;
|
||||||
++metadata.compares;
|
}
|
||||||
|
else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return h;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Sample implementation of insertion sort as h-sort of h = 1
|
* Sample implementation of insertion sort as h-sort of h = 1
|
||||||
@ -59,7 +64,7 @@ public class Shell<E> extends AbstractCustomSorts<E> {
|
|||||||
public void insertionSort(E[] arr){
|
public void insertionSort(E[] arr){
|
||||||
MetaData metaData = new MetaData();
|
MetaData metaData = new MetaData();
|
||||||
int h = 1;
|
int h = 1;
|
||||||
h = hsort(arr, h, metaData);
|
hsort(arr, h, metaData);
|
||||||
System.out.println("Array sorted (insertion sort) with " + metaData.compares + " compares and " + metaData.swaps + " swaps");
|
System.out.println("Array sorted (insertion sort) with " + metaData.compares + " compares and " + metaData.swaps + " swaps");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,40 +5,40 @@ import com.hithomelabs.princeton1.module5.AbstractCustomSorts;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class Merge<E> extends AbstractCustomSorts<E> {
|
public class Merge<E> extends AbstractCustomSorts<E> {
|
||||||
|
private E[] auxArr;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sort(E[] arr) {
|
public void sort(E[] arr) {
|
||||||
|
auxArr = (E[]) new Object[arr.length];
|
||||||
int N = arr.length;
|
merge_sort(arr, 0, arr.length-1);
|
||||||
// * * aux is a helper array required for merge
|
|
||||||
E[] aux = Arrays.copyOf(arr, N);
|
|
||||||
mergesort(arr, aux, 0, N-1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mergesort(E[] arr, E[] aux, int lo, int hi) {
|
private void merge_sort(E[] arr, int low_index, int high_index){
|
||||||
|
if(high_index - low_index > 0) {
|
||||||
|
int mid_index = low_index + (high_index - low_index)/2;
|
||||||
|
merge_sort(arr, low_index, mid_index);
|
||||||
|
merge_sort(arr, mid_index + 1, high_index);
|
||||||
hitanshu marked this conversation as resolved
Outdated
hitanshu
commented
Making a new aux arry with each recursive call is expensive Making a new aux arry with each recursive call is expensive
|
|||||||
|
|
||||||
if (hi <= lo) return;
|
// Copy array
|
||||||
int mid = lo + (hi - lo)/2;
|
for(int i=low_index; i<= high_index; i++)
|
||||||
mergesort(arr, aux, lo, mid);
|
auxArr[i] = arr[i];
|
||||||
mergesort(arr, aux, mid+1, hi);
|
|
||||||
merge(arr, aux, lo, mid, hi);
|
|
||||||
|
|
||||||
}
|
// Sort
|
||||||
|
int low_index_ptr = low_index;
|
||||||
private void merge(E[] arr, E[] aux, int lo, int mid, int hi) {
|
int mid_index_ptr = low_index + (high_index - low_index)/2;
|
||||||
|
int high_index_ptr = mid_index_ptr + 1;
|
||||||
// * * creating backup of original array
|
if(!less((Comparable<E>) auxArr[mid_index_ptr], auxArr[high_index_ptr])) {
|
||||||
for (int i = lo; i <= hi; i++)
|
for (int i = low_index; i <= high_index; i++) {
|
||||||
aux[i] = arr[i];
|
if (low_index_ptr > mid_index_ptr) {
|
||||||
|
arr[i] = auxArr[high_index_ptr++];
|
||||||
int i = lo;
|
} else if (high_index_ptr > high_index)
|
||||||
int j = mid+1;
|
arr[i] = auxArr[low_index_ptr++];
|
||||||
for (int k = lo; k <= hi; k++){
|
else if (less((Comparable<E>) auxArr[low_index_ptr], auxArr[high_index_ptr]))
|
||||||
// * If i has already reached mid, no need to compare we insert at pointer k
|
arr[i] = auxArr[low_index_ptr++];
|
||||||
if(i > mid) arr[k] = aux[j++];
|
else
|
||||||
else if(j > hi) arr[k] = aux[i++];
|
arr[i] = auxArr[high_index_ptr++];
|
||||||
else if(less((Comparable<E>) aux[i], aux[j])) arr[k] = aux[i++];
|
}
|
||||||
else arr[k] = aux[j++];
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,49 +6,45 @@ import com.hithomelabs.princeton1.module5.AbstractCustomSorts;
|
|||||||
public class Quick<E> extends AbstractCustomSorts<E> {
|
public class Quick<E> extends AbstractCustomSorts<E> {
|
||||||
@Override
|
@Override
|
||||||
public void sort(E[] arr) {
|
public void sort(E[] arr) {
|
||||||
int N = arr.length;
|
randomShuffle(arr);
|
||||||
quickSort(arr, 0, N - 1);
|
partition(arr, 0, arr.length-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void altSort(E[] arr) {
|
private void randomShuffle(E[] arr){
|
||||||
int N = arr.length;
|
int array_len = arr.length;
|
||||||
altQuickSort(arr, 0, N-1);
|
for(int i=0; i< array_len; i++){
|
||||||
|
int random_index = (int)(Math.random()*array_len);
|
||||||
|
exch(arr, i, random_index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void altQuickSort(E[] arr, int lo, int hi) {
|
private void partition(E[] arr, int low, int high){
|
||||||
if (lo >= hi) return;
|
if(low >= high)
|
||||||
int i = lo + 1;
|
return;
|
||||||
int j = i;
|
int mid = sort(arr, low, high);
|
||||||
while(j <= hi){
|
partition(arr, low, mid-1);
|
||||||
if(less((Comparable<E>) arr[j], arr[lo])){
|
partition(arr, mid + 1, high);
|
||||||
exch(arr, i, j);
|
}
|
||||||
|
|
||||||
|
private int sort(E[] arr, int low, int high){
|
||||||
|
int i = low+1;
|
||||||
|
int j = high;
|
||||||
|
while (true){
|
||||||
|
// Find the i index greater than 1st element
|
||||||
|
while (i<=high && !less((Comparable<E>) arr[low], arr[i]))
|
||||||
i++;
|
i++;
|
||||||
}
|
// Find the j index less than 1st element
|
||||||
j++;
|
while (less((Comparable<E>) arr[low], arr[j]) && j > low)
|
||||||
|
j--;
|
||||||
|
// Break if indexes are crossed
|
||||||
|
if(j < i)
|
||||||
|
break;
|
||||||
|
// Swap index values of i & j
|
||||||
|
if(less((Comparable<E>) arr[j], arr[i]))
|
||||||
|
exch(arr, i, j);
|
||||||
}
|
}
|
||||||
exch(arr, i-1, lo);
|
// Swap 1st element to it's correct position
|
||||||
altQuickSort(arr, lo, i-2);
|
exch(arr, low, j);
|
||||||
altQuickSort(arr, i, hi);
|
return j;
|
||||||
}
|
|
||||||
|
|
||||||
private void quickSort(E[] arr, int lo, int hi) {
|
|
||||||
|
|
||||||
if (lo >= hi) return;
|
|
||||||
int i = lo;
|
|
||||||
int j = hi+1;
|
|
||||||
while(true){
|
|
||||||
while(less((Comparable<E>) arr[++i], arr[lo])){
|
|
||||||
if(i == hi) break;
|
|
||||||
}
|
|
||||||
while(!less((Comparable<E>) arr[--j], arr[lo])){
|
|
||||||
if (j == lo ) break;
|
|
||||||
}
|
|
||||||
if(j<=i) break;
|
|
||||||
exch(arr, i , j);
|
|
||||||
}
|
|
||||||
exch(arr, j, lo);
|
|
||||||
quickSort(arr, lo, j-1);
|
|
||||||
quickSort(arr, j+1, hi);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@ class QuickTest {
|
|||||||
Assertions.assertArrayEquals(sorted, arr);
|
Assertions.assertArrayEquals(sorted, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * * Optional test for alternate sort implmentation
|
||||||
|
/*
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("testing Quick sort default implementation")
|
@DisplayName("testing Quick sort default implementation")
|
||||||
public void testAltSort(){
|
public void testAltSort(){
|
||||||
@ -45,6 +47,8 @@ class QuickTest {
|
|||||||
Apple[] sorted = apples.toArray(new Apple[apples.size()]);
|
Apple[] sorted = apples.toArray(new Apple[apples.size()]);
|
||||||
Assertions.assertArrayEquals(sorted, arr);
|
Assertions.assertArrayEquals(sorted, arr);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
|
Loading…
Reference in New Issue
Block a user
If the old queue is wrapped, then endPtr will be less than startPtr