fix: remove unnecesary throw to fix #704

- Fix #704
- Thanks @lprone
This commit is contained in:
yanglbme
2019-02-06 10:13:55 +08:00
parent bb670a2ceb
commit 8b92c3fdbe
9 changed files with 368 additions and 363 deletions

View File

@ -1,16 +1,15 @@
/** /**
* *
*/ */
package heaps; package Heaps;
/** /**
* @author Nicolas Renard * @author Nicolas Renard
* Exception to be thrown if the getElement method is used on an empty heap. * Exception to be thrown if the getElement method is used on an empty heap.
*
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class EmptyHeapException extends Exception { public class EmptyHeapException extends Exception {
public EmptyHeapException(String message) { public EmptyHeapException(String message) {
super(message); super(message);
} }

View File

@ -1,4 +1,4 @@
package heaps; package Heaps;
/** /**
* Interface common to heap data structures.<br> * Interface common to heap data structures.<br>
@ -10,32 +10,31 @@ package heaps;
* max-heap).</p> * max-heap).</p>
* <p>All heap-related operations (inserting or deleting an element, extracting the min or max) are performed in * <p>All heap-related operations (inserting or deleting an element, extracting the min or max) are performed in
* O(log n) time.</p> * O(log n) time.</p>
*
* @author Nicolas Renard * @author Nicolas Renard
*
*
*/ */
public interface Heap { public interface Heap {
/** /**
*
* @return the top element in the heap, the one with lowest key for min-heap or with * @return the top element in the heap, the one with lowest key for min-heap or with
* the highest key for max-heap * the highest key for max-heap
* @throws Exception if heap is empty * @throws EmptyHeapException if heap is empty
*/ */
public abstract HeapElement getElement() throws EmptyHeapException; HeapElement getElement() throws EmptyHeapException;
/** /**
* Inserts an element in the heap. Adds it to then end and toggle it until it finds its * Inserts an element in the heap. Adds it to then end and toggle it until it finds its
* right position. * right position.
* *
* @param element an instance of the HeapElement class. * @param element an instance of the HeapElement class.
*/ */
public abstract void insertElement(HeapElement element); void insertElement(HeapElement element);
/** /**
* Delete an element in the heap. * Delete an element in the heap.
* *
* @param elementIndex int containing the position in the heap of the element to be deleted. * @param elementIndex int containing the position in the heap of the element to be deleted.
*/ */
public abstract void deleteElement(int elementIndex); void deleteElement(int elementIndex);
} }

View File

