Skip to content

Commit f534bd3

Browse files
authored
Merge branch 'master' into swap_improve
2 parents a012778 + b31bc86 commit f534bd3

File tree

5 files changed

+324
-62
lines changed

5 files changed

+324
-62
lines changed

DIRECTORY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@
560560
* [NonPreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java)
561561
* [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
562562
* [ProportionalFairScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/ProportionalFairScheduling.java)
563+
* [RandomScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RandomScheduling.java)
563564
* [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java)
564565
* [SelfAdjustingScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SelfAdjustingScheduling.java)
565566
* [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java)
@@ -911,6 +912,7 @@
911912
* [StackArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java)
912913
* [StackOfLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java)
913914
* trees
915+
* [AVLTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/AVLTreeTest.java)
914916
* [BinaryTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java)
915917
* [BoundaryTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BoundaryTraversalTest.java)
916918
* [BSTFromSortedArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java)
@@ -1192,6 +1194,7 @@
11921194
* [NonPreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java)
11931195
* [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
11941196
* [ProportionalFairSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/ProportionalFairSchedulingTest.java)
1197+
* [RandomSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RandomSchedulingTest.java)
11951198
* [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java)
11961199
* [SelfAdjustingSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SelfAdjustingSchedulingTest.java)
11971200
* [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java)

src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java

Lines changed: 82 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
package com.thealgorithms.datastructures.trees;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* Represents an AVL Tree, a self-balancing binary search tree.
8+
* In an AVL tree, the heights of the two child subtrees of any node
9+
* differ by at most one. If they differ by more than one at any time,
10+
* rebalancing is performed to restore this property.
11+
*/
312
public class AVLTree {
413

514
private Node root;
615

7-
private class Node {
8-
16+
private static class Node {
917
private int key;
1018
private int balance;
1119
private int height;
@@ -17,8 +25,18 @@ private class Node {
1725
key = k;
1826
parent = p;
1927
}
28+
29+
public Integer getBalance() {
30+
return balance;
31+
}
2032
}
2133

34+
/**
35+
* Inserts a new key into the AVL tree.
36+
*
37+
* @param key the key to be inserted
38+
* @return {@code true} if the key was inserted, {@code false} if the key already exists
39+
*/
2240
public boolean insert(int key) {
2341
if (root == null) {
2442
root = new Node(key, null);
@@ -31,7 +49,6 @@ public boolean insert(int key) {
3149
}
3250

3351
parent = n;
34-
3552
boolean goLeft = n.key > key;
3653
n = goLeft ? n.left : n.right;
3754

@@ -49,8 +66,32 @@ public boolean insert(int key) {
4966
return true;
5067
}
5168

69+
/**
70+
* Deletes a key from the AVL tree.
71+
*
72+
* @param delKey the key to be deleted
73+
*/
74+
public void delete(int delKey) {
75+
if (root == null) {
76+
return;
77+
}
78+
79+
// Find the node to be deleted
80+
Node node = root;
81+
Node child = root;
82+
while (child != null) {
83+
node = child;
84+
child = delKey >= node.key ? node.right : node.left;
85+
if (delKey == node.key) {
86+
delete(node);
87+
return;
88+
}
89+
}
90+
}
91+
5292
private void delete(Node node) {
5393
if (node.left == null && node.right == null) {
94+
// Leaf node
5495
if (node.parent == null) {
5596
root = null;
5697
} else {
@@ -64,6 +105,8 @@ private void delete(Node node) {
64105
}
65106
return;
66107
}
108+
109+
// Node has one or two children
67110
Node child;
68111
if (node.left != null) {
69112
child = node.left;
@@ -80,26 +123,49 @@ private void delete(Node node) {
80123
delete(child);
81124
}
82125

83-
public void delete(int delKey) {
84-
if (root == null) {
85-
return;
126+
/**
127+
* Returns a list of balance factors for each node in the tree.
128+
*
129+
* @return a list of integers representing the balance factors of the nodes
130+
*/
131+
public List<Integer> returnBalance() {
132+
List<Integer> balances = new ArrayList<>();
133+
returnBalance(root, balances);
134+
return balances;
135+
}
136+
137+
private void returnBalance(Node n, List<Integer> balances) {
138+
if (n != null) {
139+
returnBalance(n.left, balances);
140+
balances.add(n.getBalance());
141+
returnBalance(n.right, balances);
86142
}
87-
Node node = root;
88-
Node child = root;
143+
}
89144

90-
while (child != null) {
91-
node = child;
92-
child = delKey >= node.key ? node.right : node.left;
93-
if (delKey == node.key) {
94-
delete(node);
95-
return;
96-
}
145+
/**
146+
* Searches for a key in the AVL tree.
147+
*
148+
* @param key the key to be searched
149+
* @return true if the key is found, false otherwise
150+
*/
151+
public boolean search(int key) {
152+
Node result = searchHelper(this.root, key);
153+
return result != null;
154+
}
155+
156+
private Node searchHelper(Node root, int key) {
157+
if (root == null || root.key == key) {
158+
return root;
97159
}
160+
161+
if (root.key > key) {
162+
return searchHelper(root.left, key);
163+
}
164+
return searchHelper(root.right, key);
98165
}
99166

100167
private void rebalance(Node n) {
101168
setBalance(n);
102-
103169
if (n.balance == -2) {
104170
if (height(n.left.left) >= height(n.left.right)) {
105171
n = rotateRight(n);
@@ -143,7 +209,6 @@ private Node rotateLeft(Node a) {
143209
}
144210

145211
setBalance(a, b);
146-
147212
return b;
148213
}
149214

@@ -169,7 +234,6 @@ private Node rotateRight(Node a) {
169234
}
170235

171236
setBalance(a, b);
172-
173237
return b;
174238
}
175239

@@ -197,53 +261,9 @@ private void setBalance(Node... nodes) {
197261
}
198262
}
199263

200-
public void printBalance() {
201-
printBalance(root);
202-
}
203-
204-
private void printBalance(Node n) {
205-
if (n != null) {
206-
printBalance(n.left);
207-
System.out.printf("%s ", n.balance);
208-
printBalance(n.right);
209-
}
210-
}
211-
212264
private void reheight(Node node) {
213265
if (node != null) {
214266
node.height = 1 + Math.max(height(node.left), height(node.right));
215267
}
216268
}
217-
218-
public boolean search(int key) {
219-
Node result = searchHelper(this.root, key);
220-
return result != null;
221-
}
222-
223-
private Node searchHelper(Node root, int key) {
224-
// root is null or key is present at root
225-
if (root == null || root.key == key) {
226-
return root;
227-
}
228-
229-
// key is greater than root's key
230-
if (root.key > key) {
231-
return searchHelper(root.left, key); // call the function on the node's left child
232-
}
233-
// key is less than root's key then
234-
// call the function on the node's right child as it is greater
235-
return searchHelper(root.right, key);
236-
}
237-
238-
public static void main(String[] args) {
239-
AVLTree tree = new AVLTree();
240-
241-
System.out.println("Inserting values 1 to 10");
242-
for (int i = 1; i < 10; i++) {
243-
tree.insert(i);
244-
}
245-
246-
System.out.print("Printing balance: ");
247-
tree.printBalance();
248-
}
249269
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.thealgorithms.scheduling;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import java.util.Random;
8+
9+
/**
10+
* RandomScheduling is an algorithm that assigns tasks in a random order.
11+
* It doesn't consider priority, deadlines, or burst times, making it
12+
* inefficient but useful in scenarios where fairness or unpredictability
13+
* is required (e.g., load balancing in distributed systems).
14+
*
15+
* Use Case: Distributed systems where randomness helps avoid task starvation.
16+
*
17+
* @author Hardvan
18+
*/
19+
public final class RandomScheduling {
20+
21+
private final List<String> tasks;
22+
private final Random random;
23+
24+
/**
25+
* Constructs a new RandomScheduling instance.
26+
*
27+
* @param tasks A collection of task names to be scheduled.
28+
* @param random A Random instance for generating random numbers.
29+
*/
30+
public RandomScheduling(Collection<String> tasks, Random random) {
31+
this.tasks = new ArrayList<>(tasks);
32+
this.random = random;
33+
}
34+
35+
/**
36+
* Schedules the tasks randomly and returns the randomized order.
37+
*
38+
* @return A list representing the tasks in their randomized execution order.
39+
*/
40+
public List<String> schedule() {
41+
List<String> shuffledTasks = new ArrayList<>(tasks);
42+
Collections.shuffle(shuffledTasks, random);
43+
return shuffledTasks;
44+
}
45+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.thealgorithms.datastructures.trees;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import java.util.List;
8+
import org.junit.jupiter.api.BeforeEach;
9+
import org.junit.jupiter.api.Test;
10+
11+
public class AVLTreeTest {
12+
private AVLTree avlTree;
13+
14+
@BeforeEach
15+
public void setUp() {
16+
avlTree = new AVLTree();
17+
}
18+
19+
@Test
20+
public void testInsert() {
21+
assertTrue(avlTree.insert(10));
22+
assertTrue(avlTree.insert(20));
23+
assertTrue(avlTree.insert(5));
24+
assertFalse(avlTree.insert(10)); // Duplicate
25+
}
26+
27+
@Test
28+
public void testSearch() {
29+
avlTree.insert(15);
30+
avlTree.insert(25);
31+
assertTrue(avlTree.search(15));
32+
assertFalse(avlTree.search(30)); // Not in the tree
33+
}
34+
35+
@Test
36+
public void testDeleteLeafNode() {
37+
avlTree.insert(10);
38+
avlTree.insert(20);
39+
avlTree.insert(30);
40+
avlTree.delete(30);
41+
assertFalse(avlTree.search(30));
42+
}
43+
44+
@Test
45+
public void testDeleteNodeWithOneChild() {
46+
avlTree.insert(20);
47+
avlTree.insert(10);
48+
avlTree.insert(30);
49+
avlTree.delete(10);
50+
assertFalse(avlTree.search(10));
51+
}
52+
53+
@Test
54+
public void testDeleteNodeWithTwoChildren() {
55+
avlTree.insert(20);
56+
avlTree.insert(10);
57+
avlTree.insert(30);
58+
avlTree.insert(25);
59+
avlTree.delete(20);
60+
assertFalse(avlTree.search(20));
61+
assertTrue(avlTree.search(30));
62+
assertTrue(avlTree.search(25));
63+
}
64+
65+
@Test
66+
public void testReturnBalance() {
67+
avlTree.insert(10);
68+
avlTree.insert(20);
69+
avlTree.insert(5);
70+
List<Integer> balances = avlTree.returnBalance();
71+
assertEquals(3, balances.size()); // There should be 3 nodes
72+
assertEquals(0, balances.get(0)); // Balance for node 5
73+
assertEquals(0, balances.get(1)); // Balance for node 10
74+
assertEquals(0, balances.get(2)); // Balance for node 20
75+
}
76+
77+
@Test
78+
public void testInsertAndRebalance() {
79+
avlTree.insert(30);
80+
avlTree.insert(20);
81+
avlTree.insert(10); // This should cause a right rotation
82+
assertTrue(avlTree.search(20));
83+
assertTrue(avlTree.search(10));
84+
assertTrue(avlTree.search(30));
85+
}
86+
87+
@Test
88+
public void testComplexInsertionAndDeletion() {
89+
avlTree.insert(30);
90+
avlTree.insert(20);
91+
avlTree.insert(10);
92+
avlTree.insert(25);
93+
avlTree.insert(5);
94+
avlTree.insert(15);
95+
96+
avlTree.delete(20); // Test deletion
97+
assertFalse(avlTree.search(20));
98+
assertTrue(avlTree.search(30));
99+
assertTrue(avlTree.search(25));
100+
}
101+
}

0 commit comments

Comments
 (0)