дерево сегментов правильное, но вывод запроса не - PullRequest
0 голосов
/ 25 ноября 2018

Я попытался реализовать алгоритм дерева сегментов для поиска минимального диапазона запроса в Java.Вот мой полный код java.Он строит дерево сегментов из массива.а затем печатает минимальный элемент в каждом диапазоне.проблема в том, что дерево корректно (насколько я знаю), но вывод всегда является наименьшим элементом всего массива.: - |пожалуйста, укажите, где я иду не так.

public class Solution {

static int arr[] = {-1, 2, 4, 0};
static int st[];

public static void main(String[] args) {

    st = new int [ 2 * arr.length-1];

    buildTree(0, 0, arr.length-1);

    System.out.print("original array: ");
    showArray(arr);

    System.out.print("segment tree: ");
    // shows segment tree
    showArray(st);

    System.out.println("\nqueries: \n");

    // prints minimum in every range
    for(int i=0; i<arr.length; i++) {
        for(int j=i+1; j<arr.length; j++) 
            System.out.println(i+":"+j+" -> "+search(i, j));
    }

}

// builds segment tree
static void buildTree(int pos, int left, int right) {

    if(left == right) {
        st[pos] = arr[left];
        return;
    }

    int mid = (left + right) / 2;

    buildTree(left(pos), left, mid);
    buildTree(right(pos), mid+1, right);

    int p1 = left(pos);
    int p2 = right(pos);

    st[pos] = (st[p1] > st[p2]) ? st[p2] : st[p1];
}

// left child
static int left(int pos) {
    return pos * 2 + 1;
}

// right child
static int right(int pos) {
    return pos * 2  + 2;
}

static int search(int left, int right) {

     return rmq(0, 0, st.length, left, right);
}

// range minimum query function
static int rmq(int pos, int left, int right, int qleft, int qright) {

    if((qleft > right) && (qright < left))
        return Integer.MAX_VALUE;

    if((qleft <= left) || (qright >= right))
        return st[pos];

    int mid = (left + right) / 2;

    int l = rmq(left(pos), left, mid, qleft, qright);
    int r = rmq(right(pos), mid + 1, right, qleft, qright);

    return (l > r) ? r : l;
}

// show segment tree
static void showArray(int arr[]) {

    for(Integer x : arr)
        System.out.print(x+" ");
    System.out.println();
 }
}

1 Ответ

0 голосов
/ 25 ноября 2018

Вы должны внести следующие изменения в свой код.

Прежде всего размер массива, используемого для хранения данных в сегментарной структуре данных, должен быть в 4 раза больше размера данного массива. Здесь почему?

st = new int [ 4 * arr.length - 1];

Далее в функции search третий параметр для rmq должен быть arr.length - 1.

static int search(int left, int right) {
     return rmq(0, 0, arr.length - 1, left, right);
}

И, наконец,Вы должны исправить базовые случаи и аргументы в дочерних вызовах в функции rmq следующим образом:

static int rmq(int pos, int left, int right, int qleft, int qright) {

    if((qleft > right) || (qright < left))
        return Integer.MAX_VALUE;

    if((qleft <= left) && (qright >= right))
        return st[pos];

    int mid = (left + right) / 2;

    int l = rmq(left(pos), left, mid, qleft, Math.min(qright, mid) );
    int r = rmq(right(pos), mid + 1, right, Math.max(mid + 1, qleft), qright);

    return (l > r) ? r : l;
}

Надеюсь, это поможет.

...