@ -1,7 +1,7 @@
/** /**
* *
*/ */
package heaps; package Heaps;
import java.lang.Double; import java.lang.Double;
import java.lang.Object; import java.lang.Object;
@ -12,116 +12,110 @@ import java.lang.Object;
* or double, either primitive type or object) and any kind of IMMUTABLE object the user sees fit * or double, either primitive type or object) and any kind of IMMUTABLE object the user sees fit
* to carry any information he/she likes. Be aware that the use of a mutable object might * to carry any information he/she likes. Be aware that the use of a mutable object might
* jeopardize the integrity of this information. </p> * jeopardize the integrity of this information. </p>
* @author Nicolas Renard
* *
* @author Nicolas Renard
*/ */
public class HeapElement { public class HeapElement {
private final double key; private final double key;
private final Object additionalInfo; private final Object additionalInfo;
// Constructors // Constructors
/** /**
* * @param key : a number of primitive type 'double'
* @param key : a number of primitive type 'double'
* @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry
* additional information of use for the user * additional information of use for the user
*/ */
public HeapElement(double key, Object info) { public HeapElement(double key, Object info) {
this.key = key; this.key = key;
this.additionalInfo = info; this.additionalInfo = info;
} }
/** /**
* * @param key : a number of primitive type 'int'
* @param key : a number of primitive type 'int'
* @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry
* additional information of use for the user * additional information of use for the user
*/ */
public HeapElement(int key, Object info) { public HeapElement(int key, Object info) {
this.key = key; this.key = key;
this.additionalInfo = info; this.additionalInfo = info;
} }
/** /**
* * @param key : a number of object type 'Integer'
* @param key : a number of object type 'Integer'
* @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry
* additional information of use for the user * additional information of use for the user
*/ */
public HeapElement(Integer key, Object info) { public HeapElement(Integer key, Object info) {
this.key = key; this.key = key;
this.additionalInfo = info; this.additionalInfo = info;
} }
/** /**
* * @param key : a number of object type 'Double'
* @param key : a number of object type 'Double'
* @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry
* additional information of use for the user * additional information of use for the user
*/ */
public HeapElement(Double key, Object info) { public HeapElement(Double key, Object info) {
this.key = key; this.key = key;
this.additionalInfo = info; this.additionalInfo = info;
} }
/** /**
*
* @param key : a number of primitive type 'double' * @param key : a number of primitive type 'double'
*/ */
public HeapElement(double key) { public HeapElement(double key) {
this.key = key; this.key = key;
this.additionalInfo = null; this.additionalInfo = null;
} }
/** /**
*
* @param key : a number of primitive type 'int' * @param key : a number of primitive type 'int'
*/ */
public HeapElement(int key) { public HeapElement(int key) {
this.key = key; this.key = key;
this.additionalInfo = null; this.additionalInfo = null;
} }
/** /**
*
* @param key : a number of object type 'Integer' * @param key : a number of object type 'Integer'
*/ */
public HeapElement(Integer key) { public HeapElement(Integer key) {
this.key = key; this.key = key;
this.additionalInfo = null; this.additionalInfo = null;
} }
/** /**
*
* @param key : a number of object type 'Double' * @param key : a number of object type 'Double'
*/ */
public HeapElement(Double key) { public HeapElement(Double key) {
this.key = key; this.key = key;
this.additionalInfo = null; this.additionalInfo = null;
} }
// Getters // Getters
/** /**
* @return the object containing the additional info provided by the user. * @return the object containing the additional info provided by the user.
*/ */
public Object getInfo() { public Object getInfo() {
return additionalInfo; return additionalInfo;
} }
/** /**
* @return the key value of the element * @return the key value of the element
*/ */
public double getKey() { public double getKey() {
return key; return key;
} }
// Overridden object methods // Overridden object methods
public String toString() { public String toString() {
return "Key: " + key + " - " +additionalInfo.toString(); return "Key: " + key + " - " + additionalInfo.toString();
} }
/** /**
*
* @param otherHeapElement * @param otherHeapElement
* @return true if the keys on both elements are identical and the additional info objects * @return true if the keys on both elements are identical and the additional info objects
* are identical. * are identical.

View File

@ -1,4 +1,4 @@
package heaps; package Heaps;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -6,66 +6,71 @@ import java.util.List;
/** /**
* Heap tree where a node's key is higher than or equal to its parent's and lower than or equal * Heap tree where a node's key is higher than or equal to its parent's and lower than or equal
* to its children's. * to its children's.
* @author Nicolas Renard
* *
* @author Nicolas Renard
*/ */
public class MaxHeap implements Heap { public class MaxHeap implements Heap {
private final List<HeapElement> maxHeap; private final List<HeapElement> maxHeap;
public MaxHeap(List<HeapElement> listElements) throws Exception { public MaxHeap(List<HeapElement> listElements) {
maxHeap = new ArrayList<HeapElement>(); maxHeap = new ArrayList<>();
for (HeapElement heapElement : listElements) { for (HeapElement heapElement : listElements) {
if (heapElement != null) insertElement(heapElement); if (heapElement != null) insertElement(heapElement);
else System.out.println("Null element. Not added to heap"); else System.out.println("Null element. Not added to heap");
} }
if (maxHeap.size() == 0) System.out.println("No element has been added, empty heap."); if (maxHeap.size() == 0) System.out.println("No element has been added, empty heap.");
} }
// Get the element at a given index. The key for the list is equal to index value - 1 /**
* Get the element at a given index. The key for the list is equal to index value - 1
*
* @param elementIndex index
* @return heapElement
*/
public HeapElement getElement(int elementIndex) { public HeapElement getElement(int elementIndex) {
if ((elementIndex <= 0) && (elementIndex > maxHeap.size())) throw new IndexOutOfBoundsException("Index out of heap range"); if ((elementIndex <= 0) || (elementIndex > maxHeap.size()))
throw new IndexOutOfBoundsException("Index out of heap range");
return maxHeap.get(elementIndex - 1); return maxHeap.get(elementIndex - 1);
} }
// Get the key of the element at a given index // Get the key of the element at a given index
private double getElementKey(int elementIndex) { private double getElementKey(int elementIndex) {
return maxHeap.get(elementIndex - 1).getKey(); return maxHeap.get(elementIndex - 1).getKey();
} }
// Swaps two elements in the heap // Swaps two elements in the heap
private void swap(int index1, int index2) { private void swap(int index1, int index2) {
HeapElement temporaryElement = maxHeap.get(index1 - 1); HeapElement temporaryElement = maxHeap.get(index1 - 1);
maxHeap.set(index1 - 1, maxHeap.get(index2 - 1)); maxHeap.set(index1 - 1, maxHeap.get(index2 - 1));
maxHeap.set(index2 - 1, temporaryElement); maxHeap.set(index2 - 1, temporaryElement);
} }
// Toggle an element up to its right place as long as its key is lower than its parent's // Toggle an element up to its right place as long as its key is lower than its parent's
private void toggleUp(int elementIndex) { private void toggleUp(int elementIndex) {
double key = maxHeap.get(elementIndex - 1).getKey(); double key = maxHeap.get(elementIndex - 1).getKey();
while (getElementKey((int) Math.floor(elementIndex/2)) < key) { while (getElementKey((int) Math.floor(elementIndex / 2)) < key) {
swap(elementIndex, (int) Math.floor(elementIndex/2)); swap(elementIndex, (int) Math.floor(elementIndex / 2));
elementIndex = (int) Math.floor(elementIndex/2); elementIndex = (int) Math.floor(elementIndex / 2);
} }
} }
// Toggle an element down to its right place as long as its key is higher // Toggle an element down to its right place as long as its key is higher
// than any of its children's // than any of its children's
private void toggleDown(int elementIndex) { private void toggleDown(int elementIndex) {
double key = maxHeap.get(elementIndex - 1).getKey(); double key = maxHeap.get(elementIndex - 1).getKey();
boolean wrongOrder = (key < getElementKey(elementIndex*2)) || (key < getElementKey(Math.min(elementIndex*2, maxHeap.size()))); boolean wrongOrder = (key < getElementKey(elementIndex * 2)) || (key < getElementKey(Math.min(elementIndex * 2, maxHeap.size())));
while ((2*elementIndex <= maxHeap.size()) && wrongOrder) { while ((2 * elementIndex <= maxHeap.size()) && wrongOrder) {
// Check whether it shall swap the element with its left child or its right one if any. // Check whether it shall swap the element with its left child or its right one if any.
if ((2*elementIndex < maxHeap.size()) && (getElementKey(elementIndex*2 + 1) > getElementKey(elementIndex*2))) { if ((2 * elementIndex < maxHeap.size()) && (getElementKey(elementIndex * 2 + 1) > getElementKey(elementIndex * 2))) {
swap(elementIndex, 2*elementIndex + 1); swap(elementIndex, 2 * elementIndex + 1);
elementIndex = 2*elementIndex + 1; elementIndex = 2 * elementIndex + 1;
} else {
swap(elementIndex, 2 * elementIndex);
elementIndex = 2 * elementIndex;
} }
else { wrongOrder = (key < getElementKey(elementIndex * 2)) || (key < getElementKey(Math.min(elementIndex * 2, maxHeap.size())));
swap(elementIndex, 2*elementIndex);
elementIndex = 2*elementIndex;
}
wrongOrder = (key < getElementKey(elementIndex*2)) || (key < getElementKey(Math.min(elementIndex*2, maxHeap.size())));
} }
} }
@ -84,21 +89,23 @@ public class MaxHeap implements Heap {
@Override @Override
public void deleteElement(int elementIndex) { public void deleteElement(int elementIndex) {
if (maxHeap.isEmpty()) if (maxHeap.isEmpty())
try { try {
throw new EmptyHeapException("Attempt to delete an element from an empty heap"); throw new EmptyHeapException("Attempt to delete an element from an empty heap");
} catch (EmptyHeapException e) { } catch (EmptyHeapException e) {
e.printStackTrace(); e.printStackTrace();
} }
if ((elementIndex > maxHeap.size()) && (elementIndex <= 0)) throw new IndexOutOfBoundsException("Index out of heap range"); if ((elementIndex > maxHeap.size()) || (elementIndex <= 0))
throw new IndexOutOfBoundsException("Index out of heap range");
// The last element in heap replaces the one to be deleted // The last element in heap replaces the one to be deleted
maxHeap.set(elementIndex - 1, getElement(maxHeap.size())); maxHeap.set(elementIndex - 1, getElement(maxHeap.size()));
maxHeap.remove(maxHeap.size()); maxHeap.remove(maxHeap.size());
// Shall the new element be moved up... // Shall the new element be moved up...
if (getElementKey(elementIndex) > getElementKey((int) Math.floor(elementIndex/2))) toggleUp(elementIndex); if (getElementKey(elementIndex) > getElementKey((int) Math.floor(elementIndex / 2))) toggleUp(elementIndex);
// ... or down ? // ... or down ?
else if (((2*elementIndex <= maxHeap.size()) && (getElementKey(elementIndex) < getElementKey(elementIndex*2))) || else if (((2 * elementIndex <= maxHeap.size()) && (getElementKey(elementIndex) < getElementKey(elementIndex * 2))) ||
((2*elementIndex < maxHeap.size()) && (getElementKey(elementIndex) < getElementKey(elementIndex*2)))) toggleDown(elementIndex); ((2 * elementIndex < maxHeap.size()) && (getElementKey(elementIndex) < getElementKey(elementIndex * 2))))
toggleDown(elementIndex);
} }
@Override @Override
@ -109,7 +116,4 @@ public class MaxHeap implements Heap {
throw new EmptyHeapException("Heap is empty. Error retrieving element"); throw new EmptyHeapException("Heap is empty. Error retrieving element");
} }
} }
}
}

