滿二叉排序樹中查詢三個節點的最小子樹的根節點
阿新 • • 發佈:2019-02-04
題目描述:
在一棵滿二叉排序樹深度為k,節點數為2^k-1;節點值為1至(2^k - 1),給出k和任意三個節點的值,輸出包含該三個節點的最小子樹的根節點。
樣例輸入:4 10 15 13
樣例輸出:12
首先,我們來理解一下滿二叉排序樹,如下就是一個4層的滿二叉排序樹:
* 8
* / \
* 4 12
* / \ / \
* 2 6 10 14
* /\ /\ / \ / \
* 1 3 5 7 9 11 13 15
根據上圖可以看出,滿二叉排序樹的中序遍歷是從1到2^k - 1的遞增序列(k為層數)。所以,只要給出層數我們就能夠確定這個二叉排序樹。同時,觀察可知,二叉排序樹從上到下的根節點剛好是所有元素進行二分查詢的中間節點。
根據上面的規律要解決三個節點的最小子樹的根節點這個問題可以得到如下幾點:
- 無須建立二叉樹,從1-2^k - 1的遞增陣列即就是一個滿二叉排序樹
- 當輸入的三個元素在二分節點兩側時,當前的二分節點就是要查詢的最小子樹的根節點(根據這個規則,我們也無需判斷三個元素,只需判斷最大元素和最小元素的位置即可)
- 當最小節點的值大於二分節點的值,則繼續在二分的右半部分進行查詢
- 當最大節點的值小於二分節點的值,則繼續在二分的左半部分進行查詢
根據如上幾點,編寫程式碼如下:
import java.util.Scanner;
/**
* Created by zhuxinquan on 17-4-4.
* 對於一棵滿二叉排序樹深度為k,節點數為2^k-1;節點值為1至(2^k - 1),
* 給出k和任意三個節點的值,輸出包含該三個節點的最小子樹的根節點
*
* 8
* / \
* 4 12
* / \ / \
* 2 6 10 14
* /\ /\ / \ / \
* 1 3 5 7 9 11 13 15
*/
public class BinarySortTree {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int layer = scanner.nextInt();
int a = scanner.nextInt();
int b = scanner.nextInt();
int c = scanner.nextInt();
int max = a > b ? (a > c ? a : c) : (b > c ? b : c);
int min = a < b ? (a < c ? a : c) : (b < c ? b : c);
int left = 1;
int right = (int)Math.pow(2, layer) - 1;
int middle = (left + right) / 2;
while(true){
if(middle > min && middle < max || middle == min || middle == max){
break;
}
if(min > middle){
left = middle + 1;
middle = (left + right) / 2;
}else if(max < middle){
right = middle - 1;
middle = (left + right) / 2;
}
}
System.out.println(middle);
}
}