I programmed a Binary-Tree, now I am facing a problem during printing in order. When I call my printIO method, the printIOmethod calls another method which requires as parameter the root Node (as I print recursively) the method calls each time and passes the next node.
Is there any way to print the tree without 2 methods and no parameter in the main?
Idea:
make the temp Node static and don't use a parameter in the final print method. This didn't worked, as I got some Exceptions. Any idea?
Code snippet main:
BinList bl = new BinList();
bl.add(9);
bl.add(7);
...
bl.printIO();
Code snippet of the List Class:
public void printIO() {
print_in_order(root);
}
private void print_in_order(Node temp) {
if (temp != null) {
print_in_order(temp.left);
System.out.println(temp.data);
print_in_order(temp.right);
}
}
Instead of printing in the BinList class you should split the responsability between the BinList class and the Node class:
public class BinList {
private Node root = ...;
public void printInOrder() {
if (root != null) {
root.printInOrder();
}
}
}
public class Node {
private Node left, right;
private Object data;
public void printInOrder() {
if (left != null) {
left.printInOrder();
}
System.out.printl(data);
if (right != null) {
right.printInOrder();
}
}
}
Related
I'm trying to learn and have a question about Recursive Methods in Collections I read here that:
"When implementing collection classes with recursive methods, we typically must write a pair of methods for each operation.
The first method is the public one specified in the interface. It can be written iteratively or recursively. It is written iteratively, it simply calls ...
The second method, which is a private static one that does all the work.
For example, suppose that we are implementing a generic priority queue (LN stores value as an Object) via a linked list, using a front instance variable and a priorityComparator instance variables. We would implement the add method in this class with the following pair of methods."
the QUOTED code is:
public void add (Object o)
{front = add(front,o);}
private static LN add (LN l, Object o)
{
if (l == null || priorityComparator.compare(l.value,o) < 0)
return new LN(value,l);
else {
l.next = add(l.next, o);
return l;
}
}
The source of the above informations and code is here -> link
sadly enough I found just one source :(
QUESTION1: I would like to know what benefit can this way of writing method brings to the implementation of a certain collection?
so per example, I wrote my implemented LinkedList methods like this:
//insertion....
public void insert(E data) {
first = insertEnd(first, data);
last = getLast();
//length++;
}
private static <E> Node insert(Node head, E data) {
if (head == null) {
return new Node(data);
} else {
head.setNext(insert(head.getNext(), data));
}
return head;
}
public void printList() {
printList(first);
System.out.println();
}
private static void printList(Node head) {
if (head == null) {
System.out.println("null");
return;
}
System.out.print(head.getData() + "->");
printList(head.getNext());
}
public int size() {
return size(first);
}
private static int size(Node head) {
if (head == null) {
return 0;
} else {
return 1 + size(head.getNext());
}
}
public boolean contains(E data) {
return contains(first, data);
}
public static <E> boolean contains(Node head, E data) {
if (head == null || data == null) {
return false;
}
if (head.getData().equals(data)) {
return true;
}
return contains(head.getNext(), data);
}
//count occurrences of certain value
public int countIf(E t) {
return countIf(first, t);
}
private static <E> int countIf(Node head, E t) {
if (head == null) {
return 0;
}
if (head.getData().equals(t)) {
return 1 + countIf(head.getNext(), t);
}
return countIf(head.getNext(), t);
}
//TODO: WHY IM GETTING HERE AN OVERRIDE REQUEST FROM THE COMPILER??
public ListNode<E> clone() {
first = clone(first);
ListNode<E> copy = new ListNode<>(first);
return copy;
}
private static Node clone(Node head) {
if (head == null) {
return null;
}
Node temp = new Node(head.getData());
temp.setNext(clone(head.getNext()));
return temp;
}
public ListNode<E> invert() {
first = invert(first);
ListNode<E> inverted = new ListNode<>(first);
return inverted;
}
private static Node invert(Node head) {
if (head.getNext() == null) {
return head;
}
Node newHead = invert(head.getNext());
head.getNext().setNext(head);//head.next.next=node;
head.setNext(null);//gead.next=null;
return newHead;
}
Question2is what is my following primitive idea about this topic right?
so as a beginner I would try to share my point of view about the potential benefit of this way and please try to correct me if I'm mistaken and if I missed something please point it out!
first, in case of an assertion , contains() and countIf(), this might be helpful because in main the user wouldn't have to put the head of the list as a parameter.
and because each method would be called like this list1.method() thus each list would have another head node.
second, in case of inverting and cloning, where I have to return ListNode instead of Node i can understand that the creation of the list has to be in the invert() or clone() methods.
sadly enough I couldn't find enough info online pls feel free to provide your favorite references and feel free to write your own explanation about this.
have a nice one. :)
QUESTION: What benefit can this way of writing method bring to the implementation of a certain collection?
Benefit: It works. It's doable.
What's the alternative? One method? Which of the two would that be?
void insert(E data)? Then how would the recursion work?
Node insert(Node head, E data)? Where would caller get the head value? What would caller do with the return value?
Take another look at all your method pairs. Do you see a pattern? Like, all the private methods have a Node parameter. None of the public methods do.
I am trying to implement Queue using Linked list in java from scratch without using LinkedList class. But, the code is returning null pointer exception. Please correct me if i am wrong. The output i am getting is 1 2 4 5 then null pointer exception.
package example2;
class Node
{
int data;
Node next;
Node(int data)
{
this.data=data;
}
}
public class ex {
Node last=null,first=null;
private void push(int item)
{
if(last==null)
{
first=last=new Node(item);
}
else
{
Node n = new Node(item);
last.next=n;
n.next=null;
last=n;
}
}
private void pop()
{
first=first.next;
}
public void disp()
{
while(first!=null)
{
System.out.println(first.data);
first=first.next;
}
}
public static void main(String []args)
{
ex e=new ex();
e.push(1);
e.push(2);
e.push(4);
e.push(5);
e.disp();
e.pop();
e.disp();
}
}
Your disp() method changes the value of first. Instead of iterating using first and changing its value, iterate using a temporary reference:
public void disp() {
Node current = first; //Start with "first"
while (current != null) {
System.out.println(current.data);
current = current.next; //Move "current" to next node
}
}
I dont have much experience with generics at all and am trying to get the hang of using them. After getting this to work with integers im trying to get it to work using generics but i keep getting the following error
required: genericTree
found: int
reason: actual argument int cannot be converted to genericTree by method invocation conversion
where T is a type-variable:
T extends Object declared in class genericTree
genericTree.java:83: error: method add in class genericTree cannot be applied to given types;
I get what its telling me but im not sure how to fix it. ive been trying different approaches but nothing seems to work for me.
heres my full code:
import java.util.*;
class genericTree<T>{
private Node root;
public List <genericTree<T>> list;
private class Node
{
Node left;
Node right;
T data;
Node(T newData)
{
left = null;
right = null;
data = newData;
}
}
genericTree()
{
root = null;
}
public boolean breadthSearch(genericTree<T> searchValue)
{
Queue<Node> queue = new LinkedList<Node>() ;
if (this.root == null)
return false;
queue.clear();
queue.add(root);
while(!queue.isEmpty())
{
Node node = queue.remove();
System.out.print(node.data + " ");
if(node.data == searchValue)
return true;
if(node.left != null)
queue.add(node.left);
if(node.right != null)
queue.add(node.right);
}
return false;
}
public void add(genericTree<T> data)
{
list.add(data);
}
public void display()
{
display(root);
}
private void display(Node node)
{
if(node==null)
return;
display(node.left);
System.out.println(node.data + " ");
display(node.right);
}
public static void main(String[] args)
{
genericTree bst = new genericTree();
bst.add(10);
bst.add(5);
bst.add(6);
bst.add(13);
bst.add(15);
bst.add(8);
bst.add(14);
bst.add(7);
bst.add(12);
bst.add(4);
bst.breadthSearch(6);
}
}
thanks for any help
IT looks like you intended the following
public boolean breadthSearch(genericTree<T> searchValue)
to be this
public boolean breadthSearch(T searchValue)
You might also want to make sure that your genericTree<T> is a genericTree<int>
genericTree<int> bst = new genericTree<int>();
I want to build an array recursively I started this way and cant figure how to do it properly:
public class ConnectivityNode {
private Server server;
private ConnectivityNode parent;
private ArrayList<ConnectivityNode> children;
...
public Server[] getServerRoute(){
if(this.parent == null) { return null; }
return this.server + this.parent.getServerRoute(); //of course this isnt correct
}
}
The idea is to get an array of Servers
{ parent.parent.server1, parent.server2, server3 }
One option is to work with a List and create a helper function:
private void getServerRouter(List<Server> l) {
l.add(server);
if (parent != null) {
parent.getServerRouter(l)
}
}
public Server[] getServerRouter() {
List<Server> l = new ArrayList<>();
getServerRouter(l);
return l.toArray(new Server[l.size()]);
}
You might even consider returning the List from the public method (that might make more sense).
You will need an function with a parameter. So for example like this:
public void getServerRoute(Server actualServer){
children.add(actualServer);
if(actualServer.hasParent())
getServerRoute(actualServer.getParent());
}
As I do not know how you find the parent of a server I just assumed you have a function for that matter.
Use an ArrayList:
There are two ways to do this. If you have to return an array, you can use:
public Server[] getServerRoute()
{
if(this.parent == null)
{
return null;
}
ArrayList<Server> servers = new ArrayList<Server>();
servers.add(this.server);
servers.addAll(Arrays.asList(this.parent.getServerRoute()));
return servers.toArray(new Server[0]);
}
If it's okay to just return an ArrayList (which can trivially be converted into an array, just as we did above), it would be make the function simpler:
public ArrayList<Server> getServerRoute()
{
if(this.parent == null)
{
return null;
}
ArrayList<Server> servers = new ArrayList<Server>();
servers.add(this.server);
servers.addAll(this.parent.getServerRoute());
return servers;
}
if i understand you correcty, and you want to obtain route from current element to root element in your tree, it will be something like that:
public Server[] getServerRoute(){
List<Server> servers=new ArrayList<>();
walk(this,servers);
return servers.toArray(new Server[servers.size()]);
}
private static void walk(ConnectivityNode node,List<Server> servers)
{
servers.add(node.getServer());
if (node.getParent() != null)
{
walk(node.getParent(),servers);
}
}
I have an assignment that I am terribly lost on involving doubly linked lists (note, we are supposed to create it from scratch, not using built-in API's). The program is supposed to keep track of credit cards basically. My professor wants us to use doubly-linked lists to accomplish this. The problem is, the book does not go into detail on the subject (doesn't even show pseudo code involving doubly linked lists), it merely describes what a doubly linked list is and then talks with pictures and no code in a small paragraph. But anyway, I'm done complaining. I understand perfectly well how to create a node class and how it works. The problem is how do I use the nodes to create the list? Here is what I have so far.
public class CardInfo
{
private String name;
private String cardVendor;
private String dateOpened;
private double lastBalance;
private int accountStatus;
private final int MAX_NAME_LENGTH = 25;
private final int MAX_VENDOR_LENGTH = 15;
CardInfo()
{
}
CardInfo(String n, String v, String d, double b, int s)
{
setName(n);
setCardVendor(v);
setDateOpened(d);
setLastBalance(b);
setAccountStatus(s);
}
public String getName()
{
return name;
}
public String getCardVendor()
{
return cardVendor;
}
public String getDateOpened()
{
return dateOpened;
}
public double getLastBalance()
{
return lastBalance;
}
public int getAccountStatus()
{
return accountStatus;
}
public void setName(String n)
{
if (n.length() > MAX_NAME_LENGTH)
throw new IllegalArgumentException("Too Many Characters");
else
name = n;
}
public void setCardVendor(String v)
{
if (v.length() > MAX_VENDOR_LENGTH)
throw new IllegalArgumentException("Too Many Characters");
else
cardVendor = v;
}
public void setDateOpened(String d)
{
dateOpened = d;
}
public void setLastBalance(double b)
{
lastBalance = b;
}
public void setAccountStatus(int s)
{
accountStatus = s;
}
public String toString()
{
return String.format("%-25s %-15s $%-s %-s %-s",
name, cardVendor, lastBalance, dateOpened, accountStatus);
}
}
public class CardInfoNode
{
CardInfo thisCard;
CardInfoNode next;
CardInfoNode prev;
CardInfoNode()
{
}
public void setCardInfo(CardInfo info)
{
thisCard.setName(info.getName());
thisCard.setCardVendor(info.getCardVendor());
thisCard.setLastBalance(info.getLastBalance());
thisCard.setDateOpened(info.getDateOpened());
thisCard.setAccountStatus(info.getAccountStatus());
}
public CardInfo getInfo()
{
return thisCard;
}
public void setNext(CardInfoNode node)
{
next = node;
}
public void setPrev(CardInfoNode node)
{
prev = node;
}
public CardInfoNode getNext()
{
return next;
}
public CardInfoNode getPrev()
{
return prev;
}
}
public class CardList
{
CardInfoNode head;
CardInfoNode current;
CardInfoNode tail;
CardList()
{
head = current = tail = null;
}
public void insertCardInfo(CardInfo info)
{
if(head == null)
{
head = new CardInfoNode();
head.setCardInfo(info);
head.setNext(tail);
tail.setPrev(node) // here lies the problem. tail must be set to something
// to make it doubly-linked. but tail is null since it's
// and end point of the list.
}
}
}
Here is the assignment itself if it helps to clarify what is required and more importantly, the parts I'm not understanding. Thanks
https://docs.google.com/open?id=0B3vVwsO0eQRaQlRSZG95eXlPcVE
if(head == null)
{
head = new CardInfoNode();
head.setCardInfo(info);
head.setNext(tail);
tail.setPrev(node) // here lies the problem. tail must be set to something
// to make it doubly-linked. but tail is null since it's
// and end point of the list.
}
the above code is for when u not have any nodes in list, here u r going to add nodes to ur list.I.e. ist node to list
here u r pointing head & tail to same node
I assume CardList is meant to encapsulate the actual doubly-linked-list implementation.
Consider the base case of a DLL with only a single node: the node's prev and next references will be null (or itself). The list's encapsulation's head and tail references will both be the single node (as the node is both the start and end of the list). What's so difficult to understand about that?
NB: Assuming that CardList is an encapsulation of the DLL structure (rather than an operation) there's no reason for it to have a CardInfoNode current field, as that kind of state information is only useful to algorithms that work on the structure, which would be maintaining that themselves (it also makes your class thread-unsafe).