0% found this document useful (0 votes)
5 views

codes

The document contains multiple Java code implementations for various tree and graph algorithms, including recovering a Binary Search Tree (BST), boundary traversal of a binary tree, different views of a tree (left, right, top, bottom), and graph traversal methods (BFS and DFS). Each section includes class definitions, methods for traversal or recovery, and examples of how to construct and test these algorithms. Additionally, it covers Dial's algorithm for finding shortest paths in a graph using buckets.

Uploaded by

Stuti Dhingra
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

codes

The document contains multiple Java code implementations for various tree and graph algorithms, including recovering a Binary Search Tree (BST), boundary traversal of a binary tree, different views of a tree (left, right, top, bottom), and graph traversal methods (BFS and DFS). Each section includes class definitions, methods for traversal or recovery, and examples of how to construct and test these algorithms. Additionally, it covers Dial's algorithm for finding shortest paths in a graph using buckets.

Uploaded by

Stuti Dhingra
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

CODES:

recovering bst
/*
This code simulates recovering a BST by recovering its in-order traversal array.
In a correct BST, an in-order traversal yields a sorted array.
If two nodes are swapped, the array will have one or two inversions.
This program identifies those inversions and swaps the elements back.
*/
public class RecoverBST {

// Function to recover the "BST" represented as a sorted array with two swap
ped elements.
public static void recover(int[] arr) {
int n = arr.length;
int first = -1, second = -1;

// Scan the array to find the first and possibly the second inversion.
for (int i = 0; i < n - 1; i++) {
if (arr[i] > arr[i + 1]) {
// For the first inversion, mark the first element as 'first' and the next el
ement as 'second'.
if (first == -1) {
first = i;
second = i + 1;
} else {
// For a later inversion, update 'second'.
second = i + 1;
break;
}
}
}

// If swapped elements were found, swap them back.

CODES: 1
if (first != -1 && second != -1) {
int temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
}

// Utility method to print the array.


public static void printArray(int[] arr) {
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
}

// Main method to test the recovery.


public static void main(String[] args) {
// Example: An array that represents the in-order traversal of a BST.
// Ideally, it should be sorted, e.g., 1, 2, 3, 4, 5.
// Here, suppose two elements (3 and 2) are swapped: 1, 3, 2, 4, 5.
int[] bstInOrder = {1, 3, 2, 4, 5};

System.out.println("Before recovery:");
printArray(bstInOrder);

recover(bstInOrder);

System.out.println("After recovery:");
printArray(bstInOrder);
}

BOUNDARY TRAVERSAL:

public class BoundaryTraversal {

CODES: 2
// Node class for binary tree
static class Node {
int data;
Node left, right;

Node(int data) {
this.data = data;
left = right = null;
}
}

// Print the left boundary (excluding leaf nodes)


void printLeftBoundary(Node node) {
if (node != null) {
if (node.left != null) {
// Print the node before calling recursively for top-down order.
System.out.print(node.data + " ");
printLeftBoundary(node.left);
} else if (node.right != null) {
// If no left child exists, use the right child.
System.out.print(node.data + " ");
printLeftBoundary(node.right);
}
// Do nothing if it's a leaf node.
}
}

// Print all leaf nodes in left-to-right order.


void printLeaves(Node node) {
if (node != null) {
printLeaves(node.left);
if (node.left == null && node.right == null) {
System.out.print(node.data + " ");
}
printLeaves(node.right);

CODES: 3
}
}

// Print the right boundary (excluding leaf nodes) in bottom-up order.


void printRightBoundary(Node node) {
if (node != null) {
if (node.right != null) {
// First, recursively go to the right.
printRightBoundary(node.right);
System.out.print(node.data + " ");
} else if (node.left != null) {
// If no right child exists, use the left child.
printRightBoundary(node.left);
System.out.print(node.data + " ");
}
// Do nothing if it's a leaf node.
}
}

// Function to perform the boundary traversal.


void printBoundary(Node root) {
if (root != null) {
// Print the root.
System.out.print(root.data + " ");

// Print the left boundary excluding the root and leaves.


printLeftBoundary(root.left);

// Print all leaf nodes.


printLeaves(root.left);
printLeaves(root.right);

// Print the right boundary excluding the root and leaves.


printRightBoundary(root.right);
}
}

CODES: 4
// Main method to test the boundary traversal.
public static void main(String[] args) {
BoundaryTraversal bt = new BoundaryTraversal();

/* Construct the following binary tree:


20
/ \\
8 22
/ \\ \\
4 12 25
/ \\
10 14
*/
Node root = new Node(20);
root.left = new Node(8);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
root.right = new Node(22);
root.right.right = new Node(25);

System.out.println("Boundary traversal of the binary tree is:");


bt.printBoundary(root);
}

VIEWS OF TREE:

import java.util.*;
public class TreeViews {

// Node class representing each node in the binary tree


static class Node {

CODES: 5
int data;
Node left, right;
Node(int data) {
this.data = data;
left = right = null;
}
}

// -------------------- Left View --------------------


// Prints the left view of the tree using recursion.
public static void printLeftView(Node root) {
leftViewUtil(root, 1, new int[]{0});
System.out.println();
}

// Helper method for left view.


private static void leftViewUtil(Node node, int level, int[] maxLevel) {
if (node == null) return;
// If this is the first node of its level, print it.
if (maxLevel[0] < level) {
System.out.print(node.data + " ");
maxLevel[0] = level;
}
leftViewUtil(node.left, level + 1, maxLevel);
leftViewUtil(node.right, level + 1, maxLevel);
}

// -------------------- Right View --------------------


// Prints the right view of the tree using recursion.
public static void printRightView(Node root) {
rightViewUtil(root, 1, new int[]{0});
System.out.println();
}

// Helper method for right view.


private static void rightViewUtil(Node node, int level, int[] maxLevel) {

CODES: 6
if (node == null) return;
// If this is the first node of its level (traversing right first), print it.
if (maxLevel[0] < level) {
System.out.print(node.data + " ");
maxLevel[0] = level;
}
rightViewUtil(node.right, level + 1, maxLevel);
rightViewUtil(node.left, level + 1, maxLevel);
}

// -------------------- Top View --------------------


// Prints the top view of the tree using level-order traversal.
public static void printTopView(Node root) {
if (root == null) return;
// TreeMap to keep horizontal distances in sorted order.
Map<Integer, Integer> topViewMap = new TreeMap<>();
Queue<QueueObj> queue = new LinkedList<>();
queue.add(new QueueObj(root, 0));

while (!queue.isEmpty()) {
QueueObj temp = queue.poll();
int hd = temp.hd;
// For top view, we add the first node encountered at a horizontal distanc
e.
if (!topViewMap.containsKey(hd)) {
topViewMap.put(hd, temp.node.data);
}
if (temp.node.left != null) {
queue.add(new QueueObj(temp.node.left, hd - 1));
}
if (temp.node.right != null) {
queue.add(new QueueObj(temp.node.right, hd + 1));
}
}

for (int val : topViewMap.values()) {

CODES: 7
System.out.print(val + " ");
}
System.out.println();
}

// -------------------- Bottom View --------------------


// Prints the bottom view of the tree using level-order traversal.
public static void printBottomView(Node root) {
if (root == null) return;
// TreeMap to keep horizontal distances in sorted order.
Map<Integer, Integer> bottomViewMap = new TreeMap<>();
Queue<QueueObj> queue = new LinkedList<>();
queue.add(new QueueObj(root, 0));

while (!queue.isEmpty()) {
QueueObj temp = queue.poll();
int hd = temp.hd;
// For bottom view, update the map entry at each horizontal distance.
bottomViewMap.put(hd, temp.node.data);

if (temp.node.left != null) {
queue.add(new QueueObj(temp.node.left, hd - 1));
}
if (temp.node.right != null) {
queue.add(new QueueObj(temp.node.right, hd + 1));
}
}

for (int val : bottomViewMap.values()) {


System.out.print(val + " ");
}
System.out.println();
}

// -------------------- Helper Class --------------------


// This class stores a tree node along with its horizontal distance (hd) from the

CODES: 8
root.
static class QueueObj {
Node node;
int hd;
QueueObj(Node node, int hd) {
this.node = node;
this.hd = hd;
}
}

// -------------------- Main Method --------------------


public static void main(String[] args) {
/*
Construct the following binary tree:

1
/ \\
2 3
/ \\ / \\
4 56 7
*/
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);

System.out.println("Left View of the tree:");


printLeftView(root);

System.out.println("Right View of the tree:");


printRightView(root);

System.out.println("Top View of the tree:");

CODES: 9
printTopView(root);

System.out.println("Bottom View of the tree:");


printBottomView(root);
}

BFS , DFS

import java.util.*;
public class GraphTraversal {
private int V; // Number of vertices
private LinkedList<Integer>[] adj; // Adjacency lists

// Constructor to initialize the graph with a given number of vertices.


public GraphTraversal(int v) {
V = v;
adj = new LinkedList[v];
for (int i = 0; i < v; i++) {
adj[i] = new LinkedList<>();
}
}

// Add an edge from vertex v to vertex w.


public void addEdge(int v, int w) {
adj[v].add(w);
}

// Breadth-First Search starting from vertex s.


public void BFS(int s) {
boolean[] visited = new boolean[V];
Queue<Integer> queue = new LinkedList<>();

CODES: 10
visited[s] = true;
queue.add(s);

while (!queue.isEmpty()) {
int vertex = queue.poll();
System.out.print(vertex + " ");

for (int neighbor : adj[vertex]) {


if (!visited[neighbor]) {
visited[neighbor] = true;
queue.add(neighbor);
}
}
}
}

// Utility method for Depth-First Search.


private void DFSUtil(int v, boolean[] visited) {
visited[v] = true;
System.out.print(v + " ");

for (int neighbor : adj[v]) {


if (!visited[neighbor]) {
DFSUtil(neighbor, visited);
}
}
}

// Depth-First Search starting from vertex s.


public void DFS(int s) {
boolean[] visited = new boolean[V];
DFSUtil(s, visited);
}

// Main method to test BFS and DFS.


public static void main(String[] args) {

CODES: 11
GraphTraversal graph = new GraphTraversal(4);

// Constructing a sample graph:


// Vertex 0 -> 1, 2
// Vertex 1 -> 2
// Vertex 2 -> 0, 3
// Vertex 3 -> 3 (self loop)
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 2);
graph.addEdge(2, 0);
graph.addEdge(2, 3);
graph.addEdge(3, 3);

System.out.println("BFS starting from vertex 2:");


graph.BFS(2);

System.out.println("\\nDFS starting from vertex 2:");


graph.DFS(2);
}

DIAL’S ALGO

import java.util.*;
class Node {
int vertex;
int weight;

Node(int vertex, int weight) {


this.vertex = vertex;

CODES: 12
this.weight = weight;
}

class Graph {
private int V; // Number of vertices
private List<List<Node>> adj; // Adjacency list

// Constructor to initialize the graph


public Graph(int V) {
this.V = V;
adj = new ArrayList<>(V);
for (int i = 0; i < V; i++) {
adj.add(new ArrayList<>());
}
}

// Add an edge from 'source' to 'destination' with given 'weight'


public void addEdge(int source, int destination, int weight) {
adj.get(source).add(new Node(destination, weight));
}

// Dial's Algorithm to find shortest paths from 'startVertex'


public void dialsAlgorithm(int startVertex) {
// Distance array, initialized to infinity
int[] distance = new int[V];
Arrays.fill(distance, Integer.MAX_VALUE);
distance[startVertex] = 0;

// Find the maximum edge weight (assumes edges have non-negative integ
er weights)
int maxEdgeWeight = 0;
for (int i = 0; i < V; i++) {
for (Node node : adj.get(i)) {
maxEdgeWeight = Math.max(maxEdgeWeight, node.weight);

CODES: 13
}
}

// Upper bound on distance could be (maxEdgeWeight * (V-1)), but we'll be


safe:
int maxDistance = maxEdgeWeight * V;

// Buckets: each index corresponds to a distance; stores vertices with that


distance
List<List<Integer>> buckets = new ArrayList<>(maxDistance + 1);
for (int i = 0; i <= maxDistance; i++) {
buckets.add(new ArrayList<>());
}

// Place the start vertex in the 0-distance bucket


buckets.get(0).add(startVertex);

// Current bucket index


int currentDistance = 0;

// Process vertices in the buckets


while (currentDistance <= maxDistance) {
// If the current bucket is empty, move to the next
if (buckets.get(currentDistance).isEmpty()) {
currentDistance++;
continue;
}

// Pop a vertex from the current bucket


int u = buckets.get(currentDistance)
.remove(buckets.get(currentDistance).size() - 1);

// If distance[u] has changed since it was placed here, skip it


if (distance[u] != currentDistance) {
continue;
}

CODES: 14
// Relax edges from u
for (Node edge : adj.get(u)) {
int v = edge.vertex;
int w = edge.weight;

// If a shorter path is found


if (distance[v] > distance[u] + w) {
// Remove from old bucket if needed (not strictly required in this ver
sion)
distance[v] = distance[u] + w;

// Add vertex v to the new bucket


buckets.get(distance[v]).add(v);
}
}
}

// Print the shortest distances


System.out.println("Shortest distances from vertex " + startVertex + ":");
for (int i = 0; i < V; i++) {
System.out.println("Distance to " + i + " = " + distance[i]);
}
}

// For demonstration
public static void main(String[] args) {
// Create a graph with 5 vertices (0 to 4)
Graph graph = new Graph(5);

// Add edges (source, destination, weight)


// Example:
// 0 -> 1 (weight 2), 0 -> 2 (weight 4)
// 1 -> 2 (weight 1), 1 -> 3 (weight 7)
// 2 -> 4 (weight 3), 3 -> 4 (weight 1)
graph.addEdge(0, 1, 2);

CODES: 15
graph.addEdge(0, 2, 4);
graph.addEdge(1, 2, 1);
graph.addEdge(1, 3, 7);
graph.addEdge(2, 4, 3);
graph.addEdge(3, 4, 1);

// Run Dial's Algorithm from vertex 0


graph.dialsAlgorithm(0);
}

BELLMAN FORD:

import java.util.Arrays;
class BellmanFord {

// This class represents a directed edge from 'src' to 'dest' with a given 'weig
ht'.
static class Edge {
int src, dest, weight;
Edge(int src, int dest, int weight) {
this.src = src;
this.dest = dest;
this.weight = weight;
}
}

private int V; // Number of vertices


private int E; // Number of edges
private Edge[] edges; // List of edges

// Constructor: Create a graph with V vertices and E edges


BellmanFord(int v, int e) {

CODES: 16
V = v;
E = e;
edges = new Edge[e];
}

// Adds an edge to the edge list


public void addEdge(int index, int src, int dest, int weight) {
edges[index] = new Edge(src, dest, weight);
}

/**
* Runs Bellman-Ford algorithm from the given 'start' vertex.
*
* If there is a negative cycle reachable from 'start',
* the algorithm will report it.
*/
public void bellmanFord(int start) {
// Step 1: Initialize distances from start to all other vertices
int[] dist = new int[V];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[start] = 0;

// Step 2: Relax all edges V-1 times


// Each relaxation can potentially improve the distance to a vertex.
for (int i = 1; i < V; i++) {
for (int j = 0; j < E; j++) {
Edge edge = edges[j];
int u = edge.src;
int v = edge.dest;
int w = edge.weight;

// If distance to u is not "infinity" and we can improve dist[v], relax it


if (dist[u] != Integer.MAX_VALUE && dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
}
}

CODES: 17
}

// Step 3: Check for negative-weight cycles


// If we can still relax an edge, then there is a negative cycle.
for (int j = 0; j < E; j++) {
Edge edge = edges[j];
int u = edge.src;
int v = edge.dest;
int w = edge.weight;

if (dist[u] != Integer.MAX_VALUE && dist[u] + w < dist[v]) {


System.out.println("Graph contains a negative-weight cycle!");
return;
}
}

// If no negative cycle, print the distance array


System.out.println("Shortest distances from vertex " + start + ":");
for (int i = 0; i < V; i++) {
System.out.println("Distance to vertex " + i + " = " + dist[i]);
}
}

// Example usage
public static void main(String[] args) {
int V = 5; // Number of vertices in graph
int E = 8; // Number of edges in graph

// Create a new graph


BellmanFord graph = new BellmanFord(V, E);

/*
* We'll add edges in the form:
* addEdge(index, source, destination, weight)
*
* Example edges:

CODES: 18
* 0 -> 1 (weight -1)
* 0 -> 2 (weight 4)
* 1 -> 2 (weight 3)
* 1 -> 3 (weight 2)
* 1 -> 4 (weight 2)
* 3 -> 2 (weight 5)
* 3 -> 1 (weight 1)
* 4 -> 3 (weight -3)
*/

graph.addEdge(0, 0, 1, -1);
graph.addEdge(1, 0, 2, 4);
graph.addEdge(2, 1, 2, 3);
graph.addEdge(3, 1, 3, 2);
graph.addEdge(4, 1, 4, 2);
graph.addEdge(5, 3, 2, 5);
graph.addEdge(6, 3, 1, 1);
graph.addEdge(7, 4, 3, -3);

// Run Bellman-Ford from vertex 0


graph.bellmanFord(0);
}

binomial heap:
public class BinomialHeap {
private Nodke head; // head of the root list

// Node in a binomial tree


static class Node {
int key, degree;
Node parent, child, sibling;
Node(int key) { this.key = key; }
}

CODES: 19
// Insert a new key by merging with a single-node heap.
public void insert(int key) {
head = union(head, new Node(key));
}

// Returns the minimum key in the heap.


public int findMin() {
if (head == null) throw new RuntimeException("Heap is empty");
int min = head.key;
for (Node cur = head; cur != null; cur = cur.sibling)
if (cur.key < min) min = cur.key;
return min;
}

// Extract and return the minimum key.


public int extractMin() {
if (head == null) throw new RuntimeException("Heap is empty");
Node minNode = head, minPrev = null;
Node cur = head, prev = null;
int min = cur.key;
while (cur != null) {
if (cur.key < min) {
min = cur.key;
minNode = cur;
minPrev = prev;
}
prev = cur;
cur = cur.sibling;
}
// Remove minNode from root list.
if (minPrev == null) head = minNode.sibling;
else minPrev.sibling = minNode.sibling;
// Reverse minNode's children.
Node child = minNode.child, newHead = null;
while (child != null) {

CODES: 20
Node next = child.sibling;
child.sibling = newHead;
child.parent = null;
newHead = child;
child = next;
}
head = union(head, newHead);
return minNode.key;
}

// Merges two binomial heaps.


private Node union(Node h1, Node h2) {
Node merged = merge(h1, h2);
if (merged == null) return null;
Node prev = null, curr = merged, next = curr.sibling;
while (next != null) {
if (curr.degree != next.degree || (next.sibling != null && next.sibling.degre
e == curr.degree)) {
prev = curr;
curr = next;
} else {
if (curr.key <= next.key) {
curr.sibling = next.sibling;
link(next, curr);
} else {
if (prev == null) merged = next;
else prev.sibling = next;
link(curr, next);
curr = next;
}
}
next = curr.sibling;
}
return merged;
}

CODES: 21
// Merges two root lists in order of increasing degree.
private Node merge(Node h1, Node h2) {
if (h1 == null) return h2;
if (h2 == null) return h1;
Node head;
if (h1.degree <= h2.degree) {
head = h1;
h1 = h1.sibling;
} else {
head = h2;
h2 = h2.sibling;
}
Node tail = head;
while (h1 != null && h2 != null) {
if (h1.degree <= h2.degree) {
tail.sibling = h1;
h1 = h1.sibling;
} else {
tail.sibling = h2;
h2 = h2.sibling;
}
tail = tail.sibling;
}
tail.sibling = (h1 != null) ? h1 : h2;
return head;
}

// Links two binomial trees of the same degree.


private void link(Node y, Node z) {
y.parent = z;
y.sibling = z.child;
z.child = y;
z.degree++;
}

// Simple demonstration.

CODES: 22
public static void main(String[] args) {
BinomialHeap bh = new BinomialHeap();
bh.insert(10);
bh.insert(3);
bh.insert(15);
bh.insert(6);

System.out.println("Minimum element: " + bh.findMin());


System.out.println("Extracted minimum: " + bh.extractMin());
System.out.println("Minimum after extraction: " + bh.findMin());
}

}
k-ary heap

import java.util.ArrayList;
import java.util.NoSuchElementException;
public class KaryHeap {
private int k; // Number of children per node
private ArrayList<Integer> heap;

// Constructor: specify the arity (k) of the heap


public KaryHeap(int k) {
if (k < 2) {
throw new IllegalArgumentException("k must be at least 2");
}
this.k = k;
heap = new ArrayList<>();
}

// Returns the index of the parent of the node at index i


private int parent(int i) {
return (i - 1) / k;
}

CODES: 23
// Returns the index of the j-th child (1-indexed) of the node at index i
private int child(int i, int j) {
return k * i + j;
}

// Inserts a new value into the heap


public void insert(int value) {
heap.add(value);
heapifyUp(heap.size() - 1);
}

// Restores the heap property going upward from index i


private void heapifyUp(int i) {
int current = i;
while (current > 0) {
int p = parent(current);
if (heap.get(current) < heap.get(p)) {
swap(current, p);
current = p;
} else {
break;
}
}
}

// Returns the minimum element in the heap


public int getMin() {
if (heap.isEmpty()) {
throw new NoSuchElementException("Heap is empty");
}
return heap.get(0);
}

// Extracts and returns the minimum element from the heap


public int extractMin() {
if (heap.isEmpty()) {

CODES: 24
throw new NoSuchElementException("Heap is empty");
}
int min = heap.get(0);
int last = heap.remove(heap.size() - 1);
if (!heap.isEmpty()) {
heap.set(0, last);
heapifyDown(0);
}
return min;
}

// Restores the heap property going downward from index i


private void heapifyDown(int i) {
int current = i;
while (true) {
int smallest = current;
// Check all k children of the current node
for (int j = 1; j <= k; j++) {
int c = child(current, j);
if (c < heap.size() && heap.get(c) < heap.get(smallest)) {
smallest = c;
}
}
if (smallest != current) {
swap(current, smallest);
current = smallest;
} else {
break;
}
}
}

// Utility method to swap two elements in the heap


private void swap(int i, int j) {
int temp = heap.get(i);
heap.set(i, heap.get(j));

CODES: 25
heap.set(j, temp);
}

// Simple demonstration
public static void main(String[] args) {
// Create a ternary heap (k = 3)
KaryHeap kh = new KaryHeap(3);
kh.insert(10);
kh.insert(4);
kh.insert(15);
kh.insert(2);
kh.insert(7);

System.out.println("Minimum element: " + kh.getMin());


System.out.println("Extracted minimum: " + kh.extractMin());
System.out.println("Minimum after extraction: " + kh.getMin());
}

winner tree:

public class WinnerTree {


private int[] tree; // Array representing the winner tree (internal nodes)
private int[] leaves; // Array storing the keys (leaves of the tournament)
private int n; // Number of leaves (padded to a power of 2)

/**
* Constructor: Builds a winner tree from the given keys.
* If the number of keys is not a power of 2, the array is padded with Integer.M
AX_VALUE.
*/
public WinnerTree(int[] keys) {
int m = keys.length;

CODES: 26
// Pad the number of leaves to the next power of 2.
n = 1;
while (n < m) {
n *= 2;
}
leaves = new int[n];
for (int i = 0; i < n; i++) {
if (i < m) {
leaves[i] = keys[i];
} else {
leaves[i] = Integer.MAX_VALUE; // Pad with a very high value.
}
}
tree = new int[2 * n]; // Tree indices [n, 2*n-1] will correspond to the leaves.
buildWinnerTree();
}

/**
* Build the winner tree.
* Leaves are stored at positions n to 2*n-1. Internal nodes store the index of t
he winner (the minimum value) from their children.
*/
private void buildWinnerTree() {
// Initialize leaves in the tree.
for (int i = 0; i < n; i++) {
tree[n + i] = i; // Each leaf node holds its own index.
}
// Build the internal nodes from the bottom up.
for (int i = n - 1; i > 0; i--) {
int left = tree[2 * i];
int right = tree[2 * i + 1];
// The winner is the one with the smaller key.
tree[i] = (leaves[left] <= leaves[right]) ? left : right;
}
}

CODES: 27
/**
* Returns the minimum key (the winner) in the tree.
*/
public int getWinner() {
if (n == 0) {
throw new IllegalStateException("The tree is empty.");
}
// The overall winner is stored at tree[1].
return leaves[tree[1]];
}

/**
* Updates the value at a given leaf index and then updates the tree according
ly.
* @param index The index in the original keys array (0-based).
* @param newValue The new value to update.
*/
public void update(int index, int newValue) {
if (index < 0 || index >= n) {
throw new IllegalArgumentException("Index out of range");
}
leaves[index] = newValue;
// Start updating from the corresponding leaf in the tree.
int pos = index + n;
pos /= 2;
while (pos > 0) {
int left = tree[2 * pos];
int right = tree[2 * pos + 1];
tree[pos] = (leaves[left] <= leaves[right]) ? left : right;
pos /= 2;
}
}

/**
* Extracts the winner (minimum value) from the tree.
* For demonstration, the winner's leaf is set to Integer.MAX_VALUE (simulatin

CODES: 28
g removal) and the tree is updated.
*/
public int extractWinner() {
int winnerIndex = tree[1];
int winnerValue = leaves[winnerIndex];
// Simulate removal by setting the leaf to a very high value.
update(winnerIndex, Integer.MAX_VALUE);
return winnerValue;
}

// Demonstration of the winner tree.


public static void main(String[] args) {
int[] keys = { 5, 3, 8, 6, 2, 7, 4, 1 };
WinnerTree wt = new WinnerTree(keys);
System.out.println("Winner (min): " + wt.getWinner());
System.out.println("Extracted winner: " + wt.extractWinner());
System.out.println("New winner after extraction: " + wt.getWinner());
}

CODES: 29

You might also like