问题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。