I'm solving a task from Sedgewick book:
Write a class Sample with a constructor that takes an array p[] of double values as argument and supports the fol-lowing two operations: random() —return an index i with probability p[i]/T (where T is the sum of the numbers in p[])
I think that there is a simple solution: store all border values in array and find first value that is lower than random sample, for example, we have (value, weight) pairs: (1, 10.0), (2, 20.0), (3, 10.0), (4, 10.0). We convert it to (1, 0.0), (2, 10.0), (3, 30.0), (4, 40), sample random value [0-50] (for example, 35) and find that it is > 30, so answer is '3'.
But in the book there is a suggestion:
Use a complete binary tree where each node has implied weight p[i]. Store in each node the cumulative weight of all the nodes in its subtree. To generate a random index, pick a random number between 0 and T and use the cumulative weights to determine which branch of the subtree to explore.
and I saw this solution on github: https://github.com/reneargento/algorithms-sedgewick-wayne/blob/master/src/chapter2/section4/Exercise35_Sampling.java
But I don't understand why it works: instead of representing ranges we will have some tree that will have nodes like (3, 10), (4, 10), how searching for 'closest' node to random sample will help to find a correct node?