javaで2分木探索(binarySearch)
binarySearchという、collectionsライブラリにあるメソッドを使ってjavaで2分木探索を行う方法を紹介します。
listに重複があるかどうかで実装方法が変わってきます。
Listに重複がない場合
この場合はCollections.binarySearchを使えば簡単に求まります。
存在しない場合は(-(挿入場所) - 1)が返ります。
public static void main(String args []) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 6, 9); //探索したいint int key = 4; //list上の位置。 なければ負の値が返る int position = Collections.binarySearch(list, key); //keyが4の場合は、3 //keyが5の場合は、-5 //5の挿入場所は4なので、(-4 - 1)が返ります System.out.println(position); }
Listに重複するものがある場合(なくても良い)
この場合はCollections.binarySearchの引数の3番目、Comparatorを使います。
public static void main(String args[]) { List<Integer> list = Arrays.asList(1, 2, 2, 3, 4, 4, 4, 6, 9); int key = 4; int check = Collections.binarySearch(list, key); //(1) if (check < 0) { System.out.println("not exist"); } else { //lower_bound int lowerPosition = ~Collections.binarySearch(list, key, (x, y) -> x.compareTo(y) >= 0 ? 1 : -1); //(2) System.out.println(lowerResult);// => 4 //upper_bound int upperPosition = ~Collections.binarySearch(list, key, (x, y) -> x.compareTo(y) > 0 ? 1 : -1); //(3) System.out.println(upperResult);// => 7 } }
(1) まずは、探索したい数がlistに存在するか確かめます。
checkが負ならば、存在しないということになります。
(2)key以上の数が始めて現れる位置を返します。
負で返されるので、反転の~を先頭に付けています。
(3)keyより大きい数が初めて現れる位置を返します。
重複して存在する場合は 、lowerPositionからupperPosition-1までkeyが存在することになります。
keyが4の場合は4から6の位置まで存在することになります。(最初の位置はもちろん0です)
もし重複していない場合はlowerPosition = upperPosition -1 になります。
以上がライブラリを使ったjavaで二分木探索をする方法です。