Обновление PriorityQueue/Heap

Я должен сравнить это и найти самый большой из них.

blockquote>

Вы можете обработать его с помощью BigInteger

BigInteger b1 = BigInteger.Parse("73248723847239847283974283749238");
BigInteger b2 = BigInteger.Parse("98231912938129381290120378988945");

BigInteger result = BigInteger.Max(b1, b2);

преобразовать его в массив чисел и сравнить его суммы но это не очень хорошо со стороны производительности

blockquote>

Примечание: производительность - самая маленькая проблема этого подхода

36
задан Kalamarico 20 December 2017 в 10:03
поделиться

4 ответа

Вы, возможно, должны были бы реализовать такую "кучу" сами. У Вас должны быть некоторый дескриптор к позиции объекта в "куче" и некоторые методы для увеличивания объекта или вниз когда его приоритет изменился.

Несколько лет назад я записал такую "кучу" как часть школьной работы. Увеличивание объекта или вниз является O (зарегистрируйте N), операция. Я выпускаю следующий код как общественное достояние, таким образом, можно использовать его всегда, Вам нравится. (Вы могли бы хотеть улучшить этот класс так, чтобы вместо краткого обзора isGreaterOrEqual метод порядок сортировки полагался на Компаратор Java и Сопоставимые интерфейсы, и также сделал дженерики использования класса.)

import java.util.*;

public abstract class Heap {

    private List heap;

    public Heap() {
        heap = new ArrayList();
    }

    public void push(Object obj) {
        heap.add(obj);
        pushUp(heap.size()-1);
    }

    public Object pop() {
        if (heap.size() > 0) {
            swap(0, heap.size()-1);
            Object result = heap.remove(heap.size()-1);
            pushDown(0);
            return result;
        } else {
            return null;
        }
    }

    public Object getFirst() {
        return heap.get(0);
    }

    public Object get(int index) {
        return heap.get(index);
    }

    public int size() {
        return heap.size();
    }

    protected abstract boolean isGreaterOrEqual(int first, int last);

    protected int parent(int i) {
        return (i - 1) / 2;
    }

    protected int left(int i) {
        return 2 * i + 1;
    }

    protected int right(int i) {
        return 2 * i + 2;
    }

    protected void swap(int i, int j) {
        Object tmp = heap.get(i);
        heap.set(i, heap.get(j));
        heap.set(j, tmp);
    }

    public void pushDown(int i) {
        int left = left(i);
        int right = right(i);
        int largest = i;

        if (left < heap.size() && !isGreaterOrEqual(largest, left)) {
            largest = left;
        }
        if (right < heap.size() && !isGreaterOrEqual(largest, right)) {
            largest = right;
        }

        if (largest != i) {
            swap(largest, i);
            pushDown(largest);
        }
    }

    public void pushUp(int i) {
        while (i > 0 && !isGreaterOrEqual(parent(i), i)) {
            swap(parent(i), i);
            i = parent(i);
        }
    }

    public String toString() {
        StringBuffer s = new StringBuffer("Heap:\n");
        int rowStart = 0;
        int rowSize = 1;
        for (int i = 0; i < heap.size(); i++) {
            if (i == rowStart+rowSize) {
                s.append('\n');
                rowStart = i;
                rowSize *= 2;
            }
            s.append(get(i));
            s.append(" ");
        }
        return s.toString();
    }

    public static void main(String[] args){
        Heap h = new Heap() {
            protected boolean isGreaterOrEqual(int first, int last) {
                return ((Integer)get(first)).intValue() >= ((Integer)get(last)).intValue();
            }
        };

        for (int i = 0; i < 100; i++) {
            h.push(new Integer((int)(100 * Math.random())));
        }

        System.out.println(h+"\n");

        while (h.size() > 0) {
            System.out.println(h.pop());
        }
    }
}
16
ответ дан Esko Luontola 27 November 2019 в 06:15
поделиться

PriorityQueue имеет heapify метод, который обращается вся "куча", fixUp метод, который продвигает элемент более высокого приоритета "куча", и fixDown метод, который продвигает элемент более низкого приоритета вниз "куча". К сожалению, все эти методы являются частными, таким образом, Вы не можете использовать их.

Я рассмотрел бы использование шаблона The Observer так, чтобы содержавший элемент мог сказать Очереди, что ее приоритет изменился, и Очередь может затем сделать что-то как fixUp или fixDown в зависимости от если приоритет, увеличенный или уменьшенный соответственно.

8
ответ дан Adam Jaskiewicz 27 November 2019 в 06:15
поделиться

Стандартные интерфейсы не обеспечивают возможность обновления. Вы имеете, используют пользовательский тип, который реализует это.

И Вы правы; хотя большая-O сложность алгоритмов, которые используют "кучу", не изменяется, когда Вы удаляете и заменяете верхушку, их фактическое время выполнения может почти удвоиться. Я хотел бы видеть лучше встроенную поддержку a peek() и update() стиль использования "кучи".

3
ответ дан erickson 27 November 2019 в 06:15
поделиться

В зависимости от реализации структуры данных не может быть более быстрого пути. Большинство алгоритмов PQ/heap не обеспечивает функцию обновления. Реализация Java не может несколько отличаться. Заметьте, что, хотя удаление/вставление делает код медленнее, это вряд ли приведет к коду с другой сложностью во время выполнения.

Править: взгляните на этот поток: приоритетная очередь, которая позволяет эффективное приоритетное обновление?

2
ответ дан Community 27 November 2019 в 06:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: