mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-29 15:34:21 +08:00
@ -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