问题描述
提示:给原来的BST添加了一个父节点
给BST添加一个父节点,并且添加getNode() isLeaf() getPath()方法
难点分析:
提示:这里根据isLeaf找到子节点,之后获取其路径(自带了Path)就完成了getPath方法了
叶子结点没有左右子树,可以直接根据这个判断,getpath调用自带的path方法,倒序输出就好
代码:
提示:
import java.util.*;
public class Lab25_15 {
public static void main(String[] args) {
Integer[] arr = new Integer[]{45, 54, 67, 56, 50, 45, 23, 59, 23, 67};
BST25_15<Integer> tree = new BST25_15<>(arr);
tree.delete(arr[0]);
for (int i = 0; i < arr.length; i++)
if (tree.isLeaf(arr[i]))
System.out.println(tree.getPath(arr[i]));
}
}
interface Tree25_15<E> extends Collection<E> {
/**
* Return true if the element is in the tree
*/
public boolean search(E e);
/**
* Insert element o into the binary tree
* Return true if the element is inserted successfully
*/
public boolean insert(E e);
/**
* Delete the specified element from the tree
* Return true if the element is deleted successfully
*/
public boolean delete(E e);
/**
* Get the number of nodes in the tree
*/
public int getSize();
/**
* Inorder traversal from the root
*/
public default void inorder() {
}
/**
* Postorder traversal from the root
*/
public default void postorder() {
}
/**
* Preorder traversal from the root
*/
public default void preorder() {
}
@Override
/** Return true if the tree is empty */
public default boolean isEmpty() {
return size() == 0;
}
;
@Override
public default boolean contains(Object e) {
return search((E) e);
}
@Override
public default boolean add(E e) {
return insert(e);
}
@Override
public default boolean remove(Object e) {
return delete((E) e);
}
@Override
public default int size() {
return getSize();
}
@Override
public default boolean containsAll(Collection<?> c) {
// Left as an exercise
return false;
}
@Override
public default boolean addAll(Collection<? extends E> c) {
// Left as an exercise
return false;
}
@Override
public default boolean removeAll(Collection<?> c) {
// Left as an exercise
return false;
}
@Override
public default boolean retainAll(Collection<?> c) {
// Left as an exercise
return false;
}
@Override
public default Object[] toArray() {
// Left as an exercise
return null;
}
@Override
public default <T> T[] toArray(T[] array) {
// Left as an exercise
return null;
}
}
class BST25_15<E> implements Tree25_15<E> {
protected TreeNode<E> root;
protected int size = 0;
protected Comparator<E> c;
/**
* Create a default BST with a natural order comparator
*/
public BST25_15() {
this.c = new Comparator<E>() {
public int compare(E e1, E e2) {
return ((Comparable<E>) e1).compareTo(e2);
}
};
}
/**
* Create a BST with a specified comparator
*/
public BST25_15(Comparator<E> c) {
this.c = c;
}
/**
* Create a binary tree from an array of objects
*/
public BST25_15(E[] objects) {
this();
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
@Override
/** Returns true if the element is in the tree */
public boolean search(E e) {
TreeNode<E> current = root; // Start from the root
while (current != null) {
if (c.compare(e, current.element) < 0) {
current = current.left;
} else if (c.compare(e, current.element) > 0) {
current = current.right;
} else // element matches current.element
return true; // Element is found
}
return false;
}
@Override
/** Insert element e into the binary tree
* Return true if the element is inserted successfully */
public boolean insert(E e) {
if (root == null) {
root = createNewNode(e); // Create a new root
root.parent = null;
} else {
// Locate the parent node
TreeNode<E> parent = null;
TreeNode<E> current = root;
while (current != null)
if (c.compare(e, current.element) < 0) {
parent = current;
current = current.left;
if (current != null)
current.parent = parent;
} else if (c.compare(e, current.element) > 0) {
parent = current;
current = current.right;
if (current != null)
current.parent = parent;
} else
return false; // Duplicate node not inserted
// Create the new node and attach it to the parent node
if (c.compare(e, parent.element) < 0)
parent.left = createNewNode(e);
else
parent.right = createNewNode(e);
}
size++;
return true; // Element inserted successfully
}
protected TreeNode<E> createNewNode(E e) {
return new TreeNode<>(e);
}
@Override
/** Inorder traversal from the root */
public void inorder() {
inorder(root);
}
/**
* Inorder traversal from a subtree
*/
protected void inorder(TreeNode<E> root) {
if (root == null) return;
inorder(root.left);
System.out.print(root.element + " ");
inorder(root.right);
}
@Override
/** Postorder traversal from the root */
public void postorder() {
postorder(root);
}
/**
* Postorder traversal from a subtree
*/
protected void postorder(TreeNode<E> root) {
if (root == null) return;
postorder(root.left);
postorder(root.right);
System.out.print(root.element + " ");
}
@Override
/** Preorder traversal from the root */
public void preorder() {
preorder(root);
}
/**
* Preorder traversal from a subtree
*/
protected void preorder(TreeNode<E> root) {
if (root == null) return;
System.out.print(root.element + " ");
preorder(root.left);
preorder(root.right);
}
/**
* This inner class is static, because it does not access
* any instance members defined in its outer class
*/
public static class TreeNode<E> {
protected E element;
protected TreeNode<E> left;
protected TreeNode<E> right;
protected TreeNode<E> parent;
public TreeNode(E e) {
element = e;
}
}
//添加的方法
private TreeNode<E> getNode(E element) {
TreeNode<E> current = root;
while (current != null) {
if (c.compare(element, current.element) < 0) {
current = current.left;
} else if (c.compare(element, current.element) > 0) {
current = current.right;
} else
return current;
}
return null;
}
public boolean isLeaf(E element) {
TreeNode<E> current = root;
while (current != null) {
if (c.compare(element, current.element) < 0) {
current = current.left;
} else if (c.compare(element, current.element) > 0) {
current = current.right;
} else
break;
}
if (current == null)
return false;
return current.left == null && current.right == null;
}
public ArrayList<E> getPath(E e) {
ArrayList<TreeNode<E>> list = path(e);
ArrayList<E> res = new ArrayList<>();
for (int i = list.size() - 1; i >= 0; i--)
res.add(list.get(i).element);
return res;
}
@Override
/** Get the number of nodes in the tree */
public int getSize() {
return size;
}
/**
* Returns the root of the tree
*/
public TreeNode<E> getRoot() {
return root;
}
/**
* Returns a path from the root leading to the specified element
*/
public ArrayList<TreeNode<E>> path(E e) {
ArrayList<TreeNode<E>> list =
new ArrayList<>();
TreeNode<E> current = root; // Start from the root
while (current != null) {
list.add(current); // Add the node to the list
if (c.compare(e, current.element) < 0) {
current = current.left;
} else if (c.compare(e, current.element) > 0) {
current = current.right;
} else
break;
}
return list; // Return an array list of nodes
}
@Override
/** Delete an element from the binary tree.
* Return true if the element is deleted successfully
* Return false if the element is not in the tree */
public boolean delete(E e) {
// Locate the node to be deleted and also locate its parent node
TreeNode<E> parent = null;
TreeNode<E> current = root;
while (current != null) {
if (c.compare(e, current.element) < 0) {
parent = current;
current = current.left;
} else if (c.compare(e, current.element) > 0) {
parent = current;
current = current.right;
} else
break; // Element is in the tree pointed at by current
}
if (current == null)
return false; // Element is not in the tree
// Case 1: current has no left child
if (current.left == null) {
// Connect the parent with the right child of the current node
if (parent == null) {
root = current.right;
} else {
if (c.compare(e, parent.element) < 0) {
parent.left = current.right;
current.right.parent = parent;
} else {
parent.right = current.right;
current.right.parent = parent;
}
}
} else {
// Case 2: The current node has a left child
// Locate the rightmost node in the left subtree of
// the current node and also its parent
TreeNode<E> parentOfRightMost = current;
TreeNode<E> rightMost = current.left;
while (rightMost.right != null) {
parentOfRightMost = rightMost;
rightMost = rightMost.right; // Keep going to the right
}
// Replace the element in current by the element in rightMost
current.element = rightMost.element;
// Eliminate rightmost node
if (parentOfRightMost.right == rightMost) {
parentOfRightMost.right = rightMost.left;
if (rightMost.left != null)
rightMost.left.parent = parentOfRightMost;
} else {
// Special case: parentOfRightMost == current
parentOfRightMost.left = rightMost.left;
if (rightMost.left != null)
rightMost.left.parent = parentOfRightMost;
}
}
size--; // Reduce the size of the tree
return true; // Element deleted successfully
}
@Override
/** Obtain an iterator. Use inorder. */
public Iterator<E> iterator() {
return new InorderIterator();
}
// Inner class InorderIterator
private class InorderIterator implements Iterator<E> {
// Store the elements in a list
private ArrayList<E> list =
new ArrayList<>();
private int current = 0; // Point to the current element in list
public InorderIterator() {
inorder(); // Traverse binary tree and store elements in list
}
/**
* Inorder traversal from the root
*/
private void inorder() {
inorder(root);
}
/**
* Inorder traversal from a subtree
*/
private void inorder(TreeNode<E> root) {
if (root == null) return;
inorder(root.left);
list.add(root.element);
inorder(root.right);
}
@Override
/** More elements for traversing? */
public boolean hasNext() {
if (current < list.size())
return true;
return false;
}
@Override
/** Get the current element and move to the next */
public E next() {
return list.get(current++);
}
@Override // Remove the element returned by the last next()
public void remove() {
if (current == 0) // next() has not been called yet
throw new IllegalStateException();
delete(list.get(--current));
list.clear(); // Clear the list
inorder(); // Rebuild the list
}
}
@Override
/** Remove all elements from the tree */
public void clear() {
root = null;
size = 0;
}
}