AVLTree - Why is my search interface not working? - java

I have to implement an AVL Tree with some given interface functions. So far, everything seems to be fine, except when I call inside the main function "tree.search(3)" for example, it simply doesn't work and just returns one value or null. Does anyone have an idea why that is so?
AVLTree:
public class AVLTree implements SearchTree{
public class Node {
int key;
int height;
Node left;
Node right;
String string;
Node(int key, String _string) {
this.key = key;
this.string = _string;
}
}
public static void main(String[] args) {
AVLTree tree = new AVLTree();
tree.insert(5, "gambo");
tree.insert(9, "3");
tree.insert(3, "3");
System.out.println(tree.search(9));
}
private Node root;
public Node find(int key) {
Node current = root;
while (current != null) {
if (current.key == key) {
break;
}
current = current.key < key ? current.right : current.left;
}
return current;
}
// public void insert(int key) {
// root = insert(root, key);
// }
public void delete(int key) {
root = delete(root, key);
}
public Node getRoot() {
return root;
}
public int height() {
return root == null ? -1 : root.height;
}
private Node insert(Node node, int key, String string) {
if (node == null) {
System.out.println("yep new node");
return new Node(key, string);
} else if (node.key > key) {
node.left = insert(node.left, key, node.string);
} else if (node.key < key) {
node.right = insert(node.right, key, node.string);
} else {
throw new RuntimeException("duplicate Key!");
}
return rebalance(node);
}
private Node delete(Node node, int key) {
if (node == null) {
return node;
} else if (node.key > key) {
node.left = delete(node.left, key);
} else if (node.key < key) {
node.right = delete(node.right, key);
} else {
if (node.left == null || node.right == null) {
node = (node.left == null) ? node.right : node.left;
} else {
Node mostLeftChild = mostLeftChild(node.right);
node.key = mostLeftChild.key;
node.right = delete(node.right, node.key);
}
}
if (node != null) {
node = rebalance(node);
}
return node;
}
private Node mostLeftChild(Node node) {
Node current = node;
while (current.left != null) {
current = current.left;
}
return current;
}
private Node rebalance(Node z) {
updateHeight(z);
int balance = getBalance(z);
if (balance > 1) {
if (height(z.right.right) > height(z.right.left)) {
z = rotateLeft(z);
} else {
z.right = rotateRight(z.right);
z = rotateLeft(z);
}
} else if (balance < -1) {
if (height(z.left.left) > height(z.left.right)) {
z = rotateRight(z);
} else {
z.left = rotateLeft(z.left);
z = rotateRight(z);
}
}
return z;
}
private Node rotateRight(Node y) {
Node x = y.left;
Node z = x.right;
x.right = y;
y.left = z;
updateHeight(y);
updateHeight(x);
return x;
}
private Node rotateLeft(Node y) {
Node x = y.right;
Node z = x.left;
x.left = y;
y.right = z;
updateHeight(y);
updateHeight(x);
return x;
}
private void updateHeight(Node n) {
n.height = 1 + Math.max(height(n.left), height(n.right));
}
private int height(Node n) {
return n == null ? -1 : n.height;
}
public int getBalance(Node n) {
return (n == null) ? 0 : height(n.right) - height(n.left);
}
#Override
public void insert(int key, String string) {
root = insert(root, key, string);
}
#Override
public String search(int key) {
Node p = find(key);
return p.string.toString();
}
#Override
public long getCumulativeLengthOfSearchPaths() {
return 0;
}
}
Interface:
/**
* Organizes strings with keys in a search tree and collects some statistics
*/
public interface SearchTree {
/**
* Inserts a string with a given key into the tree. The position in the tree
* depends on the rank of the key with respect to all existing keys in the tree.
* Each key is to appear in the tree at most once. Hence, this method will not
* alter the tree if the key already exists in the tree.
*
* #param key the key of the string to be inserted
* #param string the string to be inserted
*/
public void insert(int key, String string);
/**
* Deletes a string with a given key from the tree.
*
* #param key the key of the string to be deleted
*/
public void delete(int key);
/**
* Searches for a string with a given key in the tree and returns the string if
* it exists.
*
* #param key the key of the string to be searched for
* #return the string to be searched for, null if the key does not exist in the
* tree
*/
public String search(int key);
public long getCumulativeLengthOfSearchPaths();
}

