二叉搜索树实现

100 阅读2分钟

问题1:

(A) 迭代版本的实现如下:

public Comparable iterMax() {
    if (isEmpty()) {
        return null;
    }
    BSTNode max = root;
    while (max.right != null) {
        max = max.right;
    }
    return max.info;
}

首先判断树是否为空,如果是则返回null

否则,从根节点开始向右依次遍历,直到遍历到最右侧的节点,即可找到值最大的节点,返回其信息。

(B) 递归版本的实现如下:

public Comparable recMax() {
    if (isEmpty()) {
        return null;
    }
    return recMax(root).info;
}

private BSTNode recMax(BSTNode p) {
    if (p.right == null) {
        return p;
    }
    return recMax(p.right);
}

同样先判断树是否为空,如果是则返回null

否则,从根节点开始向右依次递归,直到遍历到最右侧的节点,即可找到值最大的节点,返回该节点。

问题2:

(A) 优先队列的实现可以使用二叉堆(Binary Heap)来实现。实例变量和内部类声明如下:

public class PriorityQueueImpl<E extends Comparable<E>> implements PriorityQueue<E> {

    private final int DEFAULT_CAPACITY = 100;

    private E[] elements; // 保存元素的数组

    private int size; // 队列中元素的数量

    // 私有方法,向上调整堆
    private void siftUp(int index) {
        while (index > 0) {
            int parent = (index - 1) / 2;
            if (elements[index].compareTo(elements[parent]) <= 0) {
                return;
            }
            swap(index, parent);
            index = parent;
        }
    }

    // 私有方法,向下调整堆
    private void siftDown(int index) {
        while (index * 2 + 1 < size) {
            int left = index * 2 + 1;
            int right = index * 2 + 2;
            int maxChild = left;
            if (right < size && elements[right].compareTo(elements[left]) > 0) {
                maxChild = right;
            }
            if (elements[index].compareTo(elements[maxChild]) >= 0) {
                return;
            }
            swap(index, maxChild);
            index = maxChild;
        }
    }

    // 私有方法,交换数组中两个元素的位置
    private void swap(int i, int j) {
        E tmp = elements[i];
        elements[i] = elements[j];
        elements[j] = tmp;
    }

    // 其他公共方法
    // ...

其中,DEFAULT_CAPACITY为默认容量为100。

elements保存队列中的元素,它是一个泛型数组,元素类型为E,E实现了Comparable接口,有可比较性。

size保存队列中元素的数量。

siftUp方法将新插入的元素向上调整,以维护堆的性质,保证堆顶元素为优先级最高的元素。

siftDown方法将堆顶元素向下调整,以维护堆的性质,保证堆顶元素为优先级最高的元素。

(B) 队列操作如下:

public class PriorityQueueImpl<E extends Comparable<E>> implements PriorityQueue<E> {

    // ...

    @Override
    public void add(E element) {
        if (size == elements.length) {
            throw new IllegalStateException("Queue is full");
        }
        elements[size] = element;
        size++;
        siftUp(size-1);
    }

    @Override
    public E remove() {
        if (isEmpty()) {
            return null;
        }
        E result = elements[0];
        elements[0] = elements[size-1];
        size--;
        siftDown(0);
        return result;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return elements[0];
    }

    // ...
}

add方法将一个元素添加到队列中。如果队列已满,则抛出IllegalStateException异常。添加时将新元素加入到数组的尾部,然后向上调整堆。

remove方法将堆顶元素移除,并返回该元素。如果队列为空,则返回null。移除时将堆顶元素和数组尾部的元素交换位置,然后将堆顶元素向下调整堆。

peek方法返回堆顶元素,但不移除。如果队列为空,则返回null