View File

@ -1,7 +1,7 @@
/** /**
* *
*/ */
package heaps; package Heaps;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -9,66 +9,66 @@ import java.util.List;
/** /**
* Heap tree where a node's key is higher than or equal to its parent's and lower than or equal * Heap tree where a node's key is higher than or equal to its parent's and lower than or equal
* to its children's. * to its children's.
* @author Nicolas Renard
* *
* @author Nicolas Renard
*/ */
public class MinHeap implements Heap { public class MinHeap implements Heap {
private final List<HeapElement> minHeap; private final List<HeapElement> minHeap;
public MinHeap(List<HeapElement> listElements) throws Exception { public MinHeap(List<HeapElement> listElements) {
minHeap = new ArrayList<HeapElement>(); minHeap = new ArrayList<>();
for (HeapElement heapElement : listElements) { for (HeapElement heapElement : listElements) {
if (heapElement != null) insertElement(heapElement); if (heapElement != null) insertElement(heapElement);
else System.out.println("Null element. Not added to heap"); else System.out.println("Null element. Not added to heap");
} }
if (minHeap.size() == 0) System.out.println("No element has been added, empty heap."); if (minHeap.size() == 0) System.out.println("No element has been added, empty heap.");
} }
// Get the element at a given index. The key for the list is equal to index value - 1 // Get the element at a given index. The key for the list is equal to index value - 1
public HeapElement getElement(int elementIndex) { public HeapElement getElement(int elementIndex) {
if ((elementIndex <= 0) && (elementIndex > minHeap.size())) throw new IndexOutOfBoundsException("Index out of heap range"); if ((elementIndex <= 0) || (elementIndex > minHeap.size()))
throw new IndexOutOfBoundsException("Index out of heap range");
return minHeap.get(elementIndex - 1); return minHeap.get(elementIndex - 1);
} }
// Get the key of the element at a given index // Get the key of the element at a given index
private double getElementKey(int elementIndex) { private double getElementKey(int elementIndex) {
return minHeap.get(elementIndex - 1).getKey(); return minHeap.get(elementIndex - 1).getKey();
} }
// Swaps two elements in the heap // Swaps two elements in the heap
private void swap(int index1, int index2) { private void swap(int index1, int index2) {
HeapElement temporaryElement = minHeap.get(index1 - 1); HeapElement temporaryElement = minHeap.get(index1 - 1);
minHeap.set(index1 - 1, minHeap.get(index2 - 1)); minHeap.set(index1 - 1, minHeap.get(index2 - 1));
minHeap.set(index2 - 1, temporaryElement); minHeap.set(index2 - 1, temporaryElement);
} }
// Toggle an element up to its right place as long as its key is lower than its parent's // Toggle an element up to its right place as long as its key is lower than its parent's
private void toggleUp(int elementIndex) { private void toggleUp(int elementIndex) {
double key = minHeap.get(elementIndex - 1).getKey(); double key = minHeap.get(elementIndex - 1).getKey();
while (getElementKey((int) Math.floor(elementIndex/2)) > key) { while (getElementKey((int) Math.floor(elementIndex / 2)) > key) {
swap(elementIndex, (int) Math.floor(elementIndex/2)); swap(elementIndex, (int) Math.floor(elementIndex / 2));
elementIndex = (int) Math.floor(elementIndex/2); elementIndex = (int) Math.floor(elementIndex / 2);
} }
} }
// Toggle an element down to its right place as long as its key is higher // Toggle an element down to its right place as long as its key is higher
// than any of its children's // than any of its children's
private void toggleDown(int elementIndex) { private void toggleDown(int elementIndex) {
double key = minHeap.get(elementIndex - 1).getKey(); double key = minHeap.get(elementIndex - 1).getKey();
boolean wrongOrder = (key > getElementKey(elementIndex*2)) || (key > getElementKey(Math.min(elementIndex*2, minHeap.size()))); boolean wrongOrder = (key > getElementKey(elementIndex * 2)) || (key > getElementKey(Math.min(elementIndex * 2, minHeap.size())));
while ((2*elementIndex <= minHeap.size()) && wrongOrder) { while ((2 * elementIndex <= minHeap.size()) && wrongOrder) {
// Check whether it shall swap the element with its left child or its right one if any. // Check whether it shall swap the element with its left child or its right one if any.
if ((2*elementIndex < minHeap.size()) && (getElementKey(elementIndex*2 + 1) < getElementKey(elementIndex*2))) { if ((2 * elementIndex < minHeap.size()) && (getElementKey(elementIndex * 2 + 1) < getElementKey(elementIndex * 2))) {
swap(elementIndex, 2*elementIndex + 1); swap(elementIndex, 2 * elementIndex + 1);
elementIndex = 2*elementIndex + 1; elementIndex = 2 * elementIndex + 1;
} else {
swap(elementIndex, 2 * elementIndex);
elementIndex = 2 * elementIndex;
} }
else { wrongOrder = (key > getElementKey(elementIndex * 2)) || (key > getElementKey(Math.min(elementIndex * 2, minHeap.size())));
swap(elementIndex, 2*elementIndex);
elementIndex = 2*elementIndex;
}
wrongOrder = (key > getElementKey(elementIndex*2)) || (key > getElementKey(Math.min(elementIndex*2, minHeap.size())));
} }
} }
@ -87,23 +87,25 @@ public class MinHeap implements Heap {
@Override @Override
public void deleteElement(int elementIndex) { public void deleteElement(int elementIndex) {
if (minHeap.isEmpty()) if (minHeap.isEmpty())
try { try {
throw new EmptyHeapException("Attempt to delete an element from an empty heap"); throw new EmptyHeapException("Attempt to delete an element from an empty heap");
} catch (EmptyHeapException e) { } catch (EmptyHeapException e) {
e.printStackTrace(); e.printStackTrace();
} }
if ((elementIndex > minHeap.size()) && (elementIndex <= 0)) throw new IndexOutOfBoundsException("Index out of heap range"); if ((elementIndex > minHeap.size()) || (elementIndex <= 0))
throw new IndexOutOfBoundsException("Index out of heap range");
// The last element in heap replaces the one to be deleted // The last element in heap replaces the one to be deleted
minHeap.set(elementIndex - 1, getElement(minHeap.size())); minHeap.set(elementIndex - 1, getElement(minHeap.size()));
minHeap.remove(minHeap.size()); minHeap.remove(minHeap.size());
// Shall the new element be moved up... // Shall the new element be moved up...
if (getElementKey(elementIndex) < getElementKey((int) Math.floor(elementIndex/2))) toggleUp(elementIndex); if (getElementKey(elementIndex) < getElementKey((int) Math.floor(elementIndex / 2))) toggleUp(elementIndex);
// ... or down ? // ... or down ?
else if (((2*elementIndex <= minHeap.size()) && (getElementKey(elementIndex) > getElementKey(elementIndex*2))) || else if (((2 * elementIndex <= minHeap.size()) && (getElementKey(elementIndex) > getElementKey(elementIndex * 2))) ||
((2*elementIndex < minHeap.size()) && (getElementKey(elementIndex) > getElementKey(elementIndex*2)))) toggleDown(elementIndex); ((2 * elementIndex < minHeap.size()) && (getElementKey(elementIndex) > getElementKey(elementIndex * 2))))
toggleDown(elementIndex);
} }
@Override @Override
public HeapElement getElement() throws EmptyHeapException { public HeapElement getElement() throws EmptyHeapException {
try { try {
@ -112,4 +114,4 @@ public class MinHeap implements Heap {
throw new EmptyHeapException("Heap is empty. Error retrieving element"); throw new EmptyHeapException("Heap is empty. Error retrieving element");
} }
} }
} }

View File

@ -1,13 +1,13 @@
package Heaps;
/* Minimum Priority Queue /* Minimum Priority Queue
* It is a part of heap data structure * It is a part of heap data structure
* A heap is a specific tree based data structure * A heap is a specific tree based data structure
* in which all the nodes of tree are in a specific order. * in which all the nodes of tree are in a specific order.
* that is the children are arranged in some * that is the children are arranged in some
* respect of their parents, can either be greater * respect of their parents, can either be greater
* or less than the parent. This makes it a min priority queue * or less than the parent. This makes it a min priority queue
* or max priority queue. * or max priority queue.
*/ */
// Functions: insert, delete, peek, isEmpty, print, heapSort, sink // Functions: insert, delete, peek, isEmpty, print, heapSort, sink
@ -16,15 +16,15 @@ public class MinPriorityQueue {
private int capacity; private int capacity;
private int size; private int size;
// calss the constructor and initializes the capacity // calss the constructor and initializes the capacity
MinPriorityQueue(int c) { MinPriorityQueue(int c) {
this.capacity = c; this.capacity = c;
this.size = 0; this.size = 0;
this.heap = new int[c + 1]; this.heap = new int[c + 1];
} }
// inserts the key at the end and rearranges it // inserts the key at the end and rearranges it
// so that the binary heap is in appropriate order // so that the binary heap is in appropriate order
public void insert(int key) { public void insert(int key) {
if (this.isFull()) if (this.isFull())
return; return;
@ -41,41 +41,41 @@ public class MinPriorityQueue {
this.size++; this.size++;
} }
// returns the highest priority value // returns the highest priority value
public int peek() { public int peek() {
return this.heap[1]; return this.heap[1];
} }
// returns boolean value whether the heap is empty or not // returns boolean value whether the heap is empty or not
public boolean isEmpty() { public boolean isEmpty() {
if (0 == this.size) if (0 == this.size)
return true; return true;
return false; return false;
} }
// returns boolean value whether the heap is full or not // returns boolean value whether the heap is full or not
public boolean isFull() { public boolean isFull() {
if (this.size == this.capacity) if (this.size == this.capacity)
return true; return true;
return false; return false;
} }
// prints the heap // prints the heap
public void print() { public void print() {
for (int i = 1; i <= this.capacity; i++) for (int i = 1; i <= this.capacity; i++)
System.out.print(this.heap[i] + " "); System.out.print(this.heap[i] + " ");
System.out.println(); System.out.println();
} }
// heap sorting can be done by performing // heap sorting can be done by performing
// delete function to the number of times of the size of the heap // delete function to the number of times of the size of the heap
// it returns reverse sort because it is a min priority queue // it returns reverse sort because it is a min priority queue
public void heapSort() { public void heapSort() {
for (int i = 1; i < this.capacity; i++) for (int i = 1; i < this.capacity; i++)
this.delete(); this.delete();
} }
// this function reorders the heap after every delete function // this function reorders the heap after every delete function
private void sink() { private void sink() {
int k = 1; int k = 1;
while (2 * k <= this.size || 2 * k + 1 <= this.size) { while (2 * k <= this.size || 2 * k + 1 <= this.size) {
@ -103,7 +103,7 @@ public class MinPriorityQueue {
} }
} }
// deletes the highest priority value from the heap // deletes the highest priority value from the heap
public int delete() { public int delete() {
int min = this.heap[1]; int min = this.heap[1];
this.heap[1] = this.heap[this.size]; this.heap[1] = this.heap[this.size];

View File

@ -1,12 +1,11 @@
import java.util.Scanner; import java.util.Scanner;
/** /**
*
* @author Afrizal Fikri (https://github.com/icalF) * @author Afrizal Fikri (https://github.com/icalF)
* * @author Libin Yang (https://github.com/yanglbme)
*/ */
public class LongestIncreasingSubsequence { public class LongestIncreasingSubsequence {
public static void main(String[] args) throws Exception { public static void main(String[] args) {
Scanner sc = new Scanner(System.in); Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); int n = sc.nextInt();
@ -20,7 +19,7 @@ public class LongestIncreasingSubsequence {
} }
private static int upperBound(int[] ar, int l, int r, int key) { private static int upperBound(int[] ar, int l, int r, int key) {
while (l < r-1) { while (l < r - 1) {
int m = (l + r) / 2; int m = (l + r) / 2;
if (ar[m] >= key) if (ar[m] >= key)
r = m; r = m;
@ -35,10 +34,12 @@ public class LongestIncreasingSubsequence {
int N = array.length; int N = array.length;
if (N == 0) if (N == 0)
return 0; return 0;
int[] tail = new int[N]; int[] tail = new int[N];
int length = 1; // always points empty slot in tail
// always points empty slot in tail
int length = 1;
tail[0] = array[0]; tail[0] = array[0];
for (int i = 1; i < N; i++) { for (int i = 1; i < N; i++) {
@ -46,17 +47,17 @@ public class LongestIncreasingSubsequence {
if (array[i] < tail[0]) if (array[i] < tail[0])
tail[0] = array[i]; tail[0] = array[i];
// array[i] extends largest subsequence // array[i] extends largest subsequence
else if (array[i] > tail[length-1]) else if (array[i] > tail[length - 1])
tail[length++] = array[i]; tail[length++] = array[i];
// array[i] will become end candidate of an existing subsequence or // array[i] will become end candidate of an existing subsequence or
// Throw away larger elements in all LIS, to make room for upcoming grater elements than array[i] // Throw away larger elements in all LIS, to make room for upcoming grater elements than array[i]
// (and also, array[i] would have already appeared in one of LIS, identify the location and replace it) // (and also, array[i] would have already appeared in one of LIS, identify the location and replace it)
else else
tail[upperBound(tail, -1, length-1, array[i])] = array[i]; tail[upperBound(tail, -1, length - 1, array[i])] = array[i];
} }
return length; return length;
} }
} }

View File

@ -1,83 +1,82 @@
/* /**
@author : Mayank K Jha * @author Mayank K Jha
*/
*/
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Scanner; import java.util.Scanner;
import java.util.Stack; import java.util.Stack;
public class Dijkshtra { public class Dijkshtra {
public static void main(String[] args) throws IOException { public static void main(String[] args) {
Scanner in = new Scanner(System.in); Scanner in = new Scanner(System.in);
// n = Number of nodes or vertices // n = Number of nodes or vertices
int n = in.nextInt(); int n = in.nextInt();
// m = Number of Edges // m = Number of Edges
int m = in.nextInt(); int m = in.nextInt();
// Adjacency Matrix // Adjacency Matrix
long w[][] = new long [n+1][n+1]; long[][] w = new long[n + 1][n + 1];
//Initializing Matrix with Certain Maximum Value for path b/w any two vertices // Initializing Matrix with Certain Maximum Value for path b/w any two vertices
for (long[] row : w) { for (long[] row : w) {
Arrays.fill(row, 1000000l); Arrays.fill(row, 1000000L);
} }
/* From above,we Have assumed that,initially path b/w any two Pair of vertices is Infinite such that Infinite = 1000000l /* From above,we Have assumed that,initially path b/w any two Pair of vertices is Infinite such that Infinite = 1000000l
For simplicity , We can also take path Value = Long.MAX_VALUE , but i have taken Max Value = 1000000l */ For simplicity , We can also take path Value = Long.MAX_VALUE , but i have taken Max Value = 1000000l */
// Taking Input as Edge Location b/w a pair of vertices // Taking Input as Edge Location b/w a pair of vertices
for(int i = 0; i < m; i++) { for (int i = 0; i < m; i++) {
int x = in.nextInt(),y=in.nextInt(); int x = in.nextInt(), y = in.nextInt();
long cmp = in.nextLong(); long cmp = in.nextLong();
//Comparing previous edge value with current value - Cycle Case // Comparing previous edge value with current value - Cycle Case
if(w[x][y] > cmp) { if (w[x][y] > cmp) {
w[x][y] = cmp; w[y][x] = cmp; w[x][y] = cmp;
} w[y][x] = cmp;
}
} }
// Implementing Dijkshtra's Algorithm // Implementing Dijkshtra's Algorithm
Stack<Integer> t = new Stack<Integer>(); Stack<Integer> t = new Stack<>();
int src = in.nextInt(); int src = in.nextInt();
for(int i = 1; i <= n; i++) { for (int i = 1; i <= n; i++) {
if(i != src) { if (i != src) {
t.push(i); t.push(i);
} }
} }
Stack <Integer> p = new Stack<Integer>(); Stack<Integer> p = new Stack<>();
p.push(src); p.push(src);
w[src][src] = 0; w[src][src] = 0;
while(!t.isEmpty()) { while (!t.isEmpty()) {
int min = 989997979; int min = 989997979;
int loc = -1; int loc = -1;
for(int i = 0; i < t.size(); i++) { for (int i = 0; i < t.size(); i++) {
w[src][t.elementAt(i)] = Math.min(w[src][t.elementAt(i)], w[src][p.peek()] + w[p.peek()][t.elementAt(i)]); w[src][t.elementAt(i)] = Math.min(w[src][t.elementAt(i)], w[src][p.peek()] + w[p.peek()][t.elementAt(i)]);
if(w[src][t.elementAt(i)] <= min) { if (w[src][t.elementAt(i)] <= min) {
min = (int) w[src][t.elementAt(i)]; min = (int) w[src][t.elementAt(i)];
loc = i; loc = i;
} }
} }
p.push(t.elementAt(loc)); p.push(t.elementAt(loc));
t.removeElementAt(loc); t.removeElementAt(loc);
} }
// Printing shortest path from the given source src // Printing shortest path from the given source src
for(int i = 1; i <= n; i++) { for (int i = 1; i <= n; i++) {
if(i != src && w[src][i] != 1000000l) { if (i != src && w[src][i] != 1000000L) {
System.out.print(w[src][i] + " "); System.out.print(w[src][i] + " ");
}
// Printing -1 if there is no path b/w given pair of edges
else if (i != src) {
System.out.print("-1" + " ");
}
} }
// Printing -1 if there is no path b/w given pair of edges
else if(i != src) {
System.out.print("-1" + " ");
}
}
} }
} }

View File

@ -5,167 +5,174 @@ package Others;
* Dijkstra's algorithm,is a graph search algorithm that solves the single-source * Dijkstra's algorithm,is a graph search algorithm that solves the single-source
* shortest path problem for a graph with nonnegative edge path costs, producing * shortest path problem for a graph with nonnegative edge path costs, producing
* a shortest path tree. * a shortest path tree.
* * <p>
* NOTE: The inputs to Dijkstra's algorithm are a directed and weighted graph consisting * NOTE: The inputs to Dijkstra's algorithm are a directed and weighted graph consisting
* of 2 or more nodes, generally represented by an adjacency matrix or list, and a start node. * of 2 or more nodes, generally represented by an adjacency matrix or list, and a start node.
* * <p>
* Original source of code: https://rosettacode.org/wiki/Dijkstra%27s_algorithm#Java * Original source of code: https://rosettacode.org/wiki/Dijkstra%27s_algorithm#Java
* Also most of the comments are from RosettaCode. * Also most of the comments are from RosettaCode.
*
*/ */
//import java.io.*;
import java.util.*;
public class Dijkstra {
private static final Graph.Edge[] GRAPH = {
new Graph.Edge("a", "b", 7), //Distance from node "a" to node "b" is 7. In the current Graph there is no way to move the other way (e,g, from "b" to "a"), a new edge would be needed for that
new Graph.Edge("a", "c", 9),
new Graph.Edge("a", "f", 14),
new Graph.Edge("b", "c", 10),
new Graph.Edge("b", "d", 15),
new Graph.Edge("c", "d", 11),
new Graph.Edge("c", "f", 2),
new Graph.Edge("d", "e", 6),
new Graph.Edge("e", "f", 9),
};
private static final String START = "a";
private static final String END = "e";
/** import java.util.*;
* main function
* Will run the code with "GRAPH" that was defined above. public class Dijkstra {
*/ private static final Graph.Edge[] GRAPH = {
public static void main(String[] args) { // Distance from node "a" to node "b" is 7.
Graph g = new Graph(GRAPH); // In the current Graph there is no way to move the other way (e,g, from "b" to "a"),
g.dijkstra(START); // a new edge would be needed for that
g.printPath(END); new Graph.Edge("a", "b", 7),
//g.printAllPaths(); new Graph.Edge("a", "c", 9),
} new Graph.Edge("a", "f", 14),
new Graph.Edge("b", "c", 10),
new Graph.Edge("b", "d", 15),
new Graph.Edge("c", "d", 11),
new Graph.Edge("c", "f", 2),
new Graph.Edge("d", "e", 6),
new Graph.Edge("e", "f", 9),
};
private static final String START = "a";
private static final String END = "e";
/**
* main function
* Will run the code with "GRAPH" that was defined above.
*/
public static void main(String[] args) {
Graph g = new Graph(GRAPH);
g.dijkstra(START);
g.printPath(END);
//g.printAllPaths();
}
} }
class Graph { class Graph {
private final Map<String, Vertex> graph; // mapping of vertex names to Vertex objects, built from a set of Edges // mapping of vertex names to Vertex objects, built from a set of Edges
private final Map<String, Vertex> graph;
/** One edge of the graph (only used by Graph constructor) */
public static class Edge { /** One edge of the graph (only used by Graph constructor) */
public final String v1, v2; public static class Edge {
public final int dist; public final String v1, v2;
public Edge(String v1, String v2, int dist) { public final int dist;
this.v1 = v1;
this.v2 = v2; public Edge(String v1, String v2, int dist) {
this.dist = dist; this.v1 = v1;
} this.v2 = v2;
} this.dist = dist;
}
/** One vertex of the graph, complete with mappings to neighbouring vertices */ }
public static class Vertex implements Comparable<Vertex> {
public final String name; /** One vertex of the graph, complete with mappings to neighbouring vertices */
public int dist = Integer.MAX_VALUE; // MAX_VALUE assumed to be infinity public static class Vertex implements Comparable<Vertex> {
public Vertex previous = null; public final String name;
public final Map<Vertex, Integer> neighbours = new HashMap<>(); // MAX_VALUE assumed to be infinity
public int dist = Integer.MAX_VALUE;
public Vertex(String name) { public Vertex previous = null;
this.name = name; public final Map<Vertex, Integer> neighbours = new HashMap<>();
}
public Vertex(String name) {
private void printPath() { this.name = name;
if (this == this.previous) { }
System.out.printf("%s", this.name);
} private void printPath() {
else if (this.previous == null) { if (this == this.previous) {
System.out.printf("%s(unreached)", this.name); System.out.printf("%s", this.name);
} } else if (this.previous == null) {
else { System.out.printf("%s(unreached)", this.name);
this.previous.printPath(); } else {
System.out.printf(" -> %s(%d)", this.name, this.dist); this.previous.printPath();
} System.out.printf(" -> %s(%d)", this.name, this.dist);
} }
}
public int compareTo(Vertex other) {
if (dist == other.dist) public int compareTo(Vertex other) {
return name.compareTo(other.name); if (dist == other.dist)
return name.compareTo(other.name);
return Integer.compare(dist, other.dist);
} return Integer.compare(dist, other.dist);
}
@Override public String toString() {
return "(" + name + ", " + dist + ")"; @Override
} public String toString() {
} return "(" + name + ", " + dist + ")";
}
/** Builds a graph from a set of edges */ }
public Graph(Edge[] edges) {
graph = new HashMap<>(edges.length); /** Builds a graph from a set of edges */
public Graph(Edge[] edges) {
//one pass to find all vertices graph = new HashMap<>(edges.length);
for (Edge e : edges) {
if (!graph.containsKey(e.v1)) graph.put(e.v1, new Vertex(e.v1)); // one pass to find all vertices
if (!graph.containsKey(e.v2)) graph.put(e.v2, new Vertex(e.v2)); for (Edge e : edges) {
} if (!graph.containsKey(e.v1)) graph.put(e.v1, new Vertex(e.v1));
if (!graph.containsKey(e.v2)) graph.put(e.v2, new Vertex(e.v2));
//another pass to set neighbouring vertices }
for (Edge e : edges) {
graph.get(e.v1).neighbours.put(graph.get(e.v2), e.dist); // another pass to set neighbouring vertices
//graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // also do this for an undirected graph for (Edge e : edges) {
} graph.get(e.v1).neighbours.put(graph.get(e.v2), e.dist);
} // graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // also do this for an undirected graph
}
/** Runs dijkstra using a specified source vertex */ }
public void dijkstra(String startName) {
if (!graph.containsKey(startName)) { /** Runs dijkstra using a specified source vertex */
System.err.printf("Graph doesn't contain start vertex \"%s\"\n", startName); public void dijkstra(String startName) {
return; if (!graph.containsKey(startName)) {
} System.err.printf("Graph doesn't contain start vertex \"%s\"\n", startName);
final Vertex source = graph.get(startName); return;
NavigableSet<Vertex> q = new TreeSet<>(); }
final Vertex source = graph.get(startName);
// set-up vertices NavigableSet<Vertex> q = new TreeSet<>();
for (Vertex v : graph.values()) {
v.previous = v == source ? source : null; // set-up vertices
v.dist = v == source ? 0 : Integer.MAX_VALUE; for (Vertex v : graph.values()) {
q.add(v); v.previous = v == source ? source : null;
} v.dist = v == source ? 0 : Integer.MAX_VALUE;
q.add(v);
dijkstra(q); }
}
dijkstra(q);
/** Implementation of dijkstra's algorithm using a binary heap. */ }
private void dijkstra(final NavigableSet<Vertex> q) {
Vertex u, v; /** Implementation of dijkstra's algorithm using a binary heap. */
while (!q.isEmpty()) { private void dijkstra(final NavigableSet<Vertex> q) {
Vertex u, v;
u = q.pollFirst(); // vertex with shortest distance (first iteration will return source) while (!q.isEmpty()) {
if (u.dist == Integer.MAX_VALUE) break; // we can ignore u (and any other remaining vertices) since they are unreachable // vertex with shortest distance (first iteration will return source)
u = q.pollFirst();
//look at distances to each neighbour if (u.dist == Integer.MAX_VALUE)
for (Map.Entry<Vertex, Integer> a : u.neighbours.entrySet()) { break; // we can ignore u (and any other remaining vertices) since they are unreachable
v = a.getKey(); //the neighbour in this iteration
// look at distances to each neighbour
final int alternateDist = u.dist + a.getValue(); for (Map.Entry<Vertex, Integer> a : u.neighbours.entrySet()) {
if (alternateDist < v.dist) { // shorter path to neighbour found v = a.getKey(); // the neighbour in this iteration
q.remove(v);
v.dist = alternateDist; final int alternateDist = u.dist + a.getValue();
v.previous = u; if (alternateDist < v.dist) { // shorter path to neighbour found
q.add(v); q.remove(v);
} v.dist = alternateDist;
} v.previous = u;
} q.add(v);
} }
}
/** Prints a path from the source to the specified vertex */ }
public void printPath(String endName) { }
if (!graph.containsKey(endName)) {
System.err.printf("Graph doesn't contain end vertex \"%s\"\n", endName); /** Prints a path from the source to the specified vertex */
return; public void printPath(String endName) {
} if (!graph.containsKey(endName)) {
System.err.printf("Graph doesn't contain end vertex \"%s\"\n", endName);
graph.get(endName).printPath(); return;
System.out.println(); }
}
/** Prints the path from the source to every vertex (output order is not guaranteed) */ graph.get(endName).printPath();
public void printAllPaths() { System.out.println();
for (Vertex v : graph.values()) { }
v.printPath();
System.out.println(); /** Prints the path from the source to every vertex (output order is not guaranteed) */
} public void printAllPaths() {
} for (Vertex v : graph.values()) {
} v.printPath();
System.out.println();
}
}
}