Was able to fix the issue. In case someone runs into the same problem:
I added node.string as the string value, but it needs to parameter as the argument:
node.left = insert(node.left, key, string);

Related

How to fix remove node and go to last node after?

I am having trouble removing a node from the user input and properly going to the last node, so it will be ready to add a new node after. I am refactoring this code to a larger implementation. However, I am unable to remove the node and go to the last node after. This is also using user input to find the proper node to remove. This is a generic linked list of a comparable type.
import java.util.Scanner;
import java.io.*;
class MyGenericList <T extends Comparable<T>>
{
private class Node<T>
{
T value;
Node<T> next;
}
private Node<T> first = null;
int count = 0;
public void add(T element)
{
Node<T> newnode = new Node<T>();
newnode.value = element;
newnode.next = null;
if (first == null)
{
first = newnode;
}
else
{
Node<T> lastnode = gotolastnode(first);
lastnode.next = newnode;
}
count++;
}
public void remove(T element)
{
Node<T> nn = new Node<T>();
Node<T> cur = first.next;
Node<T> prev = first;
nn.value = element;
boolean deleted = false;
while(cur != null && deleted == false)
{
if(cur.equals(element)) //data cannot be resolved or is not a field
{
prev.next = cur.next;
this.count--;
deleted = true;
}
}
prev = gotolastnode(prev);
prev.next = nn;
}
public T get(int pos)
{
Node<T> Nodeptr = first;
int hopcount=0;
while (hopcount < count && hopcount<pos)
{ if(Nodeptr != null)
{
Nodeptr = Nodeptr.next;
}
hopcount++;
}
return Nodeptr.value;
}
private Node<T> gotolastnode(Node<T> nodepointer)
{
if (nodepointer== null )
{
return nodepointer;
}
else
{
if (nodepointer.next == null)
return nodepointer;
else
return gotolastnode( nodepointer.next);
}
}
}
class Employee implements Comparable<Employee>
{
String name;
int age;
#Override
public int compareTo(Employee arg0)
{
// TODO Auto-generated method stub
return 0;
// implement compareto method here.
}
Employee( String nm, int a)
{
name =nm;
age = a;
}
}
class City implements Comparable<City>
{
String name;
int population;
City( String nm, int p)
{
name =nm;
population = p;
}
#Override
public int compareTo(City arg0) {
// TODO Auto-generated method stub
return 0;
// implement compareto method here.
}
}
public class GenericLinkedList
{
public static void main(String[] args) throws IOException
{
MyGenericList<Employee> ml = new MyGenericList<>();
ml.add(new Employee("john", 32));
ml.add(new Employee("susan", 23));
ml.add(new Employee("dale", 45));
ml.add(new Employee("eric", 23));
Employee e1 = ml.get(0);
System.out.println( "Name " + e1.name + " Age "+ e1.age );
ml.remove(new Employee("john", 32));
System.out.println( "Name " + e1.name + " Age "+ e1.age );
ml.add(new Employee("jerry", 35));
Employee e2 = ml.get(2);
System.out.println( "Name " + e2.name + " Age "+ e2.age );
}
}
The implementation of your remove method was faulty. Please see the fixed remove method below. Comments have been added in order to explain the changes.
The solution was tested via an online Java IDE and is verified to work properly.
public void remove(T element)
{
if(first == null) { // edge case - empty list
return;
}
else if(first.value.equals(element)) { // edge case - removing the first element
first = first.next;
this.count--;
return;
}
//Node<T> nn = new Node<T>(); // no need to create a new node, but rather remove an existing node.
Node<T> cur = first.next;
Node<T> prev = first;
//nn.value = element; //no need to create a new node and set its value attribute
boolean deleted = false;
while(cur != null && deleted == false)
{
if(cur.value.equals(element)) //data cannot be resolved or is not a field
{
prev.next = cur.next;
this.count--;
deleted = true;
}
else { // added missing advancement of the loop iterator - cur. prev must also be advanced
cur = cur.next;
prev = prev.next;
}
}
// This implementation adds the removed element to the end of the list, meaning
// it is not a remove method, but rather a move to the end implementation.
// In order to conform to what a remove method does, the last two code lines were commented out.
//prev = gotolastnode(prev);
//prev.next = nn;
}
You must also add an overridden implementation of equals in the Employee class (and other classes) which is used by your list:
class Employee implements Comparable<Employee>
{
String name;
int age;
#Override
public int compareTo(Employee arg0)
{
// sort first by name, then by age
if(name.equals(arg0.name)) {
return age - arg0.age;
}
return name.compareTo(arg0.name);
}
Employee( String nm, int a)
{
name =nm;
age = a;
}
#Override
public boolean equals(Object emp) {
boolean result = false;
if(emp != null && emp instanceof Employee) {
Employee e = (Employee)emp;
result = name.equals(e.name) && (age == e.age);
}
return result;
}
}

What's wrong with my LRUCache code

I try to solution a question in LeetCode,it's ask to implement a LRUCache.
And when I submit my code, the System told me the result is Wrong Answer.
Because the TestCase is too long ,I can't find the problem in my code.And when I choice "Run code" to sumbit my code,it's correct.
Here is my code
public class LRUCache {
private int capacity;
private int size;
private HashMap<Integer, Node> cache = new HashMap<>();
private Node tail;
private Node head;
public LRUCache(int capacity) {
this.capacity = capacity;
size = 0;
tail = new Node(-1, -1);
head = new Node(-1, -1);
tail.setPrev(head);
head.setNext(tail);
}
public Integer get(int key) {
Integer value = -1;
Node old = cache.get(key);
if (old != null){
//move to tail
Node node = new Node(key, old.getValue());
removeNode(old);
moveToTail(node);
value = node.getValue();
}
return value;
}
public void put(int key, int value) {
Node n = new Node(key, value);
Node old = cache.get(key);
boolean isExist = old != null;
if (isExist){
removeNode(old);
size--;
}
//move to tail
moveToTail(n);
cache.put(key, n);
size++;
//remove node if size upper than capacity
while (capacity < size){
Node rm = head.getNext();
cache.remove(rm.getKey());
removeNode(rm);
size--;
}
}
private void removeNode(Node node){
if (node.getPrev() != head){
node.getPrev().setNext(node.getNext());
node.getNext().setPrev(node.getPrev());
}else {
head.setNext(node.getNext());
node.getNext().setPrev(head);
}
node = null;
}
private void moveToTail(Node node){
node.setPrev(tail.getPrev());
tail.getPrev().setNext(node);
tail.setPrev(node);
node.setNext(tail);
}
private class Node{
private int key;
private int value;
private Node prev;
private Node next;
public Node(int key, int value) {
this.key = key;
this.value = value;
this.prev = null;
this.next = null;
}
public int getKey() {
return key;
}
public int getValue() {
return value;
}
public Node getPrev() {
return prev;
}
public void setPrev(Node prev) {
this.prev = prev;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
}
I guess there is problem in your get and put methods. Every time you are creating new nodes. Ideally it should be the same node moved across the DLL. Also, the node should have a setValue() method for updates.
The following update should work.
public Integer get(int key) {
Integer value = -1;
Node old = cache.get(key);
if (old != null){
//move to tail
/////Node node = new Node(key, old.getValue());
removeNode(old);
moveToTail(old);
value = old.getValue();
}
return value;
}
public void put(int key, int value) {
Node n = null;
n = cache.get(key);
if (n != null){
//Update the value of node and move
n.setValue(value);
removeNode(n);
size--;
}
else {
n = new Node(key, value);
}
//move to tail
moveToTail(n);
cache.put(key, n);
size++;
//remove node if size upper than capacity
while (capacity < size){
Node rm = head.getNext();
cache.remove(rm.getKey());
removeNode(rm);
size--;
}
}
Hope it helps!

Deleting Node from BST, multiple errors with Delete function, rest of code Compiles without it

So i'm very much so stuck on my delete function. I keep getting about 20 errors throughout and several are different ones. When I delete the entire thing from my code though, it compiles, so I know it's only this that is missing and messing up my code, but I also really need it in my code of course! here's the delete function and I'll also list my node Class under it as well
public Node delete(Node t, int key){
if (t == null){
return t;
}
else if (key < t.getKey()){
t.getLeft() = delete(t.left, key);
}
else if(key > t.getKey()){
t.getRight() = delete(t.right, key);
}
else{
//Deleting a node with no subtrees
if (t.getLeft() == null && t.getRight() == null){
t = null;
t--;
}
//Node only has one subtree
else if(t.getLeft() != null && t.getRight() == null){
t = t.setLeft();
t--;
}
//Node only has one subtree again for opposite side
else if (t.getLeft() == null && t.getRight() != null){
t = t.setLeft();
t--;
}
//Finding minimum in the right side, and replace
else if (t.getLeft() != null && t.getRight() != null){
temp = t;
if (t.getRight().getRight() == null && t.getRight().getLeft() == null){
temp = successor(t.getLeft());
}
else{
temp = successor(t.getRight());
}
t.key = temp.key;
if (t.getRight().getRight() == null || t.getLeft().getLeft() == null){
t.setLeft() = delete(t.left, t.key);
}
else{
t.setRight() = delete(t.right, t.key);
}
}
}
}
public Node successor(Node t){
while (t.getLeft() != null){
t = t.left;
}
}
Here's my Node Class for reference to some of the functions like getLeft() and so on:
public class Node{
private Node next;
private String name;
private int ssn;
private int key;
private Node left;
private Node right;
public Node(String name, int ssn){
this.name = name;
this.ssn = ssn;
}
public Node getRight(){
return this.right;
}
public Node getLeft(){
return this.left;
}
public void setRight(Node p){
right = p;
}
public void setLeft(Node p){
left = p;
}
public void setNext(Node n){
this.next = n;
}
public int getSSN(){
return this.ssn;
}
public int getKey(){
return ssn%10000;
}
public String getName(){
return name;
}
public Node getNext(){
return this.next;
}
public void setSSN(int ssn){
this.ssn= ssn;
}
}

Binary search tree iterator implementation with no use of collection classes

I am having trouble figuring out how to implement a binary search iterator.
My question is how do i implement an Iterator traversing "in order" while not using the collection classes?
Well the thing is that i have not a clue about how to add "parent" because i find the first 4 items in the iterator when going down but i dont seem to be able to go up since the "parent" either throws nullpointer or dont get the right items.
so how do i add "parent"?
void add(String string) {
if (string.compareTo(value) < 0) {
if(left.left == null){
left.parent = left;
}
if (left == null) {
size++;
left = new Node(string);
if...
thanks.
I suggest a three classes design:
BinarySearchTree: Public class, It represent a Binary search Tree. It contains the tree root as BinaryTreeNode.
BinaryTreeNode: Private nested class, It represent a Node, It has the key and the references: to children and to Its parent.
BinarySearchTreeIterator: Private nested class, It represent an iterator, It use a reference to a BinaryTreeNode to know the current element.
public class BinarySearchTree implements Iterable<String> {
private BinaryTreeNode root = null;
private int elements;
#Override
public Iterator<String> iterator() {
return new BinarySearchTreeIterator(root);
}
private static class BinarySearchTreeIterator implements Iterator<String> {
private BinaryTreeNode node;
public BinarySearchTreeIterator(BinaryTreeNode node) {
if (node != null) {
this.node = smallest(node);
} else {
this.node = node;
}
}
#Override
public boolean hasNext() {
return node != null;
}
private static BinaryTreeNode smallest(BinaryTreeNode n) {
if (n.left != null) {
return smallest(n.left);
} else {
return n;
}
}
#Override
public String next() {
String result = node.key;
if (node.right != null) {
node = smallest(node.right);
} else {
while (node.parent != null && node.parent.left != node) {
node = node.parent;
}
node = node.parent;
}
return result;
}
}
private static class BinaryTreeNode {
private String key;
private BinaryTreeNode parent;
private BinaryTreeNode left;
private BinaryTreeNode right;
public BinaryTreeNode(String key) {
this.key = key;
}
}
public boolean insert(String key) {
if (key == null) {
return false;
}
int lastElements = elements;
this.root = insert(key, root, null);
return lastElements < elements;
}
private BinaryTreeNode insert(String key, BinaryTreeNode node, BinaryTreeNode parent) {
BinaryTreeNode result = node;
if (node == null) {
result = new BinaryTreeNode(key);
result.parent = parent;
this.elements++;
} else {
int compare = key.compareTo(node.key);
if (compare < 0) {
result.left = insert(key, node.left, node);
} else if (compare > 0) {
result.right = insert(key, node.right, node);
}
}
return result;
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
String[] strings = {"l", "f", "t", "c", "g", "p", "u"};
for (String string : strings) {
System.out.println("insert: '" + string + "' " + tree.insert(string));
}
System.out.println("--");
for (String s : tree) {
System.out.println(s);
}
}
}
It prints:
insert: 'l' true
insert: 'f' true
insert: 't' true
insert: 'c' true
insert: 'g' true
insert: 'p' true
insert: 'u' true
--
c
f
g
l
p
t
u

How to do insert method on Word Frequency counter using linked list

public class Frequency<E extends Comparable> implements Iterable<E>{
private Node first;
private int N;
Frequency(){
N = 0;
first = null;
}
#Override
public Iterator<E> iterator() {
return new ListIterator();
}
/**
*
* List iterator
*
*/
private class ListIterator implements Iterator<E>{
private Node current;
private int index ;
ListIterator(){
current = first;
index = 0;
}
#Override
public boolean hasNext() {
return current != null;
}
public E next() {
if(!hasNext()){
return null;
}
E word = current.key;
int count = current.count;
String r = "("+word + "," + Integer.toString(count)+")";
current = current.next;
return (E)r;
}
#Override
public void remove() {
}
public int compareTo(Frequency<E>.Node first) {
return next.compareTo(first);
}
}
}
/**
*
* Node class
*
*/
private class Node {
private E key;
private int count;
private Node next;
Node(E item){
key = item;
count = 1;
next = null;
}
#Override
public String toString(){
return "("+key +","+count+")";
}
}
/*
* Inserts a word into the linked list. If the word exists, increment the
* count by 1.
*/
public void insert(E word){
if(word.equals("")){
return;
}
Node current=first;
Node temp=null;
while(current != null){
if(current.key.equals(word)){
current.count++;
temp=current;
}
current=current.next;
}
while(temp !=null && temp.next != null){
if(temp.count>first.count){
temp=first.next;
first.next=temp.next;
temp.next=first;
first=temp;
}
}
while(temp !=null && temp.next != null){
if(temp.count==first.count){
if(temp.compareTo(first)<0){
temp=first.next;
first.next=temp.next;
temp.next=first;
first=temp;
}
}
}
}
I need to sort the words in their frequency order from most frequent word to the least frequent. If two words have the same frequency they are sorted in alphabetical order. I'm not sure how to do the insert method that combines all the things I have to do. I've made attempts to do the add count part and the frequency ordering part, and I have no idea how to sort the same frequencies alphabetically. Any help would be appreciated.

Categories