Question
I need assistance implementing a working remove method in my AVL tree This is the code I have written so far within a single class
I need assistance implementing a working remove method in my AVL tree
This is the code I have written so far within a single class and a main method that prints out the height and value for insertion. I believe my insert and rotation methods work fine.
Here is my code.
import java.io.*;
import java.util.*;
public class AVLTree {
/*
* Implements a ALV tree of ints stored in a random access file. Duplicates are
* recorded by a count field associated with the int
*/
final int CREATE = 0;
final int REUSE = 1;
private RandomAccessFile f;
long root; // the address of the root node in the file
long free; // the address in the file of the first node in the free list
private class Node {
private long left;
private int data;
private int count;
private long right;
private int height;
private Node(long L, int d, long r) {
// constructor for a new node
left = L;
data = d;
right = r;
height = 0;
}
private Node(long addr) throws IOException {
// constructor for a node that exists and is stored in the file
// Go to location in the file where the next 28 bits are the values of
// our node attributes.
f.seek(addr);
// Assign the values in order to our object attributes.
data = f.readInt();
count = f.readInt();
height = f.readInt();
left = f.readLong();
right = f.readLong();
}
private void writeNode(long addr) throws IOException {
// writes the node to the file at location addr
f.seek(addr); // Go to right location.
// Write out the node object's values.
f.writeInt(data);
f.writeInt(count);
f.writeInt(height);
f.writeLong(left);
f.writeLong(right);
}
}
public AVLTree(String fname, int mode) throws IOException {
// if mode is CREATE a new empty file is created
// if mode is CREATE and a file with file name fname exists the file with
// fname must be deleted before the new empty file is created
// if mode is REUSE an existing file is used if it exists otherwise a new empty
// file is created
File path = new File(fname);
if (mode == CREATE && path.exists())
path.delete();
f = new RandomAccessFile(path, "rw");
if (mode == CREATE) {
root = 0;
free = 0;
f.writeLong(root);
f.writeLong(free);
} else {
f.seek(0);
root = f.readLong();
free = f.readLong();
}
}
public void insert(int d) throws IOException {
// insert d into the tree
// if d is in the tree increment the count field associated with d
root = insert(root, d);
f.seek(0);
f.writeLong(root);
return;
}
private long insert(long r, int d) throws IOException { // TODO Make this mine baby.
//System.out.println(r);
Node x;
// Check if the (sub)tree is empty. If it is,
// populate it with the new node.
// This is the true base case.
if (r == 0) {
long addr = getFree();
x = new Node(0, d, 0); //TODO: not passing in children.
x.writeNode(addr);
return addr;
}
// If it's not empty, traverse the
// list until we find the appropriate
// location for the new data. Traverse
// it like a binary search tree; nodes
// less than a root go left, the others
// go right.
x = new Node(r);
if (x.data > d) { // The new data is smaller. Go left.
x.left = insert(x.left, d);
}
if (x.data < d) { // The new data is greater. Go right.
x.right = insert(x.right, d);
} else {
x.count++; // If not, they are a duplicate. Increment count.
}
x.writeNode(r);
updateHeight(r);
if (isBalanced(r)) {
return r;
}
return balanceTree(r);
}
public int find(int d) throws IOException {
// if d is in the tree return the value of count associated with d
// otherwise return 0
return find(root, d);
}
private int find(long r, int d) throws IOException {
Node x = new Node(r);
// If the tree is empty, return 0.
if (r == 0) {
return 0;
}
// If data is less than root, go left.
if (x.data > d)
return find(x.left, d);
// Else, go right.
if (x.data < d)
return find(x.right, d);
// If it's not less than and not greater than,
// it's equal, so return the count. This
// behaves like an increment0r.
return x.count;
}
//TODO: DO
public void removeOne(int d) throws IOException {
// remove one copy of d from the tree
// if the copy is the last copy remove d from the tree
// if d is not in the tree the method has no effect
}
//TODO: DO
private long removeOne(long r, int d) throws IOException {
Node x = new Node(r);
// If there are no children, then
// remove d.
if (x.left == 0 && x.right == 0 && x.data == d) {
// Decrement the count by 1.
x.count--;
// If the count is now 0 (or less than), then
// remove it from the tree.
if (x.count <= 0) {
// TODO Figure out how to delete things from file.
// https://preserve.lehigh.edu/cgi/viewcontent.cgi?article=3407&context=etd
}
x.writeNode(r);
}
return 0;
}
public void removeAll(int d) throws IOException {
// remove d from the tree
// if d is not in the tree the method has no effect
}
public void close() {
// close the random access file
// before closing update the values of root and free if necessary
}
// ROTATION METHOD
private long LRot(long addr) throws IOException {
Node p = new Node(addr);
Node x = new Node(p.left);
// x's right becomes p's left.
Node tmp = x;
long tmpxAddr = p.left; // TODO Find cooler name.
p.left = x.right;
x.right = addr; // addr = p's address.
p.height--;
x.height--;
p.writeNode(addr);
x.writeNode(tmpxAddr);
return tmpxAddr;
}
// TODO Have the single rotation methods be a single method.
private long RRot(long addr) throws IOException {
Node p = new Node(addr);
Node x = new Node(p.right);
// x's left becomes p's right.
Node tmp = x;
long tmpxAddr = p.right; // TODO Find cooler name.
p.right = x.left;
x.left = addr; // addr = p's address.
p.height--;
x.height--;
p.writeNode(addr);
x.writeNode(tmpxAddr);
return tmpxAddr;
}
private long LRRot(long addr) throws IOException {
Node p = new Node(addr);
p.left = LRot(p.left);
p.writeNode(addr);
return RRot(addr);
}
private long RLRot(long addr) throws IOException {
Node p = new Node(addr);
p.right = RRot(p.right);
p.writeNode(addr);
return LRot(addr);
}
private int getHeight(long addr) throws IOException {
if (addr == 0)
return -1;
f.seek(addr);
int data = f.readInt();
int count = f.readInt();
return f.readInt(); // Height.
}
private boolean isBalanced(long addr) throws IOException {
Node tmp = new Node(addr);
// If the difference between the two node heights are greater than
// 2, then the tree is not balanced. (Uses absolute value).
return Math.abs(getHeight(tmp.left) - getHeight(tmp.right)) < 2;
}
private void updateHeight(long addr) throws IOException {
Node tmp = new Node(addr);
// Condition 1: There are no subtrees.
if (tmp.left == 0 && tmp.right == 0) {
tmp.height = 1;
}
// Condition 2: There is only a left subtree.
else if (tmp.right == 0) {
Node tmpLeft = new Node(tmp.left);
tmp.height = tmpLeft.height + 1;
}
// Condition 3: There is only a right subtree.
else if (tmp.left == 0) {
Node tmpRight = new Node(tmp.right);
tmp.height = tmpRight.height + 1;
}
// Condition 4: There are both a right and left subtree.
else {
Node tmpLeft = new Node(tmp.left);
Node tmpRight = new Node(tmp.right);
tmp.height = Math.max(tmpLeft.height, tmpRight.height) + 1;
}
tmp.writeNode(addr);
}
/**
* Get the address of the next free node.
*
* @return addr - Address (long) of place in random access file of the first
* free node
*/
private long getFree() throws IOException {
f.seek(8); // Go to the 8th byte (1st item of the 2nd line).
long addr = f.readLong();
if (addr == 0) { // The free list is empty.
return f.length(); // Our new address. We added onto the file.
}
// Update the free list.
f.seek(addr); // Go to address.
long tmpAddr = f.readLong(); // Get new address for new node.
f.seek(8); // Go back to 8th byte (1st item of 2nd line).
f.writeLong(tmpAddr); // Overwrite this address with the new address.
return addr; // Return the original address for the new node.
}
private long balanceTree(long r) throws IOException {
Node x = new Node(r);
Node left = new Node(x.left);
Node right = new Node(x.right);
Node leftChild;
Node rightChild;
// If the left is taller than the right...
if (left.height > right.height) {
// Create new nodes. Check the subtree
// heights for if double rotation is
// necessary.
leftChild = new Node(left.left);
rightChild = new Node(right.right);
// Double rotation needed.
if (leftChild.height < rightChild.height) {
return LRRot(r);
}
return RRot(r);
} else {
leftChild = new Node(right.left);
rightChild = new Node(right.right);
// Double rotation needed.
if (leftChild.height > rightChild.height) {
return RLRot(r);
}
return LRot(r);
}
}
public void print() {
try {
System.out.println(printData(root));
System.out.println(printHeight(root));
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
private String printData(long r) throws IOException {
//System.out.println(r + " " + root);
if (r == 0) {
return "";
}
Node cur = new Node(r);
return printData(cur.left) + " " + cur.data + " " + printData(cur.right);
}
private String printHeight(long r) throws IOException {
if (r == 0) {
return "";
}
Node cur = new Node(r);
return printHeight(cur.left) + " " + cur.height + " " + printHeight(cur.right);
}
//TODO: use this to test your methods.
public static void main(String args[]) {
try {
AVLTree t = new AVLTree("tree.bin", 0);
t.insert(50);
t.print();
t.insert(30);
t.print();
t.insert(75);
t.print();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started