mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-26 14:04:17 +08:00
@ -9,7 +9,7 @@ public class CircularBuffer<Item> {
|
||||
private final AtomicInteger size = new AtomicInteger(0);
|
||||
|
||||
public CircularBuffer(int size) {
|
||||
//noinspection unchecked
|
||||
// noinspection unchecked
|
||||
this.buffer = (Item[]) new Object[size];
|
||||
this.putPointer = new CircularPointer(0, size);
|
||||
this.getPointer = new CircularPointer(0, size);
|
||||
@ -24,8 +24,7 @@ public class CircularBuffer<Item> {
|
||||
}
|
||||
|
||||
public Item get() {
|
||||
if (isEmpty())
|
||||
return null;
|
||||
if (isEmpty()) return null;
|
||||
|
||||
Item item = buffer[getPointer.getAndIncrement()];
|
||||
size.decrementAndGet();
|
||||
@ -33,8 +32,7 @@ public class CircularBuffer<Item> {
|
||||
}
|
||||
|
||||
public boolean put(Item item) {
|
||||
if (isFull())
|
||||
return false;
|
||||
if (isFull()) return false;
|
||||
|
||||
buffer[putPointer.getAndIncrement()] = item;
|
||||
size.incrementAndGet();
|
||||
@ -51,8 +49,7 @@ public class CircularBuffer<Item> {
|
||||
}
|
||||
|
||||
public int getAndIncrement() {
|
||||
if (pointer == max)
|
||||
pointer = 0;
|
||||
if (pointer == max) pointer = 0;
|
||||
int tmp = pointer;
|
||||
pointer++;
|
||||
return tmp;
|
||||
|
@ -43,7 +43,8 @@ public class LFUCache<K, V> {
|
||||
* This method returns value present in the cache corresponding to the key passed as parameter
|
||||
*
|
||||
* @param <K> key for which value is to be retrieved
|
||||
* @returns <V> object corresponding to the key passed as parameter, returns null if <K> key is not present in the cache
|
||||
* @returns <V> object corresponding to the key passed as parameter, returns null if <K> key is
|
||||
* not present in the cache
|
||||
*/
|
||||
public V get(K key) {
|
||||
if (this.map.get(key) == null) {
|
||||
|
@ -126,14 +126,10 @@ public class LRUCache<K, V> {
|
||||
private I key;
|
||||
private J value;
|
||||
|
||||
public Entry() {}
|
||||
public Entry() {
|
||||
}
|
||||
|
||||
public Entry(
|
||||
Entry<I, J> preEntry,
|
||||
Entry<I, J> nextEntry,
|
||||
I key,
|
||||
J value
|
||||
) {
|
||||
public Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) {
|
||||
this.preEntry = preEntry;
|
||||
this.nextEntry = nextEntry;
|
||||
this.key = key;
|
||||
|
@ -124,14 +124,10 @@ public class MRUCache<K, V> {
|
||||
private I key;
|
||||
private J value;
|
||||
|
||||
public Entry() {}
|
||||
public Entry() {
|
||||
}
|
||||
|
||||
public Entry(
|
||||
Entry<I, J> preEntry,
|
||||
Entry<I, J> nextEntry,
|
||||
I key,
|
||||
J value
|
||||
) {
|
||||
public Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) {
|
||||
this.preEntry = preEntry;
|
||||
this.nextEntry = nextEntry;
|
||||
this.key = key;
|
||||
|
@ -44,8 +44,7 @@ public class DynamicArray<E> implements Iterable<E> {
|
||||
*/
|
||||
public void add(final E element) {
|
||||
if (this.size == this.elements.length) {
|
||||
this.elements =
|
||||
Arrays.copyOf(this.elements, newCapacity(2 * this.capacity));
|
||||
this.elements = Arrays.copyOf(this.elements, newCapacity(2 * this.capacity));
|
||||
}
|
||||
|
||||
this.elements[this.size] = element;
|
||||
@ -84,8 +83,7 @@ public class DynamicArray<E> implements Iterable<E> {
|
||||
fastRemove(this.elements, index);
|
||||
|
||||
if (this.capacity > DEFAULT_CAPACITY && size * 4 <= this.capacity) {
|
||||
this.elements =
|
||||
Arrays.copyOf(this.elements, newCapacity(this.capacity / 2));
|
||||
this.elements = Arrays.copyOf(this.elements, newCapacity(this.capacity / 2));
|
||||
}
|
||||
return oldElement;
|
||||
}
|
||||
@ -116,13 +114,7 @@ public class DynamicArray<E> implements Iterable<E> {
|
||||
final int newSize = this.size - 1;
|
||||
|
||||
if (newSize > index) {
|
||||
System.arraycopy(
|
||||
elements,
|
||||
index + 1,
|
||||
elements,
|
||||
index,
|
||||
newSize - index
|
||||
);
|
||||
System.arraycopy(elements, index + 1, elements, index, newSize - index);
|
||||
}
|
||||
|
||||
elements[this.size = newSize] = null;
|
||||
@ -144,9 +136,7 @@ public class DynamicArray<E> implements Iterable<E> {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Arrays.toString(
|
||||
Arrays.stream(this.elements).filter(Objects::nonNull).toArray()
|
||||
);
|
||||
return Arrays.toString(Arrays.stream(this.elements).filter(Objects::nonNull).toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Time Complexity = O(E), where E is equal to the number of edges
|
||||
Time Complexity = O(E), where E is equal to the number of edges
|
||||
*/
|
||||
package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
@ -64,13 +64,10 @@ public class A_Star {
|
||||
|
||||
private int distance; // distance advanced so far.
|
||||
private ArrayList<Integer> path; // list of visited nodes in this path.
|
||||
private int estimated; // heuristic value associated to the last node od the path (current node).
|
||||
private int
|
||||
estimated; // heuristic value associated to the last node od the path (current node).
|
||||
|
||||
public PathAndDistance(
|
||||
int distance,
|
||||
ArrayList<Integer> path,
|
||||
int estimated
|
||||
) {
|
||||
public PathAndDistance(int distance, ArrayList<Integer> path, int estimated) {
|
||||
this.distance = distance;
|
||||
this.path = path;
|
||||
this.estimated = estimated;
|
||||
@ -90,25 +87,16 @@ public class A_Star {
|
||||
|
||||
private void printSolution() {
|
||||
if (this.path != null) {
|
||||
System.out.println(
|
||||
"Optimal path: " +
|
||||
this.path +
|
||||
", distance: " +
|
||||
this.distance
|
||||
);
|
||||
System.out.println("Optimal path: " + this.path + ", distance: " + this.distance);
|
||||
} else {
|
||||
System.out.println(
|
||||
"There is no path available to connect the points"
|
||||
);
|
||||
System.out.println("There is no path available to connect the points");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void initializeGraph(Graph graph, ArrayList<Integer> data) {
|
||||
for (int i = 0; i < data.size(); i += 4) {
|
||||
graph.addEdge(
|
||||
new Edge(data.get(i), data.get(i + 1), data.get(i + 2))
|
||||
);
|
||||
graph.addEdge(new Edge(data.get(i), data.get(i + 1), data.get(i + 2)));
|
||||
}
|
||||
/*
|
||||
.x. node
|
||||
@ -165,123 +153,24 @@ public class A_Star {
|
||||
};
|
||||
|
||||
Graph graph = new Graph(20);
|
||||
ArrayList<Integer> graphData = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
0,
|
||||
19,
|
||||
75,
|
||||
null,
|
||||
0,
|
||||
15,
|
||||
140,
|
||||
null,
|
||||
0,
|
||||
16,
|
||||
118,
|
||||
null,
|
||||
19,
|
||||
12,
|
||||
71,
|
||||
null,
|
||||
12,
|
||||
15,
|
||||
151,
|
||||
null,
|
||||
16,
|
||||
9,
|
||||
111,
|
||||
null,
|
||||
9,
|
||||
10,
|
||||
70,
|
||||
null,
|
||||
10,
|
||||
3,
|
||||
75,
|
||||
null,
|
||||
3,
|
||||
2,
|
||||
120,
|
||||
null,
|
||||
2,
|
||||
14,
|
||||
146,
|
||||
null,
|
||||
2,
|
||||
13,
|
||||
138,
|
||||
null,
|
||||
2,
|
||||
6,
|
||||
115,
|
||||
null,
|
||||
15,
|
||||
14,
|
||||
80,
|
||||
null,
|
||||
15,
|
||||
5,
|
||||
99,
|
||||
null,
|
||||
14,
|
||||
13,
|
||||
97,
|
||||
null,
|
||||
5,
|
||||
1,
|
||||
211,
|
||||
null,
|
||||
13,
|
||||
1,
|
||||
101,
|
||||
null,
|
||||
6,
|
||||
1,
|
||||
160,
|
||||
null,
|
||||
1,
|
||||
17,
|
||||
85,
|
||||
null,
|
||||
17,
|
||||
7,
|
||||
98,
|
||||
null,
|
||||
7,
|
||||
4,
|
||||
86,
|
||||
null,
|
||||
17,
|
||||
18,
|
||||
142,
|
||||
null,
|
||||
18,
|
||||
8,
|
||||
92,
|
||||
null,
|
||||
8,
|
||||
11,
|
||||
87
|
||||
)
|
||||
);
|
||||
ArrayList<Integer> graphData = new ArrayList<>(Arrays.asList(0, 19, 75, null, 0, 15, 140,
|
||||
null, 0, 16, 118, null, 19, 12, 71, null, 12, 15, 151, null, 16, 9, 111, null, 9, 10,
|
||||
70, null, 10, 3, 75, null, 3, 2, 120, null, 2, 14, 146, null, 2, 13, 138, null, 2, 6,
|
||||
115, null, 15, 14, 80, null, 15, 5, 99, null, 14, 13, 97, null, 5, 1, 211, null, 13, 1,
|
||||
101, null, 6, 1, 160, null, 1, 17, 85, null, 17, 7, 98, null, 7, 4, 86, null, 17, 18,
|
||||
142, null, 18, 8, 92, null, 8, 11, 87));
|
||||
initializeGraph(graph, graphData);
|
||||
|
||||
PathAndDistance solution = aStar(3, 1, graph, heuristic);
|
||||
solution.printSolution();
|
||||
}
|
||||
|
||||
public static PathAndDistance aStar(
|
||||
int from,
|
||||
int to,
|
||||
Graph graph,
|
||||
int[] heuristic
|
||||
) {
|
||||
public static PathAndDistance aStar(int from, int to, Graph graph, int[] heuristic) {
|
||||
// nodes are prioritised by the less value of the current distance of their paths, and the
|
||||
// estimated value
|
||||
// given by the heuristic function to reach the destination point from the current point.
|
||||
PriorityQueue<PathAndDistance> queue = new PriorityQueue<>(
|
||||
Comparator.comparingInt(a -> (a.getDistance() + a.getEstimated()))
|
||||
);
|
||||
Comparator.comparingInt(a -> (a.getDistance() + a.getEstimated())));
|
||||
|
||||
// dummy data to start the algorithm from the beginning point
|
||||
queue.add(new PathAndDistance(0, new ArrayList<>(List.of(from)), 0));
|
||||
@ -290,34 +179,25 @@ public class A_Star {
|
||||
PathAndDistance currentData = new PathAndDistance(-1, null, -1);
|
||||
while (!queue.isEmpty() && !solutionFound) {
|
||||
currentData = queue.poll(); // first in the queue, best node so keep exploring.
|
||||
int currentPosition = currentData
|
||||
.getPath()
|
||||
.get(currentData.getPath().size() - 1); // current node.
|
||||
int currentPosition
|
||||
= currentData.getPath().get(currentData.getPath().size() - 1); // current node.
|
||||
if (currentPosition == to) {
|
||||
solutionFound = true;
|
||||
} else {
|
||||
for (Edge edge : graph.getNeighbours(currentPosition)) {
|
||||
if (!currentData.getPath().contains(edge.getTo())) { // Avoid Cycles
|
||||
ArrayList<Integer> updatedPath = new ArrayList<>(
|
||||
currentData.getPath()
|
||||
);
|
||||
updatedPath.add(edge.getTo()); // Add the new node to the path, update the distance,
|
||||
ArrayList<Integer> updatedPath = new ArrayList<>(currentData.getPath());
|
||||
updatedPath.add(
|
||||
edge.getTo()); // Add the new node to the path, update the distance,
|
||||
// and the heuristic function value associated to that path.
|
||||
queue.add(
|
||||
new PathAndDistance(
|
||||
currentData.getDistance() + edge.getWeight(),
|
||||
updatedPath,
|
||||
heuristic[edge.getTo()]
|
||||
)
|
||||
);
|
||||
queue.add(new PathAndDistance(currentData.getDistance() + edge.getWeight(),
|
||||
updatedPath, heuristic[edge.getTo()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (solutionFound)
|
||||
? currentData
|
||||
: new PathAndDistance(-1, null, -1);
|
||||
// Out of while loop, if there is a solution, the current Data stores the optimal path, and its
|
||||
// distance
|
||||
return (solutionFound) ? currentData : new PathAndDistance(-1, null, -1);
|
||||
// Out of while loop, if there is a solution, the current Data stores the optimal path, and
|
||||
// its distance
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class BellmanFord /*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs in form of edges which have
|
||||
start vertex, end vertex and weights. Vertices should be labelled with a number between 0 and total number of vertices-1,both inclusive*/{
|
||||
class BellmanFord /*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs
|
||||
in form of edges which have start vertex, end vertex and weights. Vertices should be labelled with a
|
||||
number between 0 and total number of vertices-1,both inclusive*/
|
||||
{
|
||||
|
||||
int vertex, edge;
|
||||
private Edge[] edges;
|
||||
@ -49,7 +51,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
obj.go();
|
||||
}
|
||||
|
||||
public void go() { // shows distance to all vertices // Interactive run for understanding the class first time. Assumes source vertex is 0 and
|
||||
public void go() { // shows distance to all vertices // Interactive run for understanding the
|
||||
// class first time. Assumes source vertex is 0 and
|
||||
Scanner sc = new Scanner(System.in); // Grab scanner object for user input
|
||||
int i, v, e, u, ve, w, j, neg = 0;
|
||||
System.out.println("Enter no. of vertices and edges please");
|
||||
@ -63,7 +66,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
w = sc.nextInt();
|
||||
arr[i] = new Edge(u, ve, w);
|
||||
}
|
||||
int[] dist = new int[v]; // Distance array for holding the finalized shortest path distance between source
|
||||
int[] dist = new int[v]; // Distance array for holding the finalized shortest path distance
|
||||
// between source
|
||||
// and all vertices
|
||||
int[] p = new int[v]; // Parent array for holding the paths
|
||||
for (i = 0; i < v; i++) {
|
||||
@ -73,10 +77,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
p[0] = -1;
|
||||
for (i = 0; i < v - 1; i++) {
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if (dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
|
||||
p[arr[j].v] = arr[j].u;
|
||||
}
|
||||
@ -84,10 +86,7 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
}
|
||||
// Final cycle for negative checking
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if (dist[arr[j].u] != Integer.MAX_VALUE && dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
neg = 1;
|
||||
System.out.println("Negative cycle");
|
||||
break;
|
||||
@ -113,9 +112,13 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
* @param end Ending vertex
|
||||
* @param Edge Array of edges
|
||||
*/
|
||||
public void show(int source, int end, Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray() method // Just shows results of computation, if graph is passed to it. The graph should
|
||||
public void show(int source, int end,
|
||||
Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray()
|
||||
// method // Just shows results of computation, if graph is passed to it. The
|
||||
// graph should
|
||||
int i, j, v = vertex, e = edge, neg = 0;
|
||||
double[] dist = new double[v]; // Distance array for holding the finalized shortest path distance between source
|
||||
double[] dist = new double[v]; // Distance array for holding the finalized shortest path
|
||||
// distance between source
|
||||
// and all vertices
|
||||
int[] p = new int[v]; // Parent array for holding the paths
|
||||
for (i = 0; i < v; i++) {
|
||||
@ -125,10 +128,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
p[source] = -1;
|
||||
for (i = 0; i < v - 1; i++) {
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
(int) dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if ((int) dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
|
||||
p[arr[j].v] = arr[j].u;
|
||||
}
|
||||
@ -136,10 +137,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
}
|
||||
// Final cycle for negative checking
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
(int) dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if ((int) dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
neg = 1;
|
||||
System.out.println("Negative cycle");
|
||||
break;
|
||||
|
@ -17,11 +17,7 @@ import java.util.Arrays;
|
||||
public class BipartiteGrapfDFS {
|
||||
|
||||
private static boolean bipartite(
|
||||
int V,
|
||||
ArrayList<ArrayList<Integer>> adj,
|
||||
int[] color,
|
||||
int node
|
||||
) {
|
||||
int V, ArrayList<ArrayList<Integer>> adj, int[] color, int node) {
|
||||
if (color[node] == -1) {
|
||||
color[node] = 1;
|
||||
}
|
||||
@ -38,10 +34,7 @@ public class BipartiteGrapfDFS {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isBipartite(
|
||||
int V,
|
||||
ArrayList<ArrayList<Integer>> adj
|
||||
) {
|
||||
public static boolean isBipartite(int V, ArrayList<ArrayList<Integer>> adj) {
|
||||
// Code here
|
||||
int[] color = new int[V + 1];
|
||||
Arrays.fill(color, -1);
|
||||
@ -57,9 +50,7 @@ public class BipartiteGrapfDFS {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
BufferedReader read = new BufferedReader(
|
||||
new InputStreamReader(System.in)
|
||||
);
|
||||
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
|
||||
int t = Integer.parseInt(read.readLine().trim());
|
||||
while (t-- > 0) {
|
||||
String[] S = read.readLine().trim().split(" ");
|
||||
|
@ -137,11 +137,7 @@ public class ConnectedComponent {
|
||||
graphInts.addEdge(8, 10);
|
||||
graphInts.addEdge(10, 8);
|
||||
|
||||
System.out.println(
|
||||
"Amount of different char-graphs: " + graphChars.countGraphs()
|
||||
);
|
||||
System.out.println(
|
||||
"Amount of different int-graphs: " + graphInts.countGraphs()
|
||||
);
|
||||
System.out.println("Amount of different char-graphs: " + graphChars.countGraphs());
|
||||
System.out.println("Amount of different int-graphs: " + graphInts.countGraphs());
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,7 @@ class Cycle {
|
||||
visited[i] = false;
|
||||
}
|
||||
|
||||
System.out.println(
|
||||
"Enter the details of each edges <Start Node> <End Node>"
|
||||
);
|
||||
System.out.println("Enter the details of each edges <Start Node> <End Node>");
|
||||
|
||||
for (int i = 0; i < edges; i++) {
|
||||
int start, end;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Refer https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/
|
||||
for better understanding
|
||||
for better understanding
|
||||
*/
|
||||
package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
@ -45,12 +45,8 @@ class dijkstras {
|
||||
Set[u] = true;
|
||||
|
||||
for (int v = 0; v < k; v++) {
|
||||
if (
|
||||
!Set[v] &&
|
||||
graph[u][v] != 0 &&
|
||||
dist[u] != Integer.MAX_VALUE &&
|
||||
dist[u] + graph[u][v] < dist[v]
|
||||
) {
|
||||
if (!Set[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE
|
||||
&& dist[u] + graph[u][v] < dist[v]) {
|
||||
dist[v] = dist[u] + graph[u][v];
|
||||
}
|
||||
}
|
||||
@ -61,23 +57,23 @@ class dijkstras {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[][] graph = new int[][] {
|
||||
{ 0, 4, 0, 0, 0, 0, 0, 8, 0 },
|
||||
{ 4, 0, 8, 0, 0, 0, 0, 11, 0 },
|
||||
{ 0, 8, 0, 7, 0, 4, 0, 0, 2 },
|
||||
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
|
||||
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
|
||||
{ 0, 0, 4, 14, 10, 0, 2, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 2, 0, 1, 6 },
|
||||
{ 8, 11, 0, 0, 0, 0, 1, 0, 7 },
|
||||
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 },
|
||||
{0, 4, 0, 0, 0, 0, 0, 8, 0},
|
||||
{4, 0, 8, 0, 0, 0, 0, 11, 0},
|
||||
{0, 8, 0, 7, 0, 4, 0, 0, 2},
|
||||
{0, 0, 7, 0, 9, 14, 0, 0, 0},
|
||||
{0, 0, 0, 9, 0, 10, 0, 0, 0},
|
||||
{0, 0, 4, 14, 10, 0, 2, 0, 0},
|
||||
{0, 0, 0, 0, 0, 2, 0, 1, 6},
|
||||
{8, 11, 0, 0, 0, 0, 1, 0, 7},
|
||||
{0, 0, 2, 0, 0, 0, 6, 7, 0},
|
||||
};
|
||||
dijkstras t = new dijkstras();
|
||||
t.dijkstra(graph, 0);
|
||||
} //main
|
||||
} //djikstras
|
||||
} // main
|
||||
} // djikstras
|
||||
/*
|
||||
OUTPUT :
|
||||
Vertex Distance
|
||||
Vertex Distance
|
||||
0 0
|
||||
1 4
|
||||
2 12
|
||||
|
@ -9,42 +9,32 @@ public class FloydWarshall {
|
||||
public static final int INFINITY = 999;
|
||||
|
||||
public FloydWarshall(int numberofvertices) {
|
||||
DistanceMatrix = new int[numberofvertices + 1][numberofvertices + 1]; // stores the value of distance from all the possible path form the source
|
||||
DistanceMatrix = new int[numberofvertices + 1][numberofvertices
|
||||
+ 1]; // stores the value of distance from all the possible path form the source
|
||||
// vertex to destination vertex
|
||||
// The matrix is initialized with 0's by default
|
||||
this.numberofvertices = numberofvertices;
|
||||
}
|
||||
|
||||
public void floydwarshall(int[][] AdjacencyMatrix) { // calculates all the distances from source to destination vertex
|
||||
public void floydwarshall(
|
||||
int[][] AdjacencyMatrix) { // calculates all the distances from source to destination vertex
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
DistanceMatrix[source][destination] =
|
||||
AdjacencyMatrix[source][destination];
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
DistanceMatrix[source][destination] = AdjacencyMatrix[source][destination];
|
||||
}
|
||||
}
|
||||
for (
|
||||
int intermediate = 1;
|
||||
intermediate <= numberofvertices;
|
||||
intermediate++
|
||||
) {
|
||||
for (int intermediate = 1; intermediate <= numberofvertices; intermediate++) {
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
if (
|
||||
DistanceMatrix[source][intermediate] +
|
||||
DistanceMatrix[intermediate][destination] <
|
||||
DistanceMatrix[source][destination]
|
||||
) { // calculated distance it get replaced as new shortest distance // if the new distance calculated is less then the earlier shortest
|
||||
DistanceMatrix[source][destination] =
|
||||
DistanceMatrix[source][intermediate] +
|
||||
DistanceMatrix[intermediate][destination];
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
if (DistanceMatrix[source][intermediate]
|
||||
+ DistanceMatrix[intermediate][destination]
|
||||
< DistanceMatrix[source]
|
||||
[destination]) { // calculated distance it get replaced as
|
||||
// new shortest distance // if the new
|
||||
// distance calculated is less then the
|
||||
// earlier shortest
|
||||
DistanceMatrix[source][destination] = DistanceMatrix[source][intermediate]
|
||||
+ DistanceMatrix[intermediate][destination];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -55,11 +45,7 @@ public class FloydWarshall {
|
||||
System.out.println();
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
System.out.print(source + "\t");
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
System.out.print(DistanceMatrix[source][destination] + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
@ -70,15 +56,10 @@ public class FloydWarshall {
|
||||
Scanner scan = new Scanner(System.in);
|
||||
System.out.println("Enter the number of vertices");
|
||||
int numberOfVertices = scan.nextInt();
|
||||
int[][] adjacencyMatrix = new int[numberOfVertices +
|
||||
1][numberOfVertices + 1];
|
||||
int[][] adjacencyMatrix = new int[numberOfVertices + 1][numberOfVertices + 1];
|
||||
System.out.println("Enter the Weighted Matrix for the graph");
|
||||
for (int source = 1; source <= numberOfVertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberOfVertices;
|
||||
destination++
|
||||
) {
|
||||
for (int destination = 1; destination <= numberOfVertices; destination++) {
|
||||
adjacencyMatrix[source][destination] = scan.nextInt();
|
||||
if (source == destination) {
|
||||
adjacencyMatrix[source][destination] = 0;
|
||||
|
@ -21,7 +21,7 @@ public class HamiltonianCycle {
|
||||
this.V = graph.length;
|
||||
this.cycle = new int[this.V + 1];
|
||||
|
||||
//Initialize path array with -1 value
|
||||
// Initialize path array with -1 value
|
||||
for (int i = 0; i < this.cycle.length; i++) {
|
||||
this.cycle[i] = -1;
|
||||
}
|
||||
@ -41,13 +41,15 @@ public class HamiltonianCycle {
|
||||
return cycle;
|
||||
}
|
||||
|
||||
/** function to find paths recursively
|
||||
/**
|
||||
* function to find paths recursively
|
||||
* Find paths recursively from given vertex
|
||||
* @param vertex Vertex from which path is to be found
|
||||
* @returns true if path is found false otherwise
|
||||
*/
|
||||
public boolean isPathFound(int vertex) {
|
||||
boolean isLastVertexConnectedToStart = this.graph[vertex][0] == 1 && this.pathCount == this.V;
|
||||
boolean isLastVertexConnectedToStart
|
||||
= this.graph[vertex][0] == 1 && this.pathCount == this.V;
|
||||
if (isLastVertexConnectedToStart) {
|
||||
return true;
|
||||
}
|
||||
@ -83,7 +85,8 @@ public class HamiltonianCycle {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** function to check if path is already selected
|
||||
/**
|
||||
* function to check if path is already selected
|
||||
* Check if path is already selected
|
||||
* @param vertex Starting vertex
|
||||
*/
|
||||
|
@ -133,7 +133,7 @@ class TopologicalSort<E extends Comparable<E>> {
|
||||
public class KahnsAlgorithm {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//Graph definition and initialization
|
||||
// Graph definition and initialization
|
||||
AdjacencyList<String> graph = new AdjacencyList<>();
|
||||
graph.addEdge("a", "b");
|
||||
graph.addEdge("c", "a");
|
||||
@ -144,7 +144,7 @@ public class KahnsAlgorithm {
|
||||
|
||||
TopologicalSort<String> topSort = new TopologicalSort<>(graph);
|
||||
|
||||
//Printing the order
|
||||
// Printing the order
|
||||
for (String s : topSort.topSortOrder()) {
|
||||
System.out.print(s + " ");
|
||||
}
|
||||
|
@ -7,17 +7,18 @@ import java.util.Stack;
|
||||
/**
|
||||
* Java program that implements Kosaraju Algorithm.
|
||||
* @author Shivanagouda S A (https://github.com/shivu2002a)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Kosaraju algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred by SCC. It leverages the fact that the transpose
|
||||
graph (same graph with all the edges reversed) has exactly the same SCCs as the original graph.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly connected.
|
||||
Single node is always a SCC.
|
||||
* Kosaraju algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred by SCC. It leverages the fact that the
|
||||
transpose graph (same graph with all the edges reversed) has exactly the same SCCs as the original
|
||||
graph.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly
|
||||
connected. Single node is always a SCC.
|
||||
|
||||
* Example:
|
||||
|
||||
@ -26,19 +27,20 @@ import java.util.Stack;
|
||||
| / | \ /
|
||||
| / | \ /
|
||||
v / v \ /
|
||||
1 5 --> 6
|
||||
1 5 --> 6
|
||||
|
||||
For the above graph, the SCC list goes as follows:
|
||||
0, 1, 2
|
||||
0, 1, 2
|
||||
3
|
||||
4, 5, 6
|
||||
7
|
||||
|
||||
|
||||
We can also see that order of the nodes in an SCC doesn't matter since they are in cycle.
|
||||
|
||||
{@summary}
|
||||
* Kosaraju Algorithm:
|
||||
1. Perform DFS traversal of the graph. Push node to stack before returning. This gives edges sorted by lowest finish time.
|
||||
* Kosaraju Algorithm:
|
||||
1. Perform DFS traversal of the graph. Push node to stack before returning. This gives edges
|
||||
sorted by lowest finish time.
|
||||
2. Find the transpose graph by reversing the edges.
|
||||
3. Pop nodes one by one from the stack and again to DFS on the modified graph.
|
||||
|
||||
@ -48,7 +50,7 @@ import java.util.Stack;
|
||||
| / | \ /
|
||||
| / | \ /
|
||||
| v | v v
|
||||
1 5 <--- 6
|
||||
1 5 <--- 6
|
||||
|
||||
We can observe that this graph has the same SCC as that of original graph.
|
||||
|
||||
@ -59,33 +61,33 @@ public class Kosaraju {
|
||||
// Sort edges according to lowest finish time
|
||||
Stack<Integer> stack = new Stack<Integer>();
|
||||
|
||||
//Store each component
|
||||
// Store each component
|
||||
private List<Integer> scc = new ArrayList<>();
|
||||
|
||||
//All the strongly connected components
|
||||
// All the strongly connected components
|
||||
private List<List<Integer>> sccsList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param v Node count
|
||||
* @param list Adjacency list of graph
|
||||
* @return List of SCCs
|
||||
*/
|
||||
public List<List<Integer>> kosaraju(int v, List<List<Integer>> list){
|
||||
|
||||
public List<List<Integer>> kosaraju(int v, List<List<Integer>> list) {
|
||||
|
||||
sortEdgesByLowestFinishTime(v, list);
|
||||
|
||||
|
||||
List<List<Integer>> transposeGraph = createTransposeMatrix(v, list);
|
||||
|
||||
findStronglyConnectedComponents(v, transposeGraph);
|
||||
|
||||
|
||||
return sccsList;
|
||||
}
|
||||
|
||||
private void sortEdgesByLowestFinishTime(int v, List<List<Integer>> list){
|
||||
private void sortEdgesByLowestFinishTime(int v, List<List<Integer>> list) {
|
||||
int[] vis = new int[v];
|
||||
for (int i = 0; i < v; i++) {
|
||||
if(vis[i] == 0){
|
||||
if (vis[i] == 0) {
|
||||
dfs(i, vis, list);
|
||||
}
|
||||
}
|
||||
@ -105,15 +107,15 @@ public class Kosaraju {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param v Node count
|
||||
* @param transposeGraph Transpose of the given adjacency list
|
||||
*/
|
||||
public void findStronglyConnectedComponents(int v, List<List<Integer>> transposeGraph){
|
||||
public void findStronglyConnectedComponents(int v, List<List<Integer>> transposeGraph) {
|
||||
int[] vis = new int[v];
|
||||
while (!stack.isEmpty()) {
|
||||
var node = stack.pop();
|
||||
if(vis[node] == 0){
|
||||
if (vis[node] == 0) {
|
||||
dfs2(node, vis, transposeGraph);
|
||||
sccsList.add(scc);
|
||||
scc = new ArrayList<>();
|
||||
@ -121,24 +123,21 @@ public class Kosaraju {
|
||||
}
|
||||
}
|
||||
|
||||
//Dfs to store the nodes in order of lowest finish time
|
||||
private void dfs(int node, int[] vis, List<List<Integer>> list){
|
||||
// Dfs to store the nodes in order of lowest finish time
|
||||
private void dfs(int node, int[] vis, List<List<Integer>> list) {
|
||||
vis[node] = 1;
|
||||
for(Integer neighbour : list.get(node)){
|
||||
if(vis[neighbour] == 0)
|
||||
dfs(neighbour, vis, list);
|
||||
for (Integer neighbour : list.get(node)) {
|
||||
if (vis[neighbour] == 0) dfs(neighbour, vis, list);
|
||||
}
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
//Dfs to find all the nodes of each strongly connected component
|
||||
private void dfs2(int node, int[] vis, List<List<Integer>> list){
|
||||
// Dfs to find all the nodes of each strongly connected component
|
||||
private void dfs2(int node, int[] vis, List<List<Integer>> list) {
|
||||
vis[node] = 1;
|
||||
for(Integer neighbour : list.get(node)){
|
||||
if(vis[neighbour] == 0)
|
||||
dfs2(neighbour, vis, list);
|
||||
for (Integer neighbour : list.get(node)) {
|
||||
if (vis[neighbour] == 0) dfs2(neighbour, vis, list);
|
||||
}
|
||||
scc.add(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ import java.util.PriorityQueue;
|
||||
|
||||
public class Kruskal {
|
||||
|
||||
// Complexity: O(E log V) time, where E is the number of edges in the graph and V is the number of
|
||||
// vertices
|
||||
// Complexity: O(E log V) time, where E is the number of edges in the graph and V is the number
|
||||
// of vertices
|
||||
private static class Edge {
|
||||
|
||||
private int from;
|
||||
@ -30,12 +30,7 @@ public class Kruskal {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addEdge(
|
||||
HashSet<Edge>[] graph,
|
||||
int from,
|
||||
int to,
|
||||
int weight
|
||||
) {
|
||||
private static void addEdge(HashSet<Edge>[] graph, int from, int to, int weight) {
|
||||
graph[from].add(new Edge(from, to, weight));
|
||||
}
|
||||
|
||||
@ -58,9 +53,7 @@ public class Kruskal {
|
||||
System.out.println("Initial Graph: ");
|
||||
for (int i = 0; i < graph.length; i++) {
|
||||
for (Edge edge : graph[i]) {
|
||||
System.out.println(
|
||||
i + " <-- weight " + edge.weight + " --> " + edge.to
|
||||
);
|
||||
System.out.println(i + " <-- weight " + edge.weight + " --> " + edge.to);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,9 +63,7 @@ public class Kruskal {
|
||||
System.out.println("\nMinimal Graph: ");
|
||||
for (int i = 0; i < solGraph.length; i++) {
|
||||
for (Edge edge : solGraph[i]) {
|
||||
System.out.println(
|
||||
i + " <-- weight " + edge.weight + " --> " + edge.to
|
||||
);
|
||||
System.out.println(i + " <-- weight " + edge.weight + " --> " + edge.to);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,9 +74,8 @@ public class Kruskal {
|
||||
// captain of i, stores the set with all the connected nodes to i
|
||||
HashSet<Integer>[] connectedGroups = new HashSet[nodes];
|
||||
HashSet<Edge>[] minGraph = new HashSet[nodes];
|
||||
PriorityQueue<Edge> edges = new PriorityQueue<>(
|
||||
(Comparator.comparingInt(edge -> edge.weight))
|
||||
);
|
||||
PriorityQueue<Edge> edges
|
||||
= new PriorityQueue<>((Comparator.comparingInt(edge -> edge.weight)));
|
||||
for (int i = 0; i < nodes; i++) {
|
||||
minGraph[i] = new HashSet<>();
|
||||
connectedGroups[i] = new HashSet<>();
|
||||
@ -98,18 +88,12 @@ public class Kruskal {
|
||||
while (connectedElements != nodes && !edges.isEmpty()) {
|
||||
Edge edge = edges.poll();
|
||||
// This if avoids cycles
|
||||
if (
|
||||
!connectedGroups[captain[edge.from]].contains(edge.to) &&
|
||||
!connectedGroups[captain[edge.to]].contains(edge.from)
|
||||
) {
|
||||
if (!connectedGroups[captain[edge.from]].contains(edge.to)
|
||||
&& !connectedGroups[captain[edge.to]].contains(edge.from)) {
|
||||
// merge sets of the captains of each point connected by the edge
|
||||
connectedGroups[captain[edge.from]].addAll(
|
||||
connectedGroups[captain[edge.to]]
|
||||
);
|
||||
connectedGroups[captain[edge.from]].addAll(connectedGroups[captain[edge.to]]);
|
||||
// update captains of the elements merged
|
||||
connectedGroups[captain[edge.from]].forEach(i ->
|
||||
captain[i] = captain[edge.from]
|
||||
);
|
||||
connectedGroups[captain[edge.from]].forEach(i -> captain[i] = captain[edge.from]);
|
||||
// add Edge to minimal graph
|
||||
addEdge(minGraph, edge.from, edge.to, edge.weight);
|
||||
// count how many elements have been merged
|
||||
|
@ -71,9 +71,7 @@ class AdjacencyMatrixGraph {
|
||||
public AdjacencyMatrixGraph(int givenNumberOfVertices) {
|
||||
this.setNumberOfVertices(givenNumberOfVertices);
|
||||
this.setNumberOfEdges(0);
|
||||
this.setAdjacency(
|
||||
new int[givenNumberOfVertices][givenNumberOfVertices]
|
||||
);
|
||||
this.setAdjacency(new int[givenNumberOfVertices][givenNumberOfVertices]);
|
||||
for (int i = 0; i < givenNumberOfVertices; i++) {
|
||||
for (int j = 0; j < givenNumberOfVertices; j++) {
|
||||
this.adjacency()[i][j] = AdjacencyMatrixGraph.EDGE_NONE;
|
||||
@ -247,11 +245,7 @@ class AdjacencyMatrixGraph {
|
||||
* has been visited
|
||||
* @param orderList the list to add vertices to as they are visited
|
||||
*/
|
||||
private void depthFirstOrder(
|
||||
int currentVertex,
|
||||
boolean[] visited,
|
||||
List<Integer> orderList
|
||||
) {
|
||||
private void depthFirstOrder(int currentVertex, boolean[] visited, List<Integer> orderList) {
|
||||
// If this vertex has already been visited, do nothing and return
|
||||
if (visited[currentVertex]) {
|
||||
return;
|
||||
@ -264,11 +258,9 @@ class AdjacencyMatrixGraph {
|
||||
|
||||
// Get the adjacency array for this vertex
|
||||
int[] adjacent = _adjacency[currentVertex];
|
||||
for (
|
||||
int i = 0;
|
||||
i < adjacent.length;
|
||||
i++
|
||||
) { // we are considering exploring, recurse on it // If an edge exists between the currentVertex and the vertex
|
||||
for (int i = 0; i < adjacent.length;
|
||||
i++) { // we are considering exploring, recurse on it // If an edge exists between the
|
||||
// currentVertex and the vertex
|
||||
if (adjacent[i] == AdjacencyMatrixGraph.EDGE_EXIST) {
|
||||
depthFirstOrder(i, visited, orderList);
|
||||
}
|
||||
@ -317,11 +309,9 @@ class AdjacencyMatrixGraph {
|
||||
// Get the adjacency array for the currentVertex and
|
||||
// check each node
|
||||
int[] adjacent = _adjacency[currentVertex];
|
||||
for (
|
||||
int vertex = 0;
|
||||
vertex < adjacent.length;
|
||||
vertex++
|
||||
) { // vertex we are considering exploring, we add it to the queue // If an edge exists between the current vertex and the
|
||||
for (int vertex = 0; vertex < adjacent.length;
|
||||
vertex++) { // vertex we are considering exploring, we add it to the queue // If an
|
||||
// edge exists between the current vertex and the
|
||||
if (adjacent[vertex] == AdjacencyMatrixGraph.EDGE_EXIST) {
|
||||
queue.add(vertex);
|
||||
}
|
||||
|
@ -31,9 +31,7 @@ class PrimMST {
|
||||
void printMST(int[] parent, int n, int[][] graph) {
|
||||
System.out.println("Edge Weight");
|
||||
for (int i = 1; i < V; i++) {
|
||||
System.out.println(
|
||||
parent[i] + " - " + i + " " + graph[i][parent[i]]
|
||||
);
|
||||
System.out.println(parent[i] + " - " + i + " " + graph[i][parent[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,17 +70,12 @@ class PrimMST {
|
||||
// Update key value and parent index of the adjacent
|
||||
// vertices of the picked vertex. Consider only those
|
||||
// vertices which are not yet included in MST
|
||||
for (
|
||||
int v = 0;
|
||||
v < V;
|
||||
v++
|
||||
) // Update the key only if graph[u][v] is smaller than key[v] // mstSet[v] is false for vertices not yet included in MST // graph[u][v] is non zero only for adjacent vertices of m
|
||||
for (int v = 0; v < V;
|
||||
v++) // Update the key only if graph[u][v] is smaller than key[v] // mstSet[v] is
|
||||
// false for vertices not yet included in MST // graph[u][v] is non zero only
|
||||
// for adjacent vertices of m
|
||||
{
|
||||
if (
|
||||
graph[u][v] != 0 &&
|
||||
!mstSet[v] &&
|
||||
graph[u][v] < key[v]
|
||||
) {
|
||||
if (graph[u][v] != 0 && !mstSet[v] && graph[u][v] < key[v]) {
|
||||
parent[v] = u;
|
||||
key[v] = graph[u][v];
|
||||
}
|
||||
@ -104,11 +97,11 @@ class PrimMST {
|
||||
9 */
|
||||
PrimMST t = new PrimMST();
|
||||
int[][] graph = new int[][] {
|
||||
{ 0, 2, 0, 6, 0 },
|
||||
{ 2, 0, 3, 8, 5 },
|
||||
{ 0, 3, 0, 0, 7 },
|
||||
{ 6, 8, 0, 0, 9 },
|
||||
{ 0, 5, 7, 9, 0 },
|
||||
{0, 2, 0, 6, 0},
|
||||
{2, 0, 3, 8, 5},
|
||||
{0, 3, 0, 0, 7},
|
||||
{6, 8, 0, 0, 9},
|
||||
{0, 5, 7, 9, 0},
|
||||
};
|
||||
|
||||
// Print the solution
|
||||
|
@ -8,16 +8,16 @@ import java.util.Stack;
|
||||
/**
|
||||
* Java program that implements Tarjan's Algorithm.
|
||||
* @author Shivanagouda S A (https://github.com/shivu2002a)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tarjan's algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred as SCC.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly connected.
|
||||
Single node is always a SCC.
|
||||
* Tarjan's algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred as SCC.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly
|
||||
connected. Single node is always a SCC.
|
||||
|
||||
* Example:
|
||||
0 --------> 1 -------> 3 --------> 4
|
||||
@ -38,24 +38,25 @@ import java.util.Stack;
|
||||
1, 2, 0
|
||||
3
|
||||
4
|
||||
|
||||
|
||||
We can also see that order of the nodes in an SCC doesn't matter since they are in cycle.
|
||||
|
||||
{@summary}
|
||||
Tarjan's Algorithm:
|
||||
* DFS search produces a DFS tree
|
||||
* Strongly Connected Components form subtrees of the DFS tree.
|
||||
* If we can find the head of these subtrees, we can get all the nodes in that subtree (including the head)
|
||||
and that will be one SCC.
|
||||
* There is no back edge from one SCC to another (here can be cross edges, but they will not be used).
|
||||
Tarjan's Algorithm:
|
||||
* DFS search produces a DFS tree
|
||||
* Strongly Connected Components form subtrees of the DFS tree.
|
||||
* If we can find the head of these subtrees, we can get all the nodes in that subtree (including
|
||||
the head) and that will be one SCC.
|
||||
* There is no back edge from one SCC to another (here can be cross edges, but they will not be
|
||||
used).
|
||||
|
||||
* Kosaraju Algorithm aims at doing the same but uses two DFS traversalse whereas Tarjan’s algorithm does
|
||||
the same in a single DFS, which leads to much lower constant factors in the latter.
|
||||
* Kosaraju Algorithm aims at doing the same but uses two DFS traversalse whereas Tarjan’s
|
||||
algorithm does the same in a single DFS, which leads to much lower constant factors in the latter.
|
||||
|
||||
*/
|
||||
public class TarjansAlgorithm {
|
||||
|
||||
//Timer for tracking lowtime and insertion time
|
||||
// Timer for tracking lowtime and insertion time
|
||||
private int Time;
|
||||
|
||||
private List<List<Integer>> SCClist = new ArrayList<List<Integer>>();
|
||||
@ -66,15 +67,15 @@ public class TarjansAlgorithm {
|
||||
|
||||
// insertionTime:Time when a node is visited 1st time while DFS traversal
|
||||
|
||||
// lowTime: indicates the earliest visited vertex (the vertex with minimum insertion time) that can
|
||||
// be reached from a subtree rooted with a particular node.
|
||||
// lowTime: indicates the earliest visited vertex (the vertex with minimum insertion time)
|
||||
// that can be reached from a subtree rooted with a particular node.
|
||||
int[] lowTime = new int[V];
|
||||
int[] insertionTime = new int[V];
|
||||
for (int i = 0; i < V; i++) {
|
||||
insertionTime[i] = -1;
|
||||
lowTime[i] = -1;
|
||||
}
|
||||
|
||||
|
||||
// To check if element is present in stack
|
||||
boolean[] isInStack = new boolean[V];
|
||||
|
||||
@ -90,36 +91,36 @@ public class TarjansAlgorithm {
|
||||
}
|
||||
|
||||
private void stronglyConnCompsUtil(int u, int[] lowTime, int[] insertionTime,
|
||||
boolean[] isInStack, Stack<Integer> st, List<List<Integer>> graph) {
|
||||
boolean[] isInStack, Stack<Integer> st, List<List<Integer>> graph) {
|
||||
|
||||
// Initialize insertion time and lowTime value of current node
|
||||
insertionTime[u] = Time;
|
||||
lowTime[u] = Time;
|
||||
Time += 1;
|
||||
|
||||
//Push current node into stack
|
||||
// Push current node into stack
|
||||
isInStack[u] = true;
|
||||
st.push(u);
|
||||
|
||||
// Go through all vertices adjacent to this
|
||||
for (Integer vertex : graph.get(u)) {
|
||||
//If the adjacent node is unvisited, do DFS
|
||||
// If the adjacent node is unvisited, do DFS
|
||||
if (insertionTime[vertex] == -1) {
|
||||
stronglyConnCompsUtil(vertex, lowTime, insertionTime, isInStack, st, graph);
|
||||
//update lowTime for the current node comparing lowtime of adj node
|
||||
// update lowTime for the current node comparing lowtime of adj node
|
||||
lowTime[u] = Math.min(lowTime[u], lowTime[vertex]);
|
||||
} else if (isInStack[vertex]) {
|
||||
//If adj node is in stack, update low
|
||||
// If adj node is in stack, update low
|
||||
lowTime[u] = Math.min(lowTime[u], insertionTime[vertex]);
|
||||
}
|
||||
}
|
||||
//If lowtime and insertion time are same, current node is the head of an SCC
|
||||
// head node found, get all the nodes in this SCC
|
||||
// If lowtime and insertion time are same, current node is the head of an SCC
|
||||
// head node found, get all the nodes in this SCC
|
||||
if (lowTime[u] == insertionTime[u]) {
|
||||
int w = -1;
|
||||
var scc = new ArrayList<Integer>();
|
||||
|
||||
//Stack has all the nodes of the current SCC
|
||||
// Stack has all the nodes of the current SCC
|
||||
while (w != u) {
|
||||
w = st.pop();
|
||||
scc.add(w);
|
||||
@ -128,5 +129,4 @@ public class TarjansAlgorithm {
|
||||
SCClist.add(scc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,8 @@ public class HashMapCuckooHashing {
|
||||
}
|
||||
|
||||
/**
|
||||
* The 2 Hash Functions takes a given key and finds an index based on its data, 2 distinctive ways to minimize collisions
|
||||
* The 2 Hash Functions takes a given key and finds an index based on its data, 2 distinctive
|
||||
* ways to minimize collisions
|
||||
*
|
||||
* @param key the desired key to be converted
|
||||
* @return int an index corresponding to the key
|
||||
@ -57,10 +58,10 @@ public class HashMapCuckooHashing {
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts the key into the hash map by wrapping it as an Integer object, then uses while loop to insert new key
|
||||
* if desired place is empty, return.
|
||||
* if already occupied, continue while loop over the new key that has just been pushed out.
|
||||
* if while loop continues more than Thresh, rehash table to new size, then push again.
|
||||
* inserts the key into the hash map by wrapping it as an Integer object, then uses while loop
|
||||
* to insert new key if desired place is empty, return. if already occupied, continue while loop
|
||||
* over the new key that has just been pushed out. if while loop continues more than Thresh,
|
||||
* rehash table to new size, then push again.
|
||||
*
|
||||
* @param key the desired key to be inserted in the hash map
|
||||
*/
|
||||
@ -70,26 +71,19 @@ public class HashMapCuckooHashing {
|
||||
int hash, loopCounter = 0;
|
||||
|
||||
if (isFull()) {
|
||||
System.out.println(
|
||||
"Hash table is full, lengthening & rehashing table"
|
||||
);
|
||||
System.out.println("Hash table is full, lengthening & rehashing table");
|
||||
reHashTableIncreasesTableSize();
|
||||
}
|
||||
|
||||
if (checkTableContainsKey(key)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Key already inside, no duplicates allowed"
|
||||
);
|
||||
throw new IllegalArgumentException("Key already inside, no duplicates allowed");
|
||||
}
|
||||
|
||||
while (loopCounter <= thresh) {
|
||||
loopCounter++;
|
||||
hash = hashFunction1(key);
|
||||
|
||||
if (
|
||||
(buckets[hash] == null) ||
|
||||
Objects.equals(buckets[hash], AVAILABLE)
|
||||
) {
|
||||
if ((buckets[hash] == null) || Objects.equals(buckets[hash], AVAILABLE)) {
|
||||
buckets[hash] = wrappedInt;
|
||||
size++;
|
||||
checkLoadFactor();
|
||||
@ -116,16 +110,14 @@ public class HashMapCuckooHashing {
|
||||
buckets[hash] = wrappedInt;
|
||||
wrappedInt = temp;
|
||||
}
|
||||
System.out.println(
|
||||
"Infinite loop occurred, lengthening & rehashing table"
|
||||
);
|
||||
System.out.println("Infinite loop occurred, lengthening & rehashing table");
|
||||
reHashTableIncreasesTableSize();
|
||||
insertKey2HashTable(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates new HashMapCuckooHashing object, then inserts each of the elements in the previous table to it with its new hash functions.
|
||||
* then refers current array to new table.
|
||||
* creates new HashMapCuckooHashing object, then inserts each of the elements in the previous
|
||||
* table to it with its new hash functions. then refers current array to new table.
|
||||
*
|
||||
*/
|
||||
public void reHashTableIncreasesTableSize() {
|
||||
@ -164,9 +156,7 @@ public class HashMapCuckooHashing {
|
||||
size--;
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Key " + key + " already inside, no duplicates allowed"
|
||||
);
|
||||
throw new IllegalArgumentException("Key " + key + " already inside, no duplicates allowed");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,9 +167,7 @@ public class HashMapCuckooHashing {
|
||||
if ((buckets[i] == null) || Objects.equals(buckets[i], AVAILABLE)) {
|
||||
System.out.println("Bucket " + i + ": Empty");
|
||||
} else {
|
||||
System.out.println(
|
||||
"Bucket " + i + ": " + buckets[i].toString()
|
||||
);
|
||||
System.out.println("Bucket " + i + ": " + buckets[i].toString());
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
@ -202,11 +190,9 @@ public class HashMapCuckooHashing {
|
||||
if (Objects.equals(buckets[hash], wrappedInt)) return hash;
|
||||
|
||||
hash = hashFunction2(key);
|
||||
if (
|
||||
!Objects.equals(buckets[hash], wrappedInt)
|
||||
) throw new IllegalArgumentException(
|
||||
"Key " + key + " not found in table"
|
||||
); else {
|
||||
if (!Objects.equals(buckets[hash], wrappedInt))
|
||||
throw new IllegalArgumentException("Key " + key + " not found in table");
|
||||
else {
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@ -218,16 +204,8 @@ public class HashMapCuckooHashing {
|
||||
* @return int the index where the key is located
|
||||
*/
|
||||
public boolean checkTableContainsKey(int key) {
|
||||
return (
|
||||
(
|
||||
buckets[hashFunction1(key)] != null &&
|
||||
buckets[hashFunction1(key)].equals(key)
|
||||
) ||
|
||||
(
|
||||
buckets[hashFunction2(key)] != null &&
|
||||
buckets[hashFunction2(key)] == key
|
||||
)
|
||||
);
|
||||
return ((buckets[hashFunction1(key)] != null && buckets[hashFunction1(key)].equals(key))
|
||||
|| (buckets[hashFunction2(key)] != null && buckets[hashFunction2(key)] == key));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,10 +215,7 @@ public class HashMapCuckooHashing {
|
||||
public double checkLoadFactor() {
|
||||
double factor = (double) size / tableSize;
|
||||
if (factor > .7) {
|
||||
System.out.printf(
|
||||
"Load factor is %.2f , rehashing table\n",
|
||||
factor
|
||||
);
|
||||
System.out.printf("Load factor is %.2f , rehashing table\n", factor);
|
||||
reHashTableIncreasesTableSize();
|
||||
}
|
||||
return factor;
|
||||
|
@ -15,9 +15,7 @@ import java.util.Map;
|
||||
public class Intersection {
|
||||
|
||||
public static List<Integer> intersection(int[] arr1, int[] arr2) {
|
||||
if (
|
||||
arr1 == null || arr2 == null || arr1.length == 0 || arr2.length == 0
|
||||
) {
|
||||
if (arr1 == null || arr2 == null || arr1.length == 0 || arr2.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<Integer, Integer> cnt = new HashMap<>(16);
|
||||
@ -34,5 +32,6 @@ public class Intersection {
|
||||
return res;
|
||||
}
|
||||
|
||||
private Intersection() {}
|
||||
private Intersection() {
|
||||
}
|
||||
}
|
||||
|
@ -20,31 +20,27 @@ public class Main {
|
||||
choice = In.nextInt();
|
||||
|
||||
switch (choice) {
|
||||
case 1:
|
||||
{
|
||||
System.out.println("Enter the Key: ");
|
||||
key = In.nextInt();
|
||||
h.insertHash(key);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
System.out.println("Enter the Key delete: ");
|
||||
key = In.nextInt();
|
||||
h.deleteHash(key);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
System.out.println("Print table");
|
||||
h.displayHashtable();
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
In.close();
|
||||
return;
|
||||
}
|
||||
case 1: {
|
||||
System.out.println("Enter the Key: ");
|
||||
key = In.nextInt();
|
||||
h.insertHash(key);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
System.out.println("Enter the Key delete: ");
|
||||
key = In.nextInt();
|
||||
h.deleteHash(key);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
System.out.println("Print table");
|
||||
h.displayHashtable();
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
In.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,59 +24,41 @@ public class MainCuckooHashing {
|
||||
choice = In.nextInt();
|
||||
|
||||
switch (choice) {
|
||||
case 1:
|
||||
{
|
||||
System.out.println("Enter the Key: ");
|
||||
key = In.nextInt();
|
||||
h.insertKey2HashTable(key);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
System.out.println("Enter the Key delete: ");
|
||||
key = In.nextInt();
|
||||
h.deleteKeyFromHashTable(key);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
System.out.println("Print table:\n");
|
||||
h.displayHashtable();
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
In.close();
|
||||
return;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
System.out.println(
|
||||
"Enter the Key to find and print: "
|
||||
);
|
||||
key = In.nextInt();
|
||||
System.out.println(
|
||||
"Key: " +
|
||||
key +
|
||||
" is at index: " +
|
||||
h.findKeyInTable(key) +
|
||||
"\n"
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
System.out.printf(
|
||||
"Load factor is: %.2f\n",
|
||||
h.checkLoadFactor()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
h.reHashTableIncreasesTableSize();
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
System.out.println("Enter the Key: ");
|
||||
key = In.nextInt();
|
||||
h.insertKey2HashTable(key);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
System.out.println("Enter the Key delete: ");
|
||||
key = In.nextInt();
|
||||
h.deleteKeyFromHashTable(key);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
System.out.println("Print table:\n");
|
||||
h.displayHashtable();
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
In.close();
|
||||
return;
|
||||
}
|
||||
case 5: {
|
||||
System.out.println("Enter the Key to find and print: ");
|
||||
key = In.nextInt();
|
||||
System.out.println("Key: " + key + " is at index: " + h.findKeyInTable(key) + "\n");
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
System.out.printf("Load factor is: %.2f\n", h.checkLoadFactor());
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
h.reHashTableIncreasesTableSize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,32 @@
|
||||
package com.thealgorithms.datastructures.hashmap.hashing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
/*
|
||||
This class finds the majority element(s) in an array of integers.
|
||||
A majority element is an element that appears more than or equal to n/2 times, where n is the length of the array.
|
||||
A majority element is an element that appears more than or equal to n/2 times, where n is the length
|
||||
of the array.
|
||||
*/
|
||||
public class MajorityElement {
|
||||
/*
|
||||
This method returns the majority element(s) in the given array of integers.
|
||||
@param nums: an array of integers
|
||||
@return a list of majority elements
|
||||
*/
|
||||
public static List<Integer> majority(int[] nums){
|
||||
HashMap<Integer,Integer> numToCount = new HashMap<>();
|
||||
/*
|
||||
This method returns the majority element(s) in the given array of integers.
|
||||
@param nums: an array of integers
|
||||
@return a list of majority elements
|
||||
*/
|
||||
public static List<Integer> majority(int[] nums) {
|
||||
HashMap<Integer, Integer> numToCount = new HashMap<>();
|
||||
int n = nums.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (numToCount.containsKey(nums[i])){
|
||||
numToCount.put(nums[i],numToCount.get(nums[i])+1);
|
||||
if (numToCount.containsKey(nums[i])) {
|
||||
numToCount.put(nums[i], numToCount.get(nums[i]) + 1);
|
||||
} else {
|
||||
numToCount.put(nums[i],1);
|
||||
numToCount.put(nums[i], 1);
|
||||
}
|
||||
}
|
||||
List<Integer> majorityElements = new ArrayList<>();
|
||||
for (int key: numToCount.keySet()) {
|
||||
if (numToCount.get(key) >= n/2){
|
||||
for (int key : numToCount.keySet()) {
|
||||
if (numToCount.get(key) >= n / 2) {
|
||||
majorityElements.add(key);
|
||||
}
|
||||
}
|
||||
|
@ -19,5 +19,4 @@ public abstract class Map<Key, Value> {
|
||||
protected int hash(Key key, int size) {
|
||||
return (key.hashCode() & Integer.MAX_VALUE) % size;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,10 +47,10 @@ public class FibonacciHeap {
|
||||
* $ret = the HeapNode we inserted
|
||||
*/
|
||||
public HeapNode insert(int key) {
|
||||
HeapNode toInsert = new HeapNode(key); //creates the node
|
||||
HeapNode toInsert = new HeapNode(key); // creates the node
|
||||
if (this.empty()) {
|
||||
this.min = toInsert;
|
||||
} else { //tree is not empty
|
||||
} else { // tree is not empty
|
||||
min.setNext(toInsert);
|
||||
this.updateMin(toInsert);
|
||||
}
|
||||
@ -69,14 +69,14 @@ public class FibonacciHeap {
|
||||
if (this.empty()) {
|
||||
return;
|
||||
}
|
||||
if (this.numOfHeapNodes == 1) { //if there is only one tree
|
||||
if (this.numOfHeapNodes == 1) { // if there is only one tree
|
||||
this.min = null;
|
||||
this.numOfTrees--;
|
||||
this.numOfHeapNodes--;
|
||||
return;
|
||||
}
|
||||
//change all children's parent to null//
|
||||
if (this.min.child != null) { //min has a child
|
||||
// change all children's parent to null//
|
||||
if (this.min.child != null) { // min has a child
|
||||
HeapNode child = this.min.child;
|
||||
HeapNode tmpChild = child;
|
||||
child.parent = null;
|
||||
@ -85,14 +85,14 @@ public class FibonacciHeap {
|
||||
child.parent = null;
|
||||
}
|
||||
}
|
||||
//delete the node//
|
||||
// delete the node//
|
||||
if (this.numOfTrees > 1) {
|
||||
(this.min.prev).next = this.min.next;
|
||||
(this.min.next).prev = this.min.prev;
|
||||
if (this.min.child != null) {
|
||||
(this.min.prev).setNext(this.min.child);
|
||||
}
|
||||
} else { //this.numOfTrees = 1
|
||||
} else { // this.numOfTrees = 1
|
||||
this.min = this.min.child;
|
||||
}
|
||||
this.numOfHeapNodes--;
|
||||
@ -136,17 +136,15 @@ public class FibonacciHeap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a counters array, where the value of the i-th index is the number of trees with rank i in the heap.
|
||||
* returns an empty array for an empty heap
|
||||
* Return a counters array, where the value of the i-th index is the number of trees with rank i
|
||||
* in the heap. returns an empty array for an empty heap
|
||||
*/
|
||||
public int[] countersRep() {
|
||||
if (this.empty()) {
|
||||
return new int[0]; ///return an empty array
|
||||
return new int[0]; /// return an empty array
|
||||
}
|
||||
int[] rankArray = new int[(int) Math.floor(
|
||||
Math.log(this.size()) / Math.log(GOLDEN_RATIO)
|
||||
) +
|
||||
1]; //creates the array
|
||||
int[] rankArray = new int[(int) Math.floor(Math.log(this.size()) / Math.log(GOLDEN_RATIO))
|
||||
+ 1]; // creates the array
|
||||
rankArray[this.min.rank]++;
|
||||
HeapNode curr = this.min.next;
|
||||
while (curr != this.min) {
|
||||
@ -163,8 +161,8 @@ public class FibonacciHeap {
|
||||
* @post (numOfnodes = = $prev numOfnodes - 1)
|
||||
*/
|
||||
public void delete(HeapNode x) {
|
||||
this.decreaseKey(x, x.getKey() + 1); //change key to be the minimal (-1)
|
||||
this.deleteMin(); //delete it
|
||||
this.decreaseKey(x, x.getKey() + 1); // change key to be the minimal (-1)
|
||||
this.deleteMin(); // delete it
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,13 +174,13 @@ public class FibonacciHeap {
|
||||
private void decreaseKey(HeapNode x, int delta) {
|
||||
int newKey = x.getKey() - delta;
|
||||
x.key = newKey;
|
||||
if (x.isRoot()) { //no parent to x
|
||||
if (x.isRoot()) { // no parent to x
|
||||
this.updateMin(x);
|
||||
return;
|
||||
}
|
||||
if (x.getKey() >= x.parent.getKey()) {
|
||||
return;
|
||||
} //we don't need to cut
|
||||
} // we don't need to cut
|
||||
HeapNode prevParent = x.parent;
|
||||
this.cut(x);
|
||||
this.cascadingCuts(prevParent);
|
||||
@ -197,17 +195,18 @@ public class FibonacciHeap {
|
||||
}
|
||||
|
||||
/**
|
||||
* This static function returns the total number of link operations made during the run-time of the program.
|
||||
* A link operation is the operation which gets as input two trees of the same rank, and generates a tree of
|
||||
* rank bigger by one.
|
||||
* This static function returns the total number of link operations made during the run-time of
|
||||
* the program. A link operation is the operation which gets as input two trees of the same
|
||||
* rank, and generates a tree of rank bigger by one.
|
||||
*/
|
||||
public static int totalLinks() {
|
||||
return totalLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* This static function returns the total number of cut operations made during the run-time of the program.
|
||||
* A cut operation is the operation which disconnects a subtree from its parent (during decreaseKey/delete methods).
|
||||
* This static function returns the total number of cut operations made during the run-time of
|
||||
* the program. A cut operation is the operation which disconnects a subtree from its parent
|
||||
* (during decreaseKey/delete methods).
|
||||
*/
|
||||
public static int totalCuts() {
|
||||
return totalCuts;
|
||||
@ -231,7 +230,7 @@ public class FibonacciHeap {
|
||||
* @post (numOfnodes == $prev numOfnodes)
|
||||
*/
|
||||
private void cascadingCuts(HeapNode curr) {
|
||||
if (!curr.isMarked()) { //stop the recursion
|
||||
if (!curr.isMarked()) { // stop the recursion
|
||||
curr.mark();
|
||||
if (!curr.isRoot()) this.markedHeapNoodesCounter++;
|
||||
} else {
|
||||
@ -255,10 +254,10 @@ public class FibonacciHeap {
|
||||
this.markedHeapNoodesCounter--;
|
||||
curr.marked = false;
|
||||
}
|
||||
if (curr.parent.child == curr) { //we should change the parent's child
|
||||
if (curr.next == curr) { //curr do not have brothers
|
||||
if (curr.parent.child == curr) { // we should change the parent's child
|
||||
if (curr.next == curr) { // curr do not have brothers
|
||||
curr.parent.child = null;
|
||||
} else { //curr have brothers
|
||||
} else { // curr have brothers
|
||||
curr.parent.child = curr.next;
|
||||
}
|
||||
}
|
||||
@ -285,10 +284,8 @@ public class FibonacciHeap {
|
||||
*
|
||||
*/
|
||||
private HeapNode[] toBuckets(HeapNode curr) {
|
||||
HeapNode[] buckets = new HeapNode[(int) Math.floor(
|
||||
Math.log(this.size()) / Math.log(GOLDEN_RATIO)
|
||||
) +
|
||||
1];
|
||||
HeapNode[] buckets
|
||||
= new HeapNode[(int) Math.floor(Math.log(this.size()) / Math.log(GOLDEN_RATIO)) + 1];
|
||||
curr.prev.next = null;
|
||||
HeapNode tmpCurr;
|
||||
while (curr != null) {
|
||||
@ -398,7 +395,7 @@ public class FibonacciHeap {
|
||||
private void mark() {
|
||||
if (this.isRoot()) {
|
||||
return;
|
||||
} //check if the node is a root
|
||||
} // check if the node is a root
|
||||
this.marked = true;
|
||||
}
|
||||
|
||||
|
@ -45,16 +45,10 @@ public class GenericHeap<T extends Comparable<T>> {
|
||||
int lci = 2 * pi + 1;
|
||||
int rci = 2 * pi + 2;
|
||||
int mini = pi;
|
||||
if (
|
||||
lci < this.size() &&
|
||||
isLarger(this.data.get(lci), this.data.get(mini)) > 0
|
||||
) {
|
||||
if (lci < this.size() && isLarger(this.data.get(lci), this.data.get(mini)) > 0) {
|
||||
mini = lci;
|
||||
}
|
||||
if (
|
||||
rci < this.size() &&
|
||||
isLarger(this.data.get(rci), this.data.get(mini)) > 0
|
||||
) {
|
||||
if (rci < this.size() && isLarger(this.data.get(rci), this.data.get(mini)) > 0) {
|
||||
mini = rci;
|
||||
}
|
||||
if (mini != pi) {
|
||||
@ -67,7 +61,7 @@ public class GenericHeap<T extends Comparable<T>> {
|
||||
return this.data.get(0);
|
||||
}
|
||||
|
||||
//t has higher property then return +ve
|
||||
// t has higher property then return +ve
|
||||
private int isLarger(T t, T o) {
|
||||
return t.compareTo(o);
|
||||
}
|
||||
@ -83,7 +77,7 @@ public class GenericHeap<T extends Comparable<T>> {
|
||||
|
||||
public void updatePriority(T item) {
|
||||
int index = map.get(item);
|
||||
//because we enter lesser value then old vale
|
||||
// because we enter lesser value then old vale
|
||||
upHeapify(index);
|
||||
}
|
||||
}
|
||||
|
@ -122,10 +122,8 @@ public class HeapElement {
|
||||
return false;
|
||||
}
|
||||
HeapElement otherHeapElement = (HeapElement) o;
|
||||
return (
|
||||
(this.key == otherHeapElement.key) &&
|
||||
(this.additionalInfo.equals(otherHeapElement.additionalInfo))
|
||||
);
|
||||
return ((this.key == otherHeapElement.key)
|
||||
&& (this.additionalInfo.equals(otherHeapElement.additionalInfo)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -134,10 +132,7 @@ public class HeapElement {
|
||||
public int hashCode() {
|
||||
int result = 0;
|
||||
result = 31 * result + (int) key;
|
||||
result =
|
||||
31 *
|
||||
result +
|
||||
(additionalInfo != null ? additionalInfo.hashCode() : 0);
|
||||
result = 31 * result + (additionalInfo != null ? additionalInfo.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -2,117 +2,113 @@ package com.thealgorithms.datastructures.heaps;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
/*
|
||||
* This is a leftist heap that follows the same operations as a
|
||||
* binary min heap, but may be unbalanced at times and follows a
|
||||
* leftist property, in which the left side is more heavy on the
|
||||
* right based on the null-path length (npl) values.
|
||||
*
|
||||
*
|
||||
* Source: https://iq.opengenus.org/leftist-heap/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class LeftistHeap {
|
||||
private class Node {
|
||||
private int element, npl;
|
||||
private Node left, right;
|
||||
private class Node {
|
||||
private int element, npl;
|
||||
private Node left, right;
|
||||
|
||||
// Node constructor setting the data element and left/right pointers to null
|
||||
private Node(int element) {
|
||||
this.element = element;
|
||||
left = right = null;
|
||||
npl = 0;
|
||||
}
|
||||
}
|
||||
// Node constructor setting the data element and left/right pointers to null
|
||||
private Node(int element) {
|
||||
this.element = element;
|
||||
left = right = null;
|
||||
npl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private Node root;
|
||||
private Node root;
|
||||
|
||||
// Constructor
|
||||
public LeftistHeap() {
|
||||
root = null;
|
||||
}
|
||||
// Constructor
|
||||
public LeftistHeap() {
|
||||
root = null;
|
||||
}
|
||||
|
||||
// Checks if heap is empty
|
||||
public boolean isEmpty() {
|
||||
return root == null;
|
||||
}
|
||||
// Checks if heap is empty
|
||||
public boolean isEmpty() {
|
||||
return root == null;
|
||||
}
|
||||
|
||||
// Resets structure to initial state
|
||||
public void clear() {
|
||||
// We will put head is null
|
||||
root = null;
|
||||
}
|
||||
// Resets structure to initial state
|
||||
public void clear() {
|
||||
// We will put head is null
|
||||
root = null;
|
||||
}
|
||||
|
||||
// Merge function that merges the contents of another leftist heap with the
|
||||
// current one
|
||||
public void merge(LeftistHeap h1) {
|
||||
// If the present function is rhs then we ignore the merge
|
||||
root = merge(root, h1.root);
|
||||
h1.root = null;
|
||||
}
|
||||
// Merge function that merges the contents of another leftist heap with the
|
||||
// current one
|
||||
public void merge(LeftistHeap h1) {
|
||||
// If the present function is rhs then we ignore the merge
|
||||
root = merge(root, h1.root);
|
||||
h1.root = null;
|
||||
}
|
||||
|
||||
// Function merge with two Nodes a and b
|
||||
public Node merge(Node a, Node b) {
|
||||
if (a == null)
|
||||
return b;
|
||||
// Function merge with two Nodes a and b
|
||||
public Node merge(Node a, Node b) {
|
||||
if (a == null) return b;
|
||||
|
||||
if (b == null)
|
||||
return a;
|
||||
if (b == null) return a;
|
||||
|
||||
// Violates leftist property, so must do a swap
|
||||
if (a.element > b.element) {
|
||||
Node temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
// Violates leftist property, so must do a swap
|
||||
if (a.element > b.element) {
|
||||
Node temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
// Now we call the function merge to merge a and b
|
||||
a.right = merge(a.right, b);
|
||||
// Now we call the function merge to merge a and b
|
||||
a.right = merge(a.right, b);
|
||||
|
||||
// Violates leftist property so must swap here
|
||||
if (a.left == null) {
|
||||
a.left = a.right;
|
||||
a.right = null;
|
||||
} else {
|
||||
if (a.left.npl < a.right.npl) {
|
||||
Node temp = a.left;
|
||||
a.left = a.right;
|
||||
a.right = temp;
|
||||
}
|
||||
a.npl = a.right.npl + 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
// Violates leftist property so must swap here
|
||||
if (a.left == null) {
|
||||
a.left = a.right;
|
||||
a.right = null;
|
||||
} else {
|
||||
if (a.left.npl < a.right.npl) {
|
||||
Node temp = a.left;
|
||||
a.left = a.right;
|
||||
a.right = temp;
|
||||
}
|
||||
a.npl = a.right.npl + 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
// Function insert. Uses the merge function to add the data
|
||||
public void insert(int a) {
|
||||
root = merge(new Node(a), root);
|
||||
}
|
||||
// Function insert. Uses the merge function to add the data
|
||||
public void insert(int a) {
|
||||
root = merge(new Node(a), root);
|
||||
}
|
||||
|
||||
// Returns and removes the minimum element in the heap
|
||||
public int extract_min() {
|
||||
// If is empty return -1
|
||||
if (isEmpty())
|
||||
return -1;
|
||||
// Returns and removes the minimum element in the heap
|
||||
public int extract_min() {
|
||||
// If is empty return -1
|
||||
if (isEmpty()) return -1;
|
||||
|
||||
int min = root.element;
|
||||
root = merge(root.left, root.right);
|
||||
return min;
|
||||
}
|
||||
int min = root.element;
|
||||
root = merge(root.left, root.right);
|
||||
return min;
|
||||
}
|
||||
|
||||
// Function returning a list of an in order traversal of the data structure
|
||||
public ArrayList<Integer> in_order() {
|
||||
ArrayList<Integer> lst = new ArrayList<>();
|
||||
in_order_aux(root, lst);
|
||||
return new ArrayList<>(lst);
|
||||
}
|
||||
// Function returning a list of an in order traversal of the data structure
|
||||
public ArrayList<Integer> in_order() {
|
||||
ArrayList<Integer> lst = new ArrayList<>();
|
||||
in_order_aux(root, lst);
|
||||
return new ArrayList<>(lst);
|
||||
}
|
||||
|
||||
// Auxiliary function for in_order
|
||||
private void in_order_aux(Node n, ArrayList<Integer> lst) {
|
||||
if (n == null)
|
||||
return;
|
||||
in_order_aux(n.left, lst);
|
||||
lst.add(n.element);
|
||||
in_order_aux(n.right, lst);
|
||||
}
|
||||
// Auxiliary function for in_order
|
||||
private void in_order_aux(Node n, ArrayList<Integer> lst) {
|
||||
if (n == null) return;
|
||||
in_order_aux(n.left, lst);
|
||||
lst.add(n.element);
|
||||
in_order_aux(n.right, lst);
|
||||
}
|
||||
}
|
@ -70,30 +70,20 @@ public class MaxHeap implements Heap {
|
||||
// than any of its children's
|
||||
private void toggleDown(int elementIndex) {
|
||||
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) {
|
||||
// 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);
|
||||
elementIndex = 2 * elementIndex + 1;
|
||||
} else {
|
||||
swap(elementIndex, 2 * elementIndex);
|
||||
elementIndex = 2 * elementIndex;
|
||||
}
|
||||
wrongOrder =
|
||||
(key < getElementKey(elementIndex * 2)) ||
|
||||
(
|
||||
key <
|
||||
getElementKey(Math.min(elementIndex * 2, maxHeap.size()))
|
||||
);
|
||||
wrongOrder = (key < getElementKey(elementIndex * 2))
|
||||
|| (key < getElementKey(Math.min(elementIndex * 2, maxHeap.size())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,12 +102,10 @@ public class MaxHeap implements Heap {
|
||||
@Override
|
||||
public void deleteElement(int elementIndex) {
|
||||
if (maxHeap.isEmpty()) try {
|
||||
throw new EmptyHeapException(
|
||||
"Attempt to delete an element from an empty heap"
|
||||
);
|
||||
} catch (EmptyHeapException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new EmptyHeapException("Attempt to delete an element from an empty heap");
|
||||
} catch (EmptyHeapException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if ((elementIndex > maxHeap.size()) || (elementIndex <= 0)) {
|
||||
throw new IndexOutOfBoundsException("Index out of heap range");
|
||||
}
|
||||
@ -125,22 +113,13 @@ public class MaxHeap implements Heap {
|
||||
maxHeap.set(elementIndex - 1, getElement(maxHeap.size()));
|
||||
maxHeap.remove(maxHeap.size());
|
||||
// Shall the new element be moved up...
|
||||
if (
|
||||
getElementKey(elementIndex) >
|
||||
getElementKey((int) Math.floor(elementIndex / 2.0))
|
||||
) {
|
||||
if (getElementKey(elementIndex) > getElementKey((int) Math.floor(elementIndex / 2.0))) {
|
||||
toggleUp(elementIndex);
|
||||
} // ... or down ?
|
||||
else if (
|
||||
(
|
||||
(2 * elementIndex <= maxHeap.size()) &&
|
||||
(getElementKey(elementIndex) < getElementKey(elementIndex * 2))
|
||||
) ||
|
||||
(
|
||||
(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);
|
||||
}
|
||||
}
|
||||
@ -150,9 +129,7 @@ public class MaxHeap implements Heap {
|
||||
try {
|
||||
return extractMax();
|
||||
} catch (Exception e) {
|
||||
throw new EmptyHeapException(
|
||||
"Heap is empty. Error retrieving element"
|
||||
);
|
||||
throw new EmptyHeapException("Heap is empty. Error retrieving element");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,30 +64,20 @@ public class MinHeap implements Heap {
|
||||
// than any of its children's
|
||||
private void toggleDown(int elementIndex) {
|
||||
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) {
|
||||
// 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);
|
||||
elementIndex = 2 * elementIndex + 1;
|
||||
} else {
|
||||
swap(elementIndex, 2 * elementIndex);
|
||||
elementIndex = 2 * elementIndex;
|
||||
}
|
||||
wrongOrder =
|
||||
(key > getElementKey(elementIndex * 2)) ||
|
||||
(
|
||||
key >
|
||||
getElementKey(Math.min(elementIndex * 2, minHeap.size()))
|
||||
);
|
||||
wrongOrder = (key > getElementKey(elementIndex * 2))
|
||||
|| (key > getElementKey(Math.min(elementIndex * 2, minHeap.size())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,12 +96,10 @@ public class MinHeap implements Heap {
|
||||
@Override
|
||||
public void deleteElement(int elementIndex) {
|
||||
if (minHeap.isEmpty()) try {
|
||||
throw new EmptyHeapException(
|
||||
"Attempt to delete an element from an empty heap"
|
||||
);
|
||||
} catch (EmptyHeapException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new EmptyHeapException("Attempt to delete an element from an empty heap");
|
||||
} catch (EmptyHeapException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if ((elementIndex > minHeap.size()) || (elementIndex <= 0)) {
|
||||
throw new IndexOutOfBoundsException("Index out of heap range");
|
||||
}
|
||||
@ -119,22 +107,13 @@ public class MinHeap implements Heap {
|
||||
minHeap.set(elementIndex - 1, getElement(minHeap.size()));
|
||||
minHeap.remove(minHeap.size());
|
||||
// Shall the new element be moved up...
|
||||
if (
|
||||
getElementKey(elementIndex) <
|
||||
getElementKey((int) Math.floor(elementIndex / 2.0))
|
||||
) {
|
||||
if (getElementKey(elementIndex) < getElementKey((int) Math.floor(elementIndex / 2.0))) {
|
||||
toggleUp(elementIndex);
|
||||
} // ... or down ?
|
||||
else if (
|
||||
(
|
||||
(2 * elementIndex <= minHeap.size()) &&
|
||||
(getElementKey(elementIndex) > getElementKey(elementIndex * 2))
|
||||
) ||
|
||||
(
|
||||
(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);
|
||||
}
|
||||
}
|
||||
@ -144,9 +123,7 @@ public class MinHeap implements Heap {
|
||||
try {
|
||||
return extractMin();
|
||||
} catch (Exception e) {
|
||||
throw new EmptyHeapException(
|
||||
"Heap is empty. Error retrieving element"
|
||||
);
|
||||
throw new EmptyHeapException("Heap is empty. Error retrieving element");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,10 +82,7 @@ public class MinPriorityQueue {
|
||||
while (2 * k <= this.size || 2 * k + 1 <= this.size) {
|
||||
int minIndex;
|
||||
if (this.heap[2 * k] >= this.heap[k]) {
|
||||
if (
|
||||
2 * k + 1 <= this.size &&
|
||||
this.heap[2 * k + 1] >= this.heap[k]
|
||||
) {
|
||||
if (2 * k + 1 <= this.size && this.heap[2 * k + 1] >= this.heap[k]) {
|
||||
break;
|
||||
} else if (2 * k + 1 > this.size) {
|
||||
break;
|
||||
@ -94,14 +91,8 @@ public class MinPriorityQueue {
|
||||
if (2 * k + 1 > this.size) {
|
||||
minIndex = this.heap[2 * k] < this.heap[k] ? 2 * k : k;
|
||||
} else {
|
||||
if (
|
||||
this.heap[k] > this.heap[2 * k] ||
|
||||
this.heap[k] > this.heap[2 * k + 1]
|
||||
) {
|
||||
minIndex =
|
||||
this.heap[2 * k] < this.heap[2 * k + 1]
|
||||
? 2 * k
|
||||
: 2 * k + 1;
|
||||
if (this.heap[k] > this.heap[2 * k] || this.heap[k] > this.heap[2 * k + 1]) {
|
||||
minIndex = this.heap[2 * k] < this.heap[2 * k + 1] ? 2 * k : 2 * k + 1;
|
||||
} else {
|
||||
minIndex = k;
|
||||
}
|
||||
|
@ -38,9 +38,7 @@ public class CircleLinkedList<E> {
|
||||
public void append(E value) {
|
||||
if (value == null) {
|
||||
// we do not want to add null elements to the list.
|
||||
throw new NullPointerException(
|
||||
"Cannot add null element to the list"
|
||||
);
|
||||
throw new NullPointerException("Cannot add null element to the list");
|
||||
}
|
||||
// head.next points to the last element;
|
||||
if (tail == null) {
|
||||
@ -70,9 +68,7 @@ public class CircleLinkedList<E> {
|
||||
public E remove(int pos) {
|
||||
if (pos > size || pos < 0) {
|
||||
// catching errors
|
||||
throw new IndexOutOfBoundsException(
|
||||
"position cannot be greater than size or negative"
|
||||
);
|
||||
throw new IndexOutOfBoundsException("position cannot be greater than size or negative");
|
||||
}
|
||||
// we need to keep track of the element before the element we want to remove we can see why
|
||||
// bellow.
|
||||
|
@ -120,8 +120,7 @@ public class CursorLinkedList<T> {
|
||||
while (current_index != -1) {
|
||||
T current_element = cursorSpace[current_index].element;
|
||||
if (current_element.equals(element)) {
|
||||
cursorSpace[prev_index].next =
|
||||
cursorSpace[current_index].next;
|
||||
cursorSpace[prev_index].next = cursorSpace[current_index].next;
|
||||
free(current_index);
|
||||
break;
|
||||
}
|
||||
|
@ -217,7 +217,8 @@ class LinkOperations {
|
||||
public void insertTail(int x, DoublyLinkedList doublyLinkedList) {
|
||||
Link newLink = new Link(x);
|
||||
newLink.next = null; // currentTail(tail) newlink -->
|
||||
if (doublyLinkedList.isEmpty()) { // Check if there are no elements in list then it adds first element
|
||||
if (doublyLinkedList
|
||||
.isEmpty()) { // Check if there are no elements in list then it adds first element
|
||||
tail = newLink;
|
||||
head = tail;
|
||||
} else {
|
||||
@ -234,15 +235,9 @@ class LinkOperations {
|
||||
* @param x Element to be inserted
|
||||
* @param index Index(from start) at which the element x to be inserted
|
||||
*/
|
||||
public void insertElementByIndex(
|
||||
int x,
|
||||
int index,
|
||||
DoublyLinkedList doublyLinkedList
|
||||
) {
|
||||
public void insertElementByIndex(int x, int index, DoublyLinkedList doublyLinkedList) {
|
||||
if (index > size) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Index: " + index + ", Size: " + size
|
||||
);
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
||||
}
|
||||
if (index == 0) {
|
||||
insertHead(x, doublyLinkedList);
|
||||
@ -277,7 +272,8 @@ class LinkOperations {
|
||||
if (head == null) {
|
||||
tail = null;
|
||||
} else {
|
||||
head.previous = null; // oldHead --> 2ndElement(head) nothing pointing at old head so will be removed
|
||||
head.previous = null; // oldHead --> 2ndElement(head) nothing pointing at old head so
|
||||
// will be removed
|
||||
}
|
||||
--size;
|
||||
return temp;
|
||||
@ -314,9 +310,7 @@ class LinkOperations {
|
||||
if (current != tail) {
|
||||
current = current.next;
|
||||
} else { // If we reach the tail and the element is still not found
|
||||
throw new RuntimeException(
|
||||
"The element to be deleted does not exist!"
|
||||
);
|
||||
throw new RuntimeException("The element to be deleted does not exist!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,7 @@ public class MergeSortedArrayList {
|
||||
* @param listB the second list to merge
|
||||
* @param listC the result list after merging
|
||||
*/
|
||||
public static void merge(
|
||||
List<Integer> listA,
|
||||
List<Integer> listB,
|
||||
List<Integer> listC
|
||||
) {
|
||||
public static void merge(List<Integer> listA, List<Integer> listB, List<Integer> listC) {
|
||||
int pa = 0;
|
||||
/* the index of listA */
|
||||
int pb = 0;
|
||||
|
@ -12,9 +12,7 @@ public class MergeSortedSinglyLinkedList extends SinglyLinkedList {
|
||||
}
|
||||
assert listA.toString().equals("2->4->6->8->10");
|
||||
assert listB.toString().equals("1->3->5->7->9");
|
||||
assert merge(listA, listB)
|
||||
.toString()
|
||||
.equals("1->2->3->4->5->6->7->8->9->10");
|
||||
assert merge(listA, listB).toString().equals("1->2->3->4->5->6->7->8->9->10");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -24,10 +22,7 @@ public class MergeSortedSinglyLinkedList extends SinglyLinkedList {
|
||||
* @param listB the second sored list
|
||||
* @return merged sorted list
|
||||
*/
|
||||
public static SinglyLinkedList merge(
|
||||
SinglyLinkedList listA,
|
||||
SinglyLinkedList listB
|
||||
) {
|
||||
public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList listB) {
|
||||
Node headA = listA.getHead();
|
||||
Node headB = listB.getHead();
|
||||
|
||||
|
@ -18,9 +18,7 @@ public class Merge_K_SortedLinkedlist {
|
||||
*/
|
||||
Node mergeKList(Node[] a, int N) {
|
||||
// Min Heap
|
||||
PriorityQueue<Node> min = new PriorityQueue<>(
|
||||
Comparator.comparingInt(x -> x.data)
|
||||
);
|
||||
PriorityQueue<Node> min = new PriorityQueue<>(Comparator.comparingInt(x -> x.data));
|
||||
|
||||
// adding head of all linkedList in min heap
|
||||
min.addAll(Arrays.asList(a).subList(0, N));
|
||||
|
@ -1,25 +1,30 @@
|
||||
/** Author : Suraj Kumar
|
||||
/**
|
||||
* Author : Suraj Kumar
|
||||
* Github : https://github.com/skmodi649
|
||||
*/
|
||||
|
||||
/** PROBLEM DESCRIPTION :
|
||||
/**
|
||||
* PROBLEM DESCRIPTION :
|
||||
* There is a single linked list and we are supposed to find a random node in the given linked list
|
||||
*/
|
||||
|
||||
/** ALGORITHM :
|
||||
/**
|
||||
* ALGORITHM :
|
||||
* Step 1 : START
|
||||
* Step 2 : Create an arraylist of type integer
|
||||
* Step 3 : Declare an integer type variable for size and linked list type for head
|
||||
* Step 4 : We will use two methods, one for traversing through the linked list using while loop and also increase the size by 1
|
||||
* Step 4 : We will use two methods, one for traversing through the linked list using while loop and
|
||||
* also increase the size by 1
|
||||
*
|
||||
* (a) RandomNode(head)
|
||||
* (b) run a while loop till null;
|
||||
* (c) add the value to arraylist;
|
||||
* (d) increase the size;
|
||||
*
|
||||
* Step 5 : Now use another method for getting random values using Math.random() and return the value present in arraylist for the calculated index
|
||||
* Step 6 : Now in main() method we will simply insert nodes in the linked list and then call the appropriate method and then print the random node generated
|
||||
* Step 7 : STOP
|
||||
* Step 5 : Now use another method for getting random values using Math.random() and return the
|
||||
* value present in arraylist for the calculated index Step 6 : Now in main() method we will simply
|
||||
* insert nodes in the linked list and then call the appropriate method and then print the random
|
||||
* node generated Step 7 : STOP
|
||||
*/
|
||||
|
||||
package com.thealgorithms.datastructures.lists;
|
||||
@ -86,6 +91,7 @@ public class RandomNode {
|
||||
* Time Complexity : O(n)
|
||||
* Auxiliary Space Complexity : O(1)
|
||||
*/
|
||||
/** Time Complexity : O(n)
|
||||
/**
|
||||
* Time Complexity : O(n)
|
||||
* Auxiliary Space Complexity : O(1)
|
||||
*/
|
||||
|
@ -23,10 +23,7 @@ public class SearchSinglyLinkedListRecursion extends SinglyLinkedList {
|
||||
* {@code false}.
|
||||
*/
|
||||
private boolean searchRecursion(Node node, int key) {
|
||||
return (
|
||||
node != null &&
|
||||
(node.value == key || searchRecursion(node.next, key))
|
||||
);
|
||||
return (node != null && (node.value == key || searchRecursion(node.next, key)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -125,19 +125,20 @@ public class SinglyLinkedList extends Node {
|
||||
public Node reverseList(Node node) {
|
||||
Node prev = null;
|
||||
Node curr = node;
|
||||
|
||||
|
||||
while (curr != null && curr.next != null) {
|
||||
Node next=curr.next;
|
||||
Node next = curr.next;
|
||||
curr.next = prev;
|
||||
prev = curr;
|
||||
curr = next;
|
||||
}
|
||||
//when curr.next==null, the current element is left without pointing it to its prev,so
|
||||
if(curr != null){
|
||||
// when curr.next==null, the current element is left without pointing it to its prev,so
|
||||
if (curr != null) {
|
||||
curr.next = prev;
|
||||
prev=curr;
|
||||
prev = curr;
|
||||
}
|
||||
//prev will be pointing to the last element in the Linkedlist, it will be the new head of the reversed linkedlist
|
||||
// prev will be pointing to the last element in the Linkedlist, it will be the new head of
|
||||
// the reversed linkedlist
|
||||
return prev;
|
||||
}
|
||||
|
||||
@ -244,9 +245,7 @@ public class SinglyLinkedList extends Node {
|
||||
// skip all duplicates
|
||||
if (newHead.next != null && newHead.value == newHead.next.value) {
|
||||
// move till the end of duplicates sublist
|
||||
while (
|
||||
newHead.next != null && newHead.value == newHead.next.value
|
||||
) {
|
||||
while (newHead.next != null && newHead.value == newHead.next.value) {
|
||||
newHead = newHead.next;
|
||||
}
|
||||
// skip all duplicates
|
||||
@ -412,15 +411,10 @@ public class SinglyLinkedList extends Node {
|
||||
assert list.toString().equals("10->7->5->3->1");
|
||||
System.out.println(list);
|
||||
/* Test search function */
|
||||
assert list.search(10) &&
|
||||
list.search(5) &&
|
||||
list.search(1) &&
|
||||
!list.search(100);
|
||||
assert list.search(10) && list.search(5) && list.search(1) && !list.search(100);
|
||||
|
||||
/* Test get function */
|
||||
assert list.getNth(0) == 10 &&
|
||||
list.getNth(2) == 5 &&
|
||||
list.getNth(4) == 1;
|
||||
assert list.getNth(0) == 10 && list.getNth(2) == 5 && list.getNth(4) == 1;
|
||||
|
||||
/* Test delete function */
|
||||
list.deleteHead();
|
||||
@ -443,10 +437,7 @@ public class SinglyLinkedList extends Node {
|
||||
}
|
||||
|
||||
SinglyLinkedList instance = new SinglyLinkedList();
|
||||
Node head = new Node(
|
||||
0,
|
||||
new Node(2, new Node(3, new Node(3, new Node(4))))
|
||||
);
|
||||
Node head = new Node(0, new Node(2, new Node(3, new Node(3, new Node(4)))));
|
||||
instance.setHead(head);
|
||||
instance.deleteDuplicates();
|
||||
instance.print();
|
||||
@ -469,7 +460,8 @@ class Node {
|
||||
*/
|
||||
Node next;
|
||||
|
||||
Node() {}
|
||||
Node() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -189,25 +189,23 @@ public class SkipList<E extends Comparable<E>> {
|
||||
}
|
||||
|
||||
Collections.reverse(layers);
|
||||
String result = layers
|
||||
.stream()
|
||||
.map(layer -> {
|
||||
StringBuilder acc = new StringBuilder();
|
||||
for (boolean b : layer) {
|
||||
if (b) {
|
||||
acc.append("[ ]");
|
||||
} else {
|
||||
acc.append("---");
|
||||
}
|
||||
acc.append(" ");
|
||||
}
|
||||
return acc.toString();
|
||||
})
|
||||
.collect(Collectors.joining("\n"));
|
||||
String positions = IntStream
|
||||
.range(0, sizeWithHeader - 1)
|
||||
.mapToObj(i -> String.format("%3d", i))
|
||||
.collect(Collectors.joining(" "));
|
||||
String result = layers.stream()
|
||||
.map(layer -> {
|
||||
StringBuilder acc = new StringBuilder();
|
||||
for (boolean b : layer) {
|
||||
if (b) {
|
||||
acc.append("[ ]");
|
||||
} else {
|
||||
acc.append("---");
|
||||
}
|
||||
acc.append(" ");
|
||||
}
|
||||
return acc.toString();
|
||||
})
|
||||
.collect(Collectors.joining("\n"));
|
||||
String positions = IntStream.range(0, sizeWithHeader - 1)
|
||||
.mapToObj(i -> String.format("%3d", i))
|
||||
.collect(Collectors.joining(" "));
|
||||
|
||||
return result + String.format("%n H %s%n", positions);
|
||||
}
|
||||
@ -299,17 +297,14 @@ public class SkipList<E extends Comparable<E>> {
|
||||
public BernoulliHeightStrategy(double probability) {
|
||||
if (probability <= 0 || probability >= 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Probability should be from 0 to 1. But was: " + probability
|
||||
);
|
||||
"Probability should be from 0 to 1. But was: " + probability);
|
||||
}
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int height(int expectedSize) {
|
||||
long height = Math.round(
|
||||
Math.log10(expectedSize) / Math.log10(1 / probability)
|
||||
);
|
||||
long height = Math.round(Math.log10(expectedSize) / Math.log10(1 / probability));
|
||||
if (height > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.thealgorithms.datastructures.queues;
|
||||
|
||||
//This program implements the concept of CircularQueue in Java
|
||||
//Link to the concept: (https://en.wikipedia.org/wiki/Circular_buffer)
|
||||
// This program implements the concept of CircularQueue in Java
|
||||
// Link to the concept: (https://en.wikipedia.org/wiki/Circular_buffer)
|
||||
public class CircularQueue {
|
||||
|
||||
int[] arr;
|
||||
@ -23,7 +23,8 @@ public class CircularQueue {
|
||||
public boolean isFull() {
|
||||
if (topOfQueue + 1 == beginningOfQueue) {
|
||||
return true;
|
||||
} else return topOfQueue == size - 1 && beginningOfQueue == 0;
|
||||
} else
|
||||
return topOfQueue == size - 1 && beginningOfQueue == 0;
|
||||
}
|
||||
|
||||
public void enQueue(int value) {
|
||||
|
@ -124,11 +124,9 @@ public class LinkedQueue<T> implements Iterable<T> {
|
||||
|
||||
public T peek(int pos) {
|
||||
if (pos > size)
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Position %s out of range!".formatted(pos));
|
||||
throw new IndexOutOfBoundsException("Position %s out of range!".formatted(pos));
|
||||
Node<T> node = front;
|
||||
while (pos-- > 0)
|
||||
node = node.next;
|
||||
while (pos-- > 0) node = node.next;
|
||||
return node.data;
|
||||
}
|
||||
|
||||
@ -140,7 +138,6 @@ public class LinkedQueue<T> implements Iterable<T> {
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<>() {
|
||||
|
||||
Node<T> node = front;
|
||||
|
||||
@Override
|
||||
@ -168,16 +165,14 @@ public class LinkedQueue<T> implements Iterable<T> {
|
||||
* Clear all nodes in queue
|
||||
*/
|
||||
public void clear() {
|
||||
while (size > 0)
|
||||
dequeue();
|
||||
while (size > 0) dequeue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringJoiner join = new StringJoiner(", "); // separator of ', '
|
||||
Node<T> travel = front;
|
||||
while ((travel = travel.next) != null)
|
||||
join.add(String.valueOf(travel.data));
|
||||
while ((travel = travel.next) != null) join.add(String.valueOf(travel.data));
|
||||
return '[' + join.toString() + ']';
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
package com.thealgorithms.datastructures.queues;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements a PriorityQueue.
|
||||
*
|
||||
@ -126,7 +123,8 @@ class PriorityQueue {
|
||||
if (isEmpty()) {
|
||||
throw new RuntimeException("Queue is Empty");
|
||||
} else {
|
||||
int max = queueArray[1]; // By defintion of our max-heap, value at queueArray[1] pos is the greatest
|
||||
int max = queueArray[1]; // By defintion of our max-heap, value at queueArray[1] pos is
|
||||
// the greatest
|
||||
|
||||
// Swap max and last element
|
||||
int temp = queueArray[1];
|
||||
@ -175,4 +173,3 @@ class PriorityQueue {
|
||||
return nItems;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,16 +28,13 @@ class BalancedBrackets {
|
||||
*/
|
||||
public static boolean isPaired(char leftBracket, char rightBracket) {
|
||||
char[][] pairedBrackets = {
|
||||
{ '(', ')' },
|
||||
{ '[', ']' },
|
||||
{ '{', '}' },
|
||||
{ '<', '>' },
|
||||
{'(', ')'},
|
||||
{'[', ']'},
|
||||
{'{', '}'},
|
||||
{'<', '>'},
|
||||
};
|
||||
for (char[] pairedBracket : pairedBrackets) {
|
||||
if (
|
||||
pairedBracket[0] == leftBracket &&
|
||||
pairedBracket[1] == rightBracket
|
||||
) {
|
||||
if (pairedBracket[0] == leftBracket && pairedBracket[1] == rightBracket) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -58,24 +55,21 @@ class BalancedBrackets {
|
||||
Stack<Character> bracketsStack = new Stack<>();
|
||||
for (char bracket : brackets.toCharArray()) {
|
||||
switch (bracket) {
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
bracketsStack.push(bracket);
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
if (
|
||||
bracketsStack.isEmpty() ||
|
||||
!isPaired(bracketsStack.pop(), bracket)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* other character is invalid */
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
bracketsStack.push(bracket);
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
if (bracketsStack.isEmpty() || !isPaired(bracketsStack.pop(), bracket)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* other character is invalid */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return bracketsStack.isEmpty();
|
||||
|
@ -1,8 +1,12 @@
|
||||
/** Author : Siddhant Swarup Mallick
|
||||
/**
|
||||
* Author : Siddhant Swarup Mallick
|
||||
* Github : https://github.com/siddhant2002
|
||||
*/
|
||||
|
||||
/** Program description - Given an integer array. The task is to find the maximum of the minimum of the array */
|
||||
/**
|
||||
* Program description - Given an integer array. The task is to find the maximum of the minimum of
|
||||
* the array
|
||||
*/
|
||||
package com.thealgorithms.datastructures.stacks;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -24,12 +24,7 @@ public class DecimalToAnyUsingStack {
|
||||
private static String convert(int number, int radix) {
|
||||
if (radix < 2 || radix > 16) {
|
||||
throw new ArithmeticException(
|
||||
String.format(
|
||||
"Invalid input -> number:%d,radius:%d",
|
||||
number,
|
||||
radix
|
||||
)
|
||||
);
|
||||
String.format("Invalid input -> number:%d,radius:%d", number, radix));
|
||||
}
|
||||
char[] tables = {
|
||||
'0',
|
||||
|
@ -1,7 +1,8 @@
|
||||
package com.thealgorithms.datastructures.stacks;
|
||||
|
||||
// 1. You are given a string exp representing an expression.
|
||||
// 2. Assume that the expression is balanced i.e. the opening and closing brackets match with each other.
|
||||
// 2. Assume that the expression is balanced i.e. the opening and closing brackets match with each
|
||||
// other.
|
||||
// 3. But, some of the pair of brackets maybe extra/needless.
|
||||
// 4. You are required to print true if you detect extra brackets and false otherwise.
|
||||
// e.g.'
|
||||
|
@ -10,8 +10,7 @@ public class InfixToPostfix {
|
||||
assert "34+5*6-".equals(infix2PostFix("(3+4)*5-6"));
|
||||
}
|
||||
|
||||
public static String infix2PostFix(String infixExpression)
|
||||
throws Exception {
|
||||
public static String infix2PostFix(String infixExpression) throws Exception {
|
||||
if (!BalancedBrackets.isBalanced(infixExpression)) {
|
||||
throw new Exception("invalid expression");
|
||||
}
|
||||
@ -28,10 +27,7 @@ public class InfixToPostfix {
|
||||
}
|
||||
stack.pop();
|
||||
} else {
|
||||
while (
|
||||
!stack.isEmpty() &&
|
||||
precedence(element) <= precedence(stack.peek())
|
||||
) {
|
||||
while (!stack.isEmpty() && precedence(element) <= precedence(stack.peek())) {
|
||||
output.append(stack.pop());
|
||||
}
|
||||
stack.push(element);
|
||||
@ -45,16 +41,16 @@ public class InfixToPostfix {
|
||||
|
||||
private static int precedence(char operator) {
|
||||
switch (operator) {
|
||||
case '+':
|
||||
case '-':
|
||||
return 0;
|
||||
case '*':
|
||||
case '/':
|
||||
return 1;
|
||||
case '^':
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
case '+':
|
||||
case '-':
|
||||
return 0;
|
||||
case '*':
|
||||
case '/':
|
||||
return 1;
|
||||
case '^':
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class LargestRectangle {
|
||||
maxArea = Math.max(maxArea, tmp[1] * (i - tmp[0]));
|
||||
start = tmp[0];
|
||||
}
|
||||
st.push(new int[] { start, heights[i] });
|
||||
st.push(new int[] {start, heights[i]});
|
||||
}
|
||||
while (!st.isEmpty()) {
|
||||
int[] tmp = st.pop();
|
||||
@ -29,8 +29,7 @@ public class LargestRectangle {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
assert largestRectanglehistogram(new int[] { 2, 1, 5, 6, 2, 3 })
|
||||
.equals("10");
|
||||
assert largestRectanglehistogram(new int[] { 2, 4 }).equals("4");
|
||||
assert largestRectanglehistogram(new int[] {2, 1, 5, 6, 2, 3}).equals("10");
|
||||
assert largestRectanglehistogram(new int[] {2, 4}).equals("4");
|
||||
}
|
||||
}
|
||||
|
@ -97,8 +97,8 @@ public class MaximumMinimumWindow {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = new int[] { 10, 20, 30, 50, 10, 70, 30 };
|
||||
int[] target = new int[] { 70, 30, 20, 10, 10, 10, 10 };
|
||||
int[] arr = new int[] {10, 20, 30, 50, 10, 70, 30};
|
||||
int[] target = new int[] {70, 30, 20, 10, 10, 10, 10};
|
||||
int[] res = calculateMaxOfMin(arr, arr.length);
|
||||
assert Arrays.equals(target, res);
|
||||
}
|
||||
|
@ -37,7 +37,8 @@ import java.util.Stack;
|
||||
popped elements.
|
||||
d. Finally, push the next in the stack.
|
||||
|
||||
3. If elements are left in stack after completing while loop then their Next Grater element is -1.
|
||||
3. If elements are left in stack after completing while loop then their Next Grater element is
|
||||
-1.
|
||||
*/
|
||||
|
||||
public class NextGraterElement {
|
||||
@ -61,7 +62,7 @@ public class NextGraterElement {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] input = { 2, 7, 3, 5, 4, 6, 8 };
|
||||
int[] input = {2, 7, 3, 5, 4, 6, 8};
|
||||
int[] result = findNextGreaterElements(input);
|
||||
System.out.println(Arrays.toString(result));
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
|
||||
/*
|
||||
Given an array "input" you need to print the first smaller element for each element to the left side of an array.
|
||||
For a given element x of an array, the Next Smaller element of that element is the
|
||||
first smaller element to the left side of it. If no such element is present print -1.
|
||||
|
||||
Given an array "input" you need to print the first smaller element for each element to the left
|
||||
side of an array. For a given element x of an array, the Next Smaller element of that element is
|
||||
the first smaller element to the left side of it. If no such element is present print -1.
|
||||
|
||||
Example
|
||||
input = { 2, 7, 3, 5, 4, 6, 8 };
|
||||
At i = 0
|
||||
@ -24,17 +24,17 @@ import java.util.Stack;
|
||||
Next smaller element between (0 , 4) is 4
|
||||
At i = 6
|
||||
Next smaller element between (0 , 5) is 6
|
||||
|
||||
|
||||
result : [-1, 2, 2, 3, 3, 4, 6]
|
||||
|
||||
|
||||
1) Create a new empty stack st
|
||||
|
||||
|
||||
2) Iterate over array "input" , where "i" goes from 0 to input.length -1.
|
||||
a) We are looking for value just smaller than `input[i]`. So keep popping from "stack"
|
||||
a) We are looking for value just smaller than `input[i]`. So keep popping from "stack"
|
||||
till elements in "stack.peek() >= input[i]" or stack becomes empty.
|
||||
b) If the stack is non-empty, then the top element is our previous element. Else the previous element does not exist.
|
||||
c) push input[i] in stack.
|
||||
3) If elements are left then their answer is -1
|
||||
b) If the stack is non-empty, then the top element is our previous element. Else the
|
||||
previous element does not exist. c) push input[i] in stack. 3) If elements are left then their
|
||||
answer is -1
|
||||
*/
|
||||
|
||||
public class NextSmallerElement {
|
||||
@ -61,7 +61,7 @@ public class NextSmallerElement {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] input = { 2, 7, 3, 5, 4, 6, 8 };
|
||||
int[] input = {2, 7, 3, 5, 4, 6, 8};
|
||||
int[] result = findNextSmallerElements(input);
|
||||
System.out.println(Arrays.toString(result));
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ public class NodeStack<Item> {
|
||||
/**
|
||||
* Constructors for the NodeStack.
|
||||
*/
|
||||
public NodeStack() {}
|
||||
public NodeStack() {
|
||||
}
|
||||
|
||||
private NodeStack(Item item) {
|
||||
this.data = item;
|
||||
|
@ -20,12 +20,12 @@ public class PostfixToInfix {
|
||||
|
||||
public static boolean isOperator(char token) {
|
||||
switch (token) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '/':
|
||||
case '*':
|
||||
case '^':
|
||||
return true;
|
||||
case '+':
|
||||
case '-':
|
||||
case '/':
|
||||
case '*':
|
||||
case '^':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -42,7 +42,8 @@ public class PostfixToInfix {
|
||||
int operandCount = 0;
|
||||
int operatorCount = 0;
|
||||
|
||||
/* Traverse the postfix string to check if --> Number of operands = Number of operators + 1 */
|
||||
/* Traverse the postfix string to check if --> Number of operands = Number of operators + 1
|
||||
*/
|
||||
for (int i = 0; i < postfix.length(); i++) {
|
||||
char token = postfix.charAt(i);
|
||||
|
||||
@ -59,8 +60,8 @@ public class PostfixToInfix {
|
||||
|
||||
/* Operand count is set to 2 because:-
|
||||
*
|
||||
* 1) the previous set of operands & operators combined have become a single valid expression,
|
||||
* which could be considered/assigned as a single operand.
|
||||
* 1) the previous set of operands & operators combined have become a single valid
|
||||
* expression, which could be considered/assigned as a single operand.
|
||||
*
|
||||
* 2) the operand in the current iteration.
|
||||
*/
|
||||
@ -123,7 +124,6 @@ public class PostfixToInfix {
|
||||
assert getPostfixToInfix("AB+CD+*").equals("((A+B)*(C+D))");
|
||||
assert getPostfixToInfix("AB+C+D+").equals("(((A+B)+C)+D)");
|
||||
assert getPostfixToInfix("ABCDE^*/-").equals("(A-(B/(C*(D^E))))");
|
||||
assert getPostfixToInfix("AB+CD^/E*FGH+-^")
|
||||
.equals("((((A+B)/(C^D))*E)^(F-(G+H)))");
|
||||
assert getPostfixToInfix("AB+CD^/E*FGH+-^").equals("((((A+B)/(C^D))*E)^(F-(G+H)))");
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,7 @@ public class ReverseStack {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
System.out.println(
|
||||
"Enter the number of elements you wish to insert in the stack"
|
||||
);
|
||||
System.out.println("Enter the number of elements you wish to insert in the stack");
|
||||
int n = sc.nextInt();
|
||||
int i;
|
||||
Stack<Integer> stack = new Stack<Integer>();
|
||||
@ -36,28 +34,29 @@ public class ReverseStack {
|
||||
return;
|
||||
}
|
||||
|
||||
//Store the topmost element
|
||||
// Store the topmost element
|
||||
int element = stack.peek();
|
||||
//Remove the topmost element
|
||||
// Remove the topmost element
|
||||
stack.pop();
|
||||
|
||||
//Reverse the stack for the leftover elements
|
||||
// Reverse the stack for the leftover elements
|
||||
reverseStack(stack);
|
||||
|
||||
//Insert the topmost element to the bottom of the stack
|
||||
// Insert the topmost element to the bottom of the stack
|
||||
insertAtBottom(stack, element);
|
||||
}
|
||||
|
||||
private static void insertAtBottom(Stack<Integer> stack, int element) {
|
||||
if (stack.isEmpty()) {
|
||||
//When stack is empty, insert the element so it will be present at the bottom of the stack
|
||||
// When stack is empty, insert the element so it will be present at the bottom of the
|
||||
// stack
|
||||
stack.push(element);
|
||||
return;
|
||||
}
|
||||
|
||||
int ele = stack.peek();
|
||||
/*Keep popping elements till stack becomes empty. Push the elements once the topmost element has
|
||||
moved to the bottom of the stack.
|
||||
/*Keep popping elements till stack becomes empty. Push the elements once the topmost element
|
||||
has moved to the bottom of the stack.
|
||||
*/
|
||||
stack.pop();
|
||||
insertAtBottom(stack, element);
|
||||
|
@ -23,9 +23,7 @@ class StackOfLinkedList {
|
||||
assert stack.pop() == 5;
|
||||
assert stack.pop() == 4;
|
||||
|
||||
System.out.println(
|
||||
"Top element of stack currently is: " + stack.peek()
|
||||
);
|
||||
System.out.println("Top element of stack currently is: " + stack.peek());
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,9 +118,7 @@ class LinkedListStack {
|
||||
builder.append(cur.data).append("->");
|
||||
cur = cur.next;
|
||||
}
|
||||
return builder
|
||||
.replace(builder.length() - 2, builder.length(), "")
|
||||
.toString();
|
||||
return builder.replace(builder.length() - 2, builder.length(), "").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,23 +3,23 @@ package com.thealgorithms.datastructures.trees;
|
||||
/*
|
||||
* Avl is algo that balance itself while adding new alues to tree
|
||||
* by rotating branches of binary tree and make itself Binary seaarch tree
|
||||
* there are four cases which has to tackle
|
||||
* rotating - left right ,left left,right right,right left
|
||||
* there are four cases which has to tackle
|
||||
* rotating - left right ,left left,right right,right left
|
||||
|
||||
Test Case:
|
||||
|
||||
AVLTree tree=new AVLTree();
|
||||
tree.insert(20);
|
||||
tree.insert(25);
|
||||
tree.insert(30);
|
||||
tree.insert(10);
|
||||
tree.insert(5);
|
||||
tree.insert(15);
|
||||
tree.insert(27);
|
||||
tree.insert(19);
|
||||
tree.insert(16);
|
||||
|
||||
tree.display();
|
||||
tree.insert(20);
|
||||
tree.insert(25);
|
||||
tree.insert(30);
|
||||
tree.insert(10);
|
||||
tree.insert(5);
|
||||
tree.insert(15);
|
||||
tree.insert(27);
|
||||
tree.insert(19);
|
||||
tree.insert(16);
|
||||
|
||||
tree.display();
|
||||
|
||||
|
||||
|
||||
@ -59,16 +59,16 @@ public class AVLSimple {
|
||||
}
|
||||
node.height = Math.max(height(node.left), height(node.right)) + 1;
|
||||
int bf = bf(node);
|
||||
//LL case
|
||||
// LL case
|
||||
if (bf > 1 && item < node.left.data) return rightRotate(node);
|
||||
//RR case
|
||||
// RR case
|
||||
if (bf < -1 && item > node.right.data) return leftRotate(node);
|
||||
//RL case
|
||||
// RL case
|
||||
if (bf < -1 && item < node.right.data) {
|
||||
node.right = rightRotate(node.right);
|
||||
return leftRotate(node);
|
||||
}
|
||||
//LR case
|
||||
// LR case
|
||||
if (bf > 1 && item > node.left.data) {
|
||||
node.left = leftRotate(node.left);
|
||||
return rightRotate(node);
|
||||
@ -84,11 +84,15 @@ public class AVLSimple {
|
||||
|
||||
private void display(Node node) {
|
||||
String str = "";
|
||||
if (node.left != null) str += node.left.data + "=>"; else str +=
|
||||
"END=>";
|
||||
if (node.left != null)
|
||||
str += node.left.data + "=>";
|
||||
else
|
||||
str += "END=>";
|
||||
str += node.data + "";
|
||||
if (node.right != null) str += "<=" + node.right.data; else str +=
|
||||
"<=END";
|
||||
if (node.right != null)
|
||||
str += "<=" + node.right.data;
|
||||
else
|
||||
str += "<=END";
|
||||
System.out.println(str);
|
||||
if (node.left != null) display(node.left);
|
||||
if (node.right != null) display(node.right);
|
||||
|
@ -39,17 +39,20 @@ public class BSTRecursiveGeneric<T extends Comparable<T>> {
|
||||
integerTree.add(5);
|
||||
integerTree.add(10);
|
||||
integerTree.add(9);
|
||||
assert !integerTree.find(4) : "4 is not yet present in BST";
|
||||
assert integerTree.find(10) : "10 should be present in BST";
|
||||
assert !integerTree.find(4)
|
||||
: "4 is not yet present in BST";
|
||||
assert integerTree.find(10)
|
||||
: "10 should be present in BST";
|
||||
integerTree.remove(9);
|
||||
assert !integerTree.find(9) : "9 was just deleted from BST";
|
||||
assert !integerTree.find(9)
|
||||
: "9 was just deleted from BST";
|
||||
integerTree.remove(1);
|
||||
assert !integerTree.find(
|
||||
1
|
||||
) : "Since 1 was not present so find deleting would do no change";
|
||||
assert !integerTree.find(1)
|
||||
: "Since 1 was not present so find deleting would do no change";
|
||||
integerTree.add(20);
|
||||
integerTree.add(70);
|
||||
assert integerTree.find(70) : "70 was inserted but not found";
|
||||
assert integerTree.find(70)
|
||||
: "70 was inserted but not found";
|
||||
/*
|
||||
Will print in following order
|
||||
5 10 20 70
|
||||
@ -63,17 +66,20 @@ public class BSTRecursiveGeneric<T extends Comparable<T>> {
|
||||
stringTree.add("banana");
|
||||
stringTree.add("pineapple");
|
||||
stringTree.add("date");
|
||||
assert !stringTree.find("girl") : "girl is not yet present in BST";
|
||||
assert stringTree.find("pineapple") : "10 should be present in BST";
|
||||
assert !stringTree.find("girl")
|
||||
: "girl is not yet present in BST";
|
||||
assert stringTree.find("pineapple")
|
||||
: "10 should be present in BST";
|
||||
stringTree.remove("date");
|
||||
assert !stringTree.find("date") : "date was just deleted from BST";
|
||||
assert !stringTree.find("date")
|
||||
: "date was just deleted from BST";
|
||||
stringTree.remove("boy");
|
||||
assert !stringTree.find(
|
||||
"boy"
|
||||
) : "Since boy was not present so deleting would do no change";
|
||||
assert !stringTree.find("boy")
|
||||
: "Since boy was not present so deleting would do no change";
|
||||
stringTree.add("india");
|
||||
stringTree.add("hills");
|
||||
assert stringTree.find("hills") : "hills was inserted but not found";
|
||||
assert stringTree.find("hills")
|
||||
: "hills was inserted but not found";
|
||||
/*
|
||||
Will print in following order
|
||||
banana hills india pineapple
|
||||
|
@ -143,7 +143,8 @@ public class BinaryTree {
|
||||
if (temp.right == null && temp.left == null) {
|
||||
if (temp == root) {
|
||||
root = null;
|
||||
} // This if/else assigns the new node to be either the left or right child of the parent
|
||||
} // This if/else assigns the new node to be either the left or right child of the
|
||||
// parent
|
||||
else if (temp.parent.data < temp.data) {
|
||||
temp.parent.right = null;
|
||||
} else {
|
||||
@ -179,7 +180,8 @@ public class BinaryTree {
|
||||
else {
|
||||
successor.parent = temp.parent;
|
||||
|
||||
// This if/else assigns the new node to be either the left or right child of the parent
|
||||
// This if/else assigns the new node to be either the left or right child of the
|
||||
// parent
|
||||
if (temp.parent.data < temp.data) {
|
||||
temp.parent.right = successor;
|
||||
} else {
|
||||
|
@ -24,8 +24,6 @@ public class CheckBinaryTreeIsValidBST {
|
||||
}
|
||||
|
||||
return (
|
||||
isBSTUtil(node.left, min, node.data - 1) &&
|
||||
isBSTUtil(node.right, node.data + 1, max)
|
||||
);
|
||||
isBSTUtil(node.left, min, node.data - 1) && isBSTUtil(node.right, node.data + 1, max));
|
||||
}
|
||||
}
|
||||
|
@ -80,11 +80,7 @@ public class CheckIfBinaryTreeBalanced {
|
||||
* @param depth The current depth of the node
|
||||
* @param isBalanced The array of length 1 keeping track of our balance
|
||||
*/
|
||||
private int isBalancedRecursive(
|
||||
BTNode node,
|
||||
int depth,
|
||||
boolean[] isBalanced
|
||||
) {
|
||||
private int isBalancedRecursive(BTNode node, int depth, boolean[] isBalanced) {
|
||||
// If the node is null, we should not explore it and the height is 0
|
||||
// If the tree is already not balanced, might as well stop because we
|
||||
// can't make it balanced now!
|
||||
@ -94,11 +90,7 @@ public class CheckIfBinaryTreeBalanced {
|
||||
|
||||
// Visit the left and right children, incrementing their depths by 1
|
||||
int leftHeight = isBalancedRecursive(node.left, depth + 1, isBalanced);
|
||||
int rightHeight = isBalancedRecursive(
|
||||
node.right,
|
||||
depth + 1,
|
||||
isBalanced
|
||||
);
|
||||
int rightHeight = isBalancedRecursive(node.right, depth + 1, isBalanced);
|
||||
|
||||
// If the height of either of the left or right subtrees differ by more
|
||||
// than 1, we cannot be balanced
|
||||
@ -174,10 +166,7 @@ public class CheckIfBinaryTreeBalanced {
|
||||
|
||||
// The height of the subtree containing this node is the
|
||||
// max of the left and right subtree heighs plus 1
|
||||
subtreeHeights.put(
|
||||
node,
|
||||
Math.max(rightHeight, leftHeight) + 1
|
||||
);
|
||||
subtreeHeights.put(node, Math.max(rightHeight, leftHeight) + 1);
|
||||
|
||||
// We've now visited this node, so we pop it from the stack
|
||||
nodeStack.pop();
|
||||
|
@ -48,10 +48,12 @@ public class CheckTreeIsSymmetric {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isSymmetric(leftSubtreeRoot.right, rightSubtreRoot.left) && isSymmetric(leftSubtreeRoot.left, rightSubtreRoot.right);
|
||||
return isSymmetric(leftSubtreeRoot.right, rightSubtreRoot.left)
|
||||
&& isSymmetric(leftSubtreeRoot.left, rightSubtreRoot.right);
|
||||
}
|
||||
|
||||
private static boolean isInvalidSubtree(Node leftSubtreeRoot, Node rightSubtreeRoot) {
|
||||
return leftSubtreeRoot == null || rightSubtreeRoot == null || leftSubtreeRoot.data != rightSubtreeRoot.data;
|
||||
return leftSubtreeRoot == null || rightSubtreeRoot == null
|
||||
|| leftSubtreeRoot.data != rightSubtreeRoot.data;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import com.thealgorithms.datastructures.trees.BinaryTree.Node;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -37,13 +36,8 @@ public class CreateBinaryTreeFromInorderPreorder {
|
||||
return createTreeOptimized(preorder, inorderMap, 0, 0, inorder.length);
|
||||
}
|
||||
|
||||
private static Node createTree(
|
||||
final Integer[] preorder,
|
||||
final Integer[] inorder,
|
||||
final int preStart,
|
||||
final int inStart,
|
||||
final int size
|
||||
) {
|
||||
private static Node createTree(final Integer[] preorder, final Integer[] inorder,
|
||||
final int preStart, final int inStart, final int size) {
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
@ -55,32 +49,15 @@ public class CreateBinaryTreeFromInorderPreorder {
|
||||
}
|
||||
int leftNodesCount = i - inStart;
|
||||
int rightNodesCount = size - leftNodesCount - 1;
|
||||
root.left =
|
||||
createTree(
|
||||
preorder,
|
||||
inorder,
|
||||
preStart + 1,
|
||||
inStart,
|
||||
leftNodesCount
|
||||
);
|
||||
root.right =
|
||||
createTree(
|
||||
preorder,
|
||||
inorder,
|
||||
preStart + leftNodesCount + 1,
|
||||
i + 1,
|
||||
rightNodesCount
|
||||
);
|
||||
root.left = createTree(preorder, inorder, preStart + 1, inStart, leftNodesCount);
|
||||
root.right
|
||||
= createTree(preorder, inorder, preStart + leftNodesCount + 1, i + 1, rightNodesCount);
|
||||
return root;
|
||||
}
|
||||
|
||||
private static Node createTreeOptimized(
|
||||
final Integer[] preorder,
|
||||
final Map<Integer, Integer> inorderMap,
|
||||
final int preStart,
|
||||
final int inStart,
|
||||
final int size
|
||||
) {
|
||||
private static Node createTreeOptimized(final Integer[] preorder,
|
||||
final Map<Integer, Integer> inorderMap, final int preStart, final int inStart,
|
||||
final int size) {
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
@ -89,22 +66,10 @@ public class CreateBinaryTreeFromInorderPreorder {
|
||||
int i = inorderMap.get(preorder[preStart]);
|
||||
int leftNodesCount = i - inStart;
|
||||
int rightNodesCount = size - leftNodesCount - 1;
|
||||
root.left =
|
||||
createTreeOptimized(
|
||||
preorder,
|
||||
inorderMap,
|
||||
preStart + 1,
|
||||
inStart,
|
||||
leftNodesCount
|
||||
);
|
||||
root.right =
|
||||
createTreeOptimized(
|
||||
preorder,
|
||||
inorderMap,
|
||||
preStart + leftNodesCount + 1,
|
||||
i + 1,
|
||||
rightNodesCount
|
||||
);
|
||||
root.left
|
||||
= createTreeOptimized(preorder, inorderMap, preStart + 1, inStart, leftNodesCount);
|
||||
root.right = createTreeOptimized(
|
||||
preorder, inorderMap, preStart + leftNodesCount + 1, i + 1, rightNodesCount);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,7 @@ public class GenericTree {
|
||||
if (node == null) {
|
||||
System.out.println("Enter root's data");
|
||||
} else {
|
||||
System.out.println(
|
||||
"Enter data of parent of index " + node.data + " " + childindx
|
||||
);
|
||||
System.out.println("Enter data of parent of index " + node.data + " " + childindx);
|
||||
}
|
||||
// input
|
||||
node = new Node();
|
||||
|
@ -34,15 +34,11 @@ public class KDTree {
|
||||
* @param points Array of initial points
|
||||
*/
|
||||
KDTree(Point[] points) {
|
||||
if (points.length == 0) throw new IllegalArgumentException(
|
||||
"Points array cannot be empty"
|
||||
);
|
||||
if (points.length == 0) throw new IllegalArgumentException("Points array cannot be empty");
|
||||
this.k = points[0].getDimension();
|
||||
for (Point point : points) if (
|
||||
point.getDimension() != k
|
||||
) throw new IllegalArgumentException(
|
||||
"Points must have the same dimension"
|
||||
);
|
||||
for (Point point : points)
|
||||
if (point.getDimension() != k)
|
||||
throw new IllegalArgumentException("Points must have the same dimension");
|
||||
this.root = build(points, 0);
|
||||
}
|
||||
|
||||
@ -53,19 +49,13 @@ public class KDTree {
|
||||
*
|
||||
*/
|
||||
KDTree(int[][] pointsCoordinates) {
|
||||
if (pointsCoordinates.length == 0) throw new IllegalArgumentException(
|
||||
"Points array cannot be empty"
|
||||
);
|
||||
if (pointsCoordinates.length == 0)
|
||||
throw new IllegalArgumentException("Points array cannot be empty");
|
||||
this.k = pointsCoordinates[0].length;
|
||||
Point[] points = Arrays
|
||||
.stream(pointsCoordinates)
|
||||
.map(Point::new)
|
||||
.toArray(Point[]::new);
|
||||
for (Point point : points) if (
|
||||
point.getDimension() != k
|
||||
) throw new IllegalArgumentException(
|
||||
"Points must have the same dimension"
|
||||
);
|
||||
Point[] points = Arrays.stream(pointsCoordinates).map(Point::new).toArray(Point[] ::new);
|
||||
for (Point point : points)
|
||||
if (point.getDimension() != k)
|
||||
throw new IllegalArgumentException("Points must have the same dimension");
|
||||
this.root = build(points, 0);
|
||||
}
|
||||
|
||||
@ -125,11 +115,7 @@ public class KDTree {
|
||||
*
|
||||
* @return The distance between the two points
|
||||
*/
|
||||
public static int comparableDistanceExceptAxis(
|
||||
Point p1,
|
||||
Point p2,
|
||||
int axis
|
||||
) {
|
||||
public static int comparableDistanceExceptAxis(Point p1, Point p2, int axis) {
|
||||
int distance = 0;
|
||||
for (int i = 0; i < p1.getDimension(); i++) {
|
||||
if (i == axis) continue;
|
||||
@ -177,9 +163,10 @@ public class KDTree {
|
||||
* @return The nearest child Node
|
||||
*/
|
||||
public Node getNearChild(Point point) {
|
||||
if (
|
||||
point.getCoordinate(axis) < this.point.getCoordinate(axis)
|
||||
) return left; else return right;
|
||||
if (point.getCoordinate(axis) < this.point.getCoordinate(axis))
|
||||
return left;
|
||||
else
|
||||
return right;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,9 +177,10 @@ public class KDTree {
|
||||
* @return The farthest child Node
|
||||
*/
|
||||
public Node getFarChild(Point point) {
|
||||
if (
|
||||
point.getCoordinate(axis) < this.point.getCoordinate(axis)
|
||||
) return right; else return left;
|
||||
if (point.getCoordinate(axis) < this.point.getCoordinate(axis))
|
||||
return right;
|
||||
else
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -221,18 +209,11 @@ public class KDTree {
|
||||
if (points.length == 0) return null;
|
||||
int axis = depth % k;
|
||||
if (points.length == 1) return new Node(points[0], axis);
|
||||
Arrays.sort(
|
||||
points,
|
||||
Comparator.comparingInt(o -> o.getCoordinate(axis))
|
||||
);
|
||||
Arrays.sort(points, Comparator.comparingInt(o -> o.getCoordinate(axis)));
|
||||
int median = points.length >> 1;
|
||||
Node node = new Node(points[median], axis);
|
||||
node.left = build(Arrays.copyOfRange(points, 0, median), depth + 1);
|
||||
node.right =
|
||||
build(
|
||||
Arrays.copyOfRange(points, median + 1, points.length),
|
||||
depth + 1
|
||||
);
|
||||
node.right = build(Arrays.copyOfRange(points, median + 1, points.length), depth + 1);
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -243,9 +224,8 @@ public class KDTree {
|
||||
*
|
||||
*/
|
||||
public void insert(Point point) {
|
||||
if (point.getDimension() != k) throw new IllegalArgumentException(
|
||||
"Point has wrong dimension"
|
||||
);
|
||||
if (point.getDimension() != k)
|
||||
throw new IllegalArgumentException("Point has wrong dimension");
|
||||
root = insert(root, point, 0);
|
||||
}
|
||||
|
||||
@ -261,9 +241,10 @@ public class KDTree {
|
||||
private Node insert(Node root, Point point, int depth) {
|
||||
int axis = depth % k;
|
||||
if (root == null) return new Node(point, axis);
|
||||
if (point.getCoordinate(axis) < root.getAxisCoordinate()) root.left =
|
||||
insert(root.left, point, depth + 1); else root.right =
|
||||
insert(root.right, point, depth + 1);
|
||||
if (point.getCoordinate(axis) < root.getAxisCoordinate())
|
||||
root.left = insert(root.left, point, depth + 1);
|
||||
else
|
||||
root.right = insert(root.right, point, depth + 1);
|
||||
|
||||
return root;
|
||||
}
|
||||
@ -276,9 +257,8 @@ public class KDTree {
|
||||
* @return The Node corresponding to the specified point
|
||||
*/
|
||||
public Optional<Node> search(Point point) {
|
||||
if (point.getDimension() != k) throw new IllegalArgumentException(
|
||||
"Point has wrong dimension"
|
||||
);
|
||||
if (point.getDimension() != k)
|
||||
throw new IllegalArgumentException("Point has wrong dimension");
|
||||
return search(root, point);
|
||||
}
|
||||
|
||||
@ -323,9 +303,8 @@ public class KDTree {
|
||||
} else {
|
||||
Node left = findMin(root.left, axis);
|
||||
Node right = findMin(root.right, axis);
|
||||
Node[] candidates = { left, root, right };
|
||||
return Arrays
|
||||
.stream(candidates)
|
||||
Node[] candidates = {left, root, right};
|
||||
return Arrays.stream(candidates)
|
||||
.filter(Objects::nonNull)
|
||||
.min(Comparator.comparingInt(a -> a.point.getCoordinate(axis)))
|
||||
.orElse(null);
|
||||
@ -359,9 +338,8 @@ public class KDTree {
|
||||
} else {
|
||||
Node left = findMax(root.left, axis);
|
||||
Node right = findMax(root.right, axis);
|
||||
Node[] candidates = { left, root, right };
|
||||
return Arrays
|
||||
.stream(candidates)
|
||||
Node[] candidates = {left, root, right};
|
||||
return Arrays.stream(candidates)
|
||||
.filter(Objects::nonNull)
|
||||
.max(Comparator.comparingInt(a -> a.point.getCoordinate(axis)))
|
||||
.orElse(null);
|
||||
@ -374,8 +352,8 @@ public class KDTree {
|
||||
* @param point the point to delete
|
||||
* */
|
||||
public void delete(Point point) {
|
||||
Node node = search(point)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Point not found"));
|
||||
Node node
|
||||
= search(point).orElseThrow(() -> new IllegalArgumentException("Point not found"));
|
||||
root = delete(root, node);
|
||||
}
|
||||
|
||||
@ -398,12 +376,13 @@ public class KDTree {
|
||||
Node min = findMin(root.left, root.getAxis());
|
||||
root.point = min.point;
|
||||
root.left = delete(root.left, min);
|
||||
} else return null;
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
if (
|
||||
root.getAxisCoordinate() < node.point.getCoordinate(root.getAxis())
|
||||
) root.left = delete(root.left, node); else root.right =
|
||||
delete(root.right, node);
|
||||
if (root.getAxisCoordinate() < node.point.getCoordinate(root.getAxis()))
|
||||
root.left = delete(root.left, node);
|
||||
else
|
||||
root.right = delete(root.right, node);
|
||||
return root;
|
||||
}
|
||||
|
||||
@ -427,17 +406,12 @@ public class KDTree {
|
||||
if (root == null) return nearest;
|
||||
if (root.point.equals(point)) return root;
|
||||
int distance = Point.comparableDistance(root.point, point);
|
||||
int distanceExceptAxis = Point.comparableDistanceExceptAxis(
|
||||
root.point,
|
||||
point,
|
||||
root.getAxis()
|
||||
);
|
||||
if (distance < Point.comparableDistance(nearest.point, point)) nearest =
|
||||
root;
|
||||
int distanceExceptAxis
|
||||
= Point.comparableDistanceExceptAxis(root.point, point, root.getAxis());
|
||||
if (distance < Point.comparableDistance(nearest.point, point)) nearest = root;
|
||||
nearest = findNearest(root.getNearChild(point), point, nearest);
|
||||
if (
|
||||
distanceExceptAxis < Point.comparableDistance(nearest.point, point)
|
||||
) nearest = findNearest(root.getFarChild(point), point, nearest);
|
||||
if (distanceExceptAxis < Point.comparableDistance(nearest.point, point))
|
||||
nearest = findNearest(root.getFarChild(point), point, nearest);
|
||||
return nearest;
|
||||
}
|
||||
}
|
||||
|
@ -8,17 +8,17 @@ public class LCA {
|
||||
private static Scanner scanner = new Scanner(System.in);
|
||||
|
||||
public static void main(String[] args) {
|
||||
//The adjacency list representation of a tree:
|
||||
// The adjacency list representation of a tree:
|
||||
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
|
||||
|
||||
//v is the number of vertices and e is the number of edges
|
||||
// v is the number of vertices and e is the number of edges
|
||||
int v = scanner.nextInt(), e = v - 1;
|
||||
|
||||
for (int i = 0; i < v; i++) {
|
||||
adj.add(new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
//Storing the given tree as an adjacency list
|
||||
// Storing the given tree as an adjacency list
|
||||
int to, from;
|
||||
for (int i = 0; i < e; i++) {
|
||||
to = scanner.nextInt();
|
||||
@ -28,19 +28,19 @@ public class LCA {
|
||||
adj.get(from).add(to);
|
||||
}
|
||||
|
||||
//parent[v1] gives parent of a vertex v1
|
||||
// parent[v1] gives parent of a vertex v1
|
||||
int[] parent = new int[v];
|
||||
|
||||
//depth[v1] gives depth of vertex v1 with respect to the root
|
||||
// depth[v1] gives depth of vertex v1 with respect to the root
|
||||
int[] depth = new int[v];
|
||||
|
||||
//Assuming the tree to be rooted at 0, hence calculating parent and depth of every vertex
|
||||
// Assuming the tree to be rooted at 0, hence calculating parent and depth of every vertex
|
||||
dfs(adj, 0, -1, parent, depth);
|
||||
|
||||
//Inputting the two vertices whose LCA is to be calculated
|
||||
// Inputting the two vertices whose LCA is to be calculated
|
||||
int v1 = scanner.nextInt(), v2 = scanner.nextInt();
|
||||
|
||||
//Outputting the LCA
|
||||
// Outputting the LCA
|
||||
System.out.println(getLCA(v1, v2, depth, parent));
|
||||
}
|
||||
|
||||
@ -54,12 +54,7 @@ public class LCA {
|
||||
* @param depth An array to store depth of all vertices
|
||||
*/
|
||||
private static void dfs(
|
||||
ArrayList<ArrayList<Integer>> adj,
|
||||
int s,
|
||||
int p,
|
||||
int[] parent,
|
||||
int[] depth
|
||||
) {
|
||||
ArrayList<ArrayList<Integer>> adj, int s, int p, int[] parent, int[] depth) {
|
||||
for (int adjacent : adj.get(s)) {
|
||||
if (adjacent != p) {
|
||||
parent[adjacent] = s;
|
||||
|
@ -24,7 +24,8 @@ public class LazySegmentTree {
|
||||
this.right = null;
|
||||
}
|
||||
|
||||
/** Update the value of this node with the given value diff.
|
||||
/**
|
||||
* Update the value of this node with the given value diff.
|
||||
*
|
||||
* @param diff The value to add to every index of this node range.
|
||||
*/
|
||||
@ -33,7 +34,8 @@ public class LazySegmentTree {
|
||||
this.value += (this.end - this.start) * diff;
|
||||
}
|
||||
|
||||
/** Shift the lazy value of this node to its children.
|
||||
/**
|
||||
* Shift the lazy value of this node to its children.
|
||||
*/
|
||||
public void shift() {
|
||||
if (lazy == 0) return;
|
||||
@ -44,7 +46,8 @@ public class LazySegmentTree {
|
||||
this.lazy = 0;
|
||||
}
|
||||
|
||||
/** Create a new node that is the sum of this node and the given node.
|
||||
/**
|
||||
* Create a new node that is the sum of this node and the given node.
|
||||
*
|
||||
* @param left The left Node of merging
|
||||
* @param right The right Node of merging
|
||||
@ -53,11 +56,7 @@ public class LazySegmentTree {
|
||||
static Node merge(Node left, Node right) {
|
||||
if (left == null) return right;
|
||||
if (right == null) return left;
|
||||
Node result = new Node(
|
||||
left.start,
|
||||
right.end,
|
||||
left.value + right.value
|
||||
);
|
||||
Node result = new Node(left.start, right.end, left.value + right.value);
|
||||
result.left = left;
|
||||
result.right = right;
|
||||
return result;
|
||||
@ -78,7 +77,8 @@ public class LazySegmentTree {
|
||||
|
||||
private final Node root;
|
||||
|
||||
/** Create a new LazySegmentTree with the given array.
|
||||
/**
|
||||
* Create a new LazySegmentTree with the given array.
|
||||
*
|
||||
* @param array The array to create the LazySegmentTree from.
|
||||
*/
|
||||
@ -86,7 +86,8 @@ public class LazySegmentTree {
|
||||
this.root = buildTree(array, 0, array.length);
|
||||
}
|
||||
|
||||
/** Build a new LazySegmentTree from the given array in O(n) time.
|
||||
/**
|
||||
* Build a new LazySegmentTree from the given array in O(n) time.
|
||||
*
|
||||
* @param array The array to build the LazySegmentTree from.
|
||||
* @param start The start index of the current node.
|
||||
@ -101,7 +102,8 @@ public class LazySegmentTree {
|
||||
return Node.merge(left, right);
|
||||
}
|
||||
|
||||
/** Update the value of given range with the given value diff in O(log n) time.
|
||||
/**
|
||||
* Update the value of given range with the given value diff in O(log n) time.
|
||||
*
|
||||
* @param left The left index of the range to update.
|
||||
* @param right The right index of the range to update.
|
||||
@ -121,7 +123,8 @@ public class LazySegmentTree {
|
||||
curr.value = merge.value;
|
||||
}
|
||||
|
||||
/** Get Node of given range in O(log n) time.
|
||||
/**
|
||||
* Get Node of given range in O(log n) time.
|
||||
*
|
||||
* @param left The left index of the range to update.
|
||||
* @param right The right index of the range to update.
|
||||
@ -131,10 +134,7 @@ public class LazySegmentTree {
|
||||
if (left <= curr.start && curr.end <= right) return curr;
|
||||
if (left >= curr.end || right <= curr.start) return null;
|
||||
curr.shift();
|
||||
return Node.merge(
|
||||
getRange(left, right, curr.left),
|
||||
getRange(left, right, curr.right)
|
||||
);
|
||||
return Node.merge(getRange(left, right, curr.left), getRange(left, right, curr.right));
|
||||
}
|
||||
|
||||
public int getRange(int left, int right) {
|
||||
|
@ -28,14 +28,8 @@ public class RedBlackBST {
|
||||
return;
|
||||
}
|
||||
printTree(node.left);
|
||||
System.out.print(
|
||||
((node.color == R) ? " R " : " B ") +
|
||||
"Key: " +
|
||||
node.key +
|
||||
" Parent: " +
|
||||
node.p.key +
|
||||
"\n"
|
||||
);
|
||||
System.out.print(((node.color == R) ? " R " : " B ") + "Key: " + node.key
|
||||
+ " Parent: " + node.p.key + "\n");
|
||||
printTree(node.right);
|
||||
}
|
||||
|
||||
@ -43,14 +37,8 @@ public class RedBlackBST {
|
||||
if (node == nil) {
|
||||
return;
|
||||
}
|
||||
System.out.print(
|
||||
((node.color == R) ? " R " : " B ") +
|
||||
"Key: " +
|
||||
node.key +
|
||||
" Parent: " +
|
||||
node.p.key +
|
||||
"\n"
|
||||
);
|
||||
System.out.print(((node.color == R) ? " R " : " B ") + "Key: " + node.key
|
||||
+ " Parent: " + node.p.key + "\n");
|
||||
printTreepre(node.left);
|
||||
printTreepre(node.right);
|
||||
}
|
||||
|
@ -5,9 +5,8 @@ import java.util.Deque;
|
||||
|
||||
/**
|
||||
* Given 2 binary trees.
|
||||
* This code checks whether they are the same (structurally identical and have the same values) or not.
|
||||
* <p>
|
||||
* Example:
|
||||
* This code checks whether they are the same (structurally identical and have the same values) or
|
||||
* not. <p> Example:
|
||||
* 1. Binary trees:
|
||||
* 1 1
|
||||
* / \ / \
|
||||
|
@ -26,21 +26,14 @@ public class SegmentTree {
|
||||
}
|
||||
|
||||
int mid = start + (end - start) / 2;
|
||||
this.seg_t[index] =
|
||||
constructTree(arr, start, mid, index * 2 + 1) +
|
||||
constructTree(arr, mid + 1, end, index * 2 + 2);
|
||||
this.seg_t[index] = constructTree(arr, start, mid, index * 2 + 1)
|
||||
+ constructTree(arr, mid + 1, end, index * 2 + 2);
|
||||
return this.seg_t[index];
|
||||
}
|
||||
|
||||
/* A function which will update the value at a index i. This will be called by the
|
||||
update function internally*/
|
||||
private void updateTree(
|
||||
int start,
|
||||
int end,
|
||||
int index,
|
||||
int diff,
|
||||
int seg_index
|
||||
) {
|
||||
private void updateTree(int start, int end, int index, int diff, int seg_index) {
|
||||
if (index < start || index > end) {
|
||||
return;
|
||||
}
|
||||
@ -64,14 +57,9 @@ public class SegmentTree {
|
||||
updateTree(0, n - 1, index, diff, 0);
|
||||
}
|
||||
|
||||
/* A function to get the sum of the elements from index l to index r. This will be called internally*/
|
||||
private int getSumTree(
|
||||
int start,
|
||||
int end,
|
||||
int q_start,
|
||||
int q_end,
|
||||
int seg_index
|
||||
) {
|
||||
/* A function to get the sum of the elements from index l to index r. This will be called
|
||||
* internally*/
|
||||
private int getSumTree(int start, int end, int q_start, int q_end, int seg_index) {
|
||||
if (q_start <= start && q_end >= end) {
|
||||
return this.seg_t[seg_index];
|
||||
}
|
||||
@ -81,10 +69,8 @@ public class SegmentTree {
|
||||
}
|
||||
|
||||
int mid = start + (end - start) / 2;
|
||||
return (
|
||||
getSumTree(start, mid, q_start, q_end, seg_index * 2 + 1) +
|
||||
getSumTree(mid + 1, end, q_start, q_end, seg_index * 2 + 2)
|
||||
);
|
||||
return (getSumTree(start, mid, q_start, q_end, seg_index * 2 + 1)
|
||||
+ getSumTree(mid + 1, end, q_start, q_end, seg_index * 2 + 2));
|
||||
}
|
||||
|
||||
/* A function to query the sum of the subarray [start...end]*/
|
||||
|
@ -5,7 +5,8 @@ package com.thealgorithms.datastructures.trees;
|
||||
*/
|
||||
|
||||
/* PROBLEM DESCRIPTION :
|
||||
There is a Binary Search Tree given, and we are supposed to find a random node in the given binary tree.
|
||||
There is a Binary Search Tree given, and we are supposed to find a random node in the given binary
|
||||
tree.
|
||||
*/
|
||||
|
||||
/* ALGORITHM :
|
||||
@ -14,9 +15,9 @@ package com.thealgorithms.datastructures.trees;
|
||||
Step 3: Now use a method inOrder() that takes a node as input parameter to traverse through the
|
||||
binary tree in inorder fashion as also store the values in a ArrayList simultaneously.
|
||||
Step 4: Now define a method getRandom() that takes a node as input parameter, in this first call
|
||||
the inOrder() method to store the values in the arraylist, then find the size of the binary tree and now just generate a random number between 0 to n-1.
|
||||
Step 5: After generating the number display the value of the ArrayList at the generated index
|
||||
Step 6: STOP
|
||||
the inOrder() method to store the values in the arraylist, then find the size of the
|
||||
binary tree and now just generate a random number between 0 to n-1. Step 5: After generating the
|
||||
number display the value of the ArrayList at the generated index Step 6: STOP
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -65,7 +66,7 @@ public class TreeRandomNode {
|
||||
int n = list.size();
|
||||
int min = 0;
|
||||
int max = n - 1;
|
||||
//Generate random int value from 0 to n-1
|
||||
// Generate random int value from 0 to n-1
|
||||
int b = (int) (Math.random() * (max - min + 1) + min);
|
||||
// displaying the value at the generated index
|
||||
int random = list.get(b);
|
||||
@ -74,9 +75,10 @@ public class TreeRandomNode {
|
||||
}
|
||||
/* Explanation of the Approach :
|
||||
(a) Form the required binary tree
|
||||
(b) Now use the inOrder() method to get the nodes in inOrder fashion and also store them in the given arraylist 'list'
|
||||
(c) Using the getRandom() method generate a random number between 0 to n-1, then get the value at the generated random number
|
||||
from the arraylist using get() method and finally display the result.
|
||||
(b) Now use the inOrder() method to get the nodes in inOrder fashion and also store them in the
|
||||
given arraylist 'list' (c) Using the getRandom() method generate a random number between 0 to n-1,
|
||||
then get the value at the generated random number from the arraylist using get() method and
|
||||
finally display the result.
|
||||
*/
|
||||
/* OUTPUT :
|
||||
First output :
|
||||
|
@ -83,57 +83,56 @@ public class TrieImp {
|
||||
public static void main(String[] args) {
|
||||
TrieImp obj = new TrieImp();
|
||||
String word;
|
||||
@SuppressWarnings("resource")
|
||||
Scanner scan = new Scanner(System.in);
|
||||
@SuppressWarnings("resource") Scanner scan = new Scanner(System.in);
|
||||
sop("string should contain only a-z character for all operation");
|
||||
while (true) {
|
||||
sop("1. Insert\n2. Search\n3. Delete\n4. Quit");
|
||||
try {
|
||||
int t = scan.nextInt();
|
||||
switch (t) {
|
||||
case 1:
|
||||
word = scan.next();
|
||||
if (isValid(word)) {
|
||||
obj.insert(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
word = scan.next();
|
||||
boolean resS = false;
|
||||
if (isValid(word)) {
|
||||
resS = obj.search(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
if (resS) {
|
||||
sop("word found");
|
||||
} else {
|
||||
sop("word not found");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
word = scan.next();
|
||||
boolean resD = false;
|
||||
if (isValid(word)) {
|
||||
resD = obj.delete(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
if (resD) {
|
||||
sop("word got deleted successfully");
|
||||
} else {
|
||||
sop("word not found");
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
sop("Quit successfully");
|
||||
System.exit(1);
|
||||
break;
|
||||
default:
|
||||
sop("Input int from 1-4");
|
||||
break;
|
||||
case 1:
|
||||
word = scan.next();
|
||||
if (isValid(word)) {
|
||||
obj.insert(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
word = scan.next();
|
||||
boolean resS = false;
|
||||
if (isValid(word)) {
|
||||
resS = obj.search(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
if (resS) {
|
||||
sop("word found");
|
||||
} else {
|
||||
sop("word not found");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
word = scan.next();
|
||||
boolean resD = false;
|
||||
if (isValid(word)) {
|
||||
resD = obj.delete(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
if (resD) {
|
||||
sop("word got deleted successfully");
|
||||
} else {
|
||||
sop("word not found");
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
sop("Quit successfully");
|
||||
System.exit(1);
|
||||
break;
|
||||
default:
|
||||
sop("Input int from 1-4");
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String badInput = scan.next();
|
||||
|
@ -23,7 +23,7 @@ in a tree from top to bottom and left to right, so for a tree :
|
||||
public class VerticalOrderTraversal {
|
||||
|
||||
/*Function that receives a root Node and prints the tree
|
||||
in Vertical Order.*/
|
||||
in Vertical Order.*/
|
||||
public static ArrayList<Integer> verticalTraversal(BinaryTree.Node root) {
|
||||
if (root == null) {
|
||||
return new ArrayList<>();
|
||||
@ -32,19 +32,19 @@ public class VerticalOrderTraversal {
|
||||
/*Queue to store the Nodes.*/
|
||||
Queue<BinaryTree.Node> queue = new LinkedList<>();
|
||||
|
||||
/*Queue to store the index of particular vertical
|
||||
column of a tree , with root at 0, Nodes on left
|
||||
with negative index and Nodes on right with positive
|
||||
index. */
|
||||
/*Queue to store the index of particular vertical
|
||||
column of a tree , with root at 0, Nodes on left
|
||||
with negative index and Nodes on right with positive
|
||||
index. */
|
||||
Queue<Integer> index = new LinkedList<>();
|
||||
|
||||
/*Map of Integer and ArrayList to store all the
|
||||
elements in a particular index in a single arrayList
|
||||
that will have a key equal to the index itself. */
|
||||
/*Map of Integer and ArrayList to store all the
|
||||
elements in a particular index in a single arrayList
|
||||
that will have a key equal to the index itself. */
|
||||
Map<Integer, ArrayList<Integer>> map = new HashMap<>();
|
||||
|
||||
/* min and max stores leftmost and right most index to
|
||||
later print the tree in vertical fashion.*/
|
||||
later print the tree in vertical fashion.*/
|
||||
int max = 0, min = 0;
|
||||
queue.offer(root);
|
||||
index.offer(0);
|
||||
@ -52,38 +52,38 @@ public class VerticalOrderTraversal {
|
||||
while (!queue.isEmpty()) {
|
||||
if (queue.peek().left != null) {
|
||||
/*Adding the left Node if it is not null
|
||||
and its index by subtracting 1 from it's
|
||||
parent's index*/
|
||||
and its index by subtracting 1 from it's
|
||||
parent's index*/
|
||||
queue.offer(queue.peek().left);
|
||||
index.offer(index.peek() - 1);
|
||||
}
|
||||
if (queue.peek().right != null) {
|
||||
/*Adding the right Node if it is not null
|
||||
and its index by adding 1 from it's
|
||||
parent's index*/
|
||||
and its index by adding 1 from it's
|
||||
parent's index*/
|
||||
queue.offer(queue.peek().right);
|
||||
index.offer(index.peek() + 1);
|
||||
}
|
||||
/*If the map does not contains the index a new
|
||||
ArrayList is created with the index as key.*/
|
||||
ArrayList is created with the index as key.*/
|
||||
if (!map.containsKey(index.peek())) {
|
||||
ArrayList<Integer> a = new ArrayList<>();
|
||||
map.put(index.peek(), a);
|
||||
}
|
||||
/*For a index, corresponding Node data is added
|
||||
to the respective ArrayList present at that
|
||||
index. */
|
||||
to the respective ArrayList present at that
|
||||
index. */
|
||||
map.get(index.peek()).add(queue.peek().data);
|
||||
max = Math.max(max, index.peek());
|
||||
min = Math.min(min, index.peek());
|
||||
/*The Node and its index are removed
|
||||
from their respective queues.*/
|
||||
from their respective queues.*/
|
||||
index.poll();
|
||||
queue.poll();
|
||||
}
|
||||
/*Finally map data is printed here which has keys
|
||||
from min to max. Each ArrayList represents a
|
||||
vertical column that is added in ans ArrayList.*/
|
||||
from min to max. Each ArrayList represents a
|
||||
vertical column that is added in ans ArrayList.*/
|
||||
ArrayList<Integer> ans = new ArrayList<>();
|
||||
for (int i = min; i <= max; i++) {
|
||||
ans.addAll(map.get(i));
|
||||
|
@ -17,7 +17,8 @@ import java.util.*;
|
||||
* This solution implements the breadth-first search (BFS) algorithm using a queue.
|
||||
* 1. The algorithm starts with a root node. This node is added to a queue.
|
||||
* 2. While the queue is not empty:
|
||||
* - each time we enter the while-loop we get queue size. Queue size refers to the number of nodes at the current level.
|
||||
* - each time we enter the while-loop we get queue size. Queue size refers to the number of nodes
|
||||
* at the current level.
|
||||
* - we traverse all the level nodes in 2 ways: from left to right OR from right to left
|
||||
* (this state is stored on `prevLevelFromLeftToRight` variable)
|
||||
* - if the current node has children we add them to a queue
|
||||
|
@ -27,7 +27,7 @@ class Main {
|
||||
}
|
||||
|
||||
public static int nearestRightKey(NRKTree root, int x0) {
|
||||
//Check whether tree is empty
|
||||
// Check whether tree is empty
|
||||
if (root == null) {
|
||||
return 0;
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user