I have a big task to do as an exercise for Data Structures and algorithms, and part of it is to modify this tree data structure to print the tree in an alphabetical order.I won't post the whole task because it is huge. Im stuck on the last part which asks me to modify the given tree Data Structure to print the tree in an alphabetical order. I am stuck on it for couple of days and simple don't have any idea how to do it. Any help would be appriciated, thanks. My opinion is that i have to somehow modify the printTreeRecursive() method.
For example the current data structure will print a tree like this:
c: d c b a
(The first added child is printed last).
Where c: is the root and d c b a are his children
But im supposed to modify it to look like this:
c: a b c d
Here is the data structure:
public class SLLTree<E> implements Tree<E> {
// SLLNode is the implementation of the Node interface
class SLLNode<P> implements Node<P> {
// Holds the links to the needed nodes
SLLNode<P> parent, sibling, firstChild;
// Hold the data
P element;
public SLLNode(P o) {
element = o;
parent = sibling = firstChild = null;
}
public P getElement() {
return element;
}
public void setElement(P o) {
element = o;
}
}
protected SLLNode<E> root;
public SLLTree() {
root = null;
}
public Node<E> root() {
return root;
}
public Tree.Node<E> parent(Tree.Node<E> node) {
return ((SLLNode<E>) node).parent;
}
public int childCount(Tree.Node<E> node) {
SLLNode<E> tmp = ((SLLNode<E>) node).firstChild;
int num = 0;
while (tmp != null) {
tmp = tmp.sibling;
num++;
}
return num;
}
public void makeRoot(E elem) {
root = new SLLNode<E>(elem);
}
public Node<E> addChild(Node<E> node, E elem) {
SLLNode<E> tmp = new SLLNode<E>(elem);
SLLNode<E> curr = (SLLNode<E>) node;
tmp.sibling = curr.firstChild;
curr.firstChild = tmp;
tmp.parent = curr;
return tmp;
}
public void remove(Tree.Node<E> node) {
SLLNode<E> curr = (SLLNode<E>) node;
if (curr.parent != null) {
if (curr.parent.firstChild == curr) {
// The node is the first child of its parent
// Reconnect the parent to the next sibling
curr.parent.firstChild = curr.sibling;
} else {
// The node is not the first child of its parent
// Start from the first and search the node in the sibling list
// and remove it
SLLNode<E> tmp = curr.parent.firstChild;
while (tmp.sibling != curr) {
tmp = tmp.sibling;
}
tmp.sibling = curr.sibling;
}
} else {
root = null;
}
}
class SLLTreeIterator<T> implements Iterator<T> {
SLLNode<T> start, current;
public SLLTreeIterator(SLLNode<T> node) {
start = node;
current = node;
}
public boolean hasNext() {
return (current != null);
}
public T next() throws NoSuchElementException {
if (current != null) {
SLLNode<T> tmp = current;
current = current.sibling;
return tmp.getElement();
} else {
throw new NoSuchElementException();
}
}
public void remove() {
if (current != null) {
current = current.sibling;
}
}
}
public Iterator<E> children(Tree.Node<E> node) {
return new SLLTreeIterator<E>(((SLLNode<E>) node).firstChild);
}
void printTreeRecursive(Node<E> node, int level) {
if (node == null)
return;
int i;
SLLNode<E> tmp;
for (i = 0; i < level; i++)
System.out.print(" ");
System.out.println(node.getElement().toString());
tmp = ((SLLNode<E>) node).firstChild;
while (tmp != null) {
printTreeRecursive(tmp, level + 1);
tmp = tmp.sibling;
}
}
public void printTree() {
printTreeRecursive(root, 0);
}
public int countMaxChildren() {
return countMaxChildrenRecursive(root);
}
int countMaxChildrenRecursive(SLLNode<E> node) {
int t = childCount(node);
SLLNode<E> tmp = node.firstChild;
while (tmp != null) {
t = Math.max(t, countMaxChildrenRecursive(tmp));
tmp = tmp.sibling;
}
return t;
}
}
public interface Tree<E> {
// //////////Accessors ////////////
public Tree.Node<E> root();
public Tree.Node<E> parent(Tree.Node<E> node);
public int childCount(Tree.Node<E> node);
// //////////Transformers ////////////
public void makeRoot(E elem);
public Tree.Node<E> addChild(Tree.Node<E> node, E elem);
public void remove(Tree.Node<E> node);
// //////////Iterator ////////////
public Iterator<E> children(Tree.Node<E> node);
// //////Inner interface for tree nodes ////////
public interface Node<E> {
public E getElement();
public void setElement(E elem);
}
}
public class SLLTreeTest {
public static void main(String[] args) {
Tree.Node<String> a, b, c, d;
SLLTree<String> t = new SLLTree<String>();
t.makeRoot("C:");
a = t.addChild(t.root, "Program files");
b = t.addChild(a, "CodeBlocks");
c = t.addChild(b, "codeblocks.dll");
c = t.addChild(b, "codeblocks.exe");
b = t.addChild(a, "Nodepad++");
c = t.addChild(b, "langs.xml");
d = c;
c = t.addChild(b, "readme.txt");
c = t.addChild(b, "notepad++.exe");
a = t.addChild(t.root, "Users");
b = t.addChild(a, "Darko");
c = t.addChild(b, "Desktop");
c = t.addChild(b, "Downloads");
c = t.addChild(b, "My Documents");
c = t.addChild(b, "My Pictures");
b = t.addChild(a, "Public");
a = t.addChild(t.root, "Windows");
b = t.addChild(a, "Media");
t.printTree();
t.remove(d);
t.printTree();
System.out.println("The maximum number of children is "
+ t.countMaxChildren());
}
}
As I see, my initial suggestion is good-enough for the asker and other commenters as well. So, as this is a studying task, I will not write code as an answer (I would take all the fun, wouldn't I?). I will share some important checkpoints to reach in the thought process, which, if reached should lead to the solution:
we need a Collection
we need to use a breadth-first traversing (printTreeRecursive is a good example)
we need to look at the while cycle of printTreeRecursive, as it is key to reach a traversing
whenever we reach a node, we should insert sort the node into the collection
after the traversing, we iterate the Collection and print out its elements
Related
I'm doing an assignment for an internship, and they gave me a task to create a navigation menu, such as this one down bellow:
. Company
.... About Us
....... Team
.... Mission
. References
.... Client 1
.... Client 2
The whole point of the task is for me to find a way to transform this input into a tree structure and then print it out recursively...
The input is:
ID NAME PARENTID
1; Company; NULL;
2; About Us; 1;
3; Mission; 1;
4; Team; 2;
5; Client1; 7;
6; Client2; 7;
7; References; NULL;
If this was a first parent then children type of input, then the task would be super easy, however I'm stuck and can't seem to understand the algorithm behind it. The whole deal is that References are added at the end, but Client 1 & Client 2 are both children of References...
Here are the codes:
Model class:
// WITH SETTERS AND GETTERS
public class NavLink
{
private String id;
private String name;
private String parentId;
private String isHidden;
private String linkUrl;
}
Triple Linked List Node Class:
public class TLLNode<NavLink>
{
public NavLink element;
public TLLNode<NavLink> parent, sibling, child;
public TLLNode(NavLink elem)
{
this.element = elem;
parent = sibling = child = null;
}
}
Tree class:
public class Tree
{
private TLLNode<NavLink> root;
public Tree(NavLink element) { this.root = new TLLNode(element); }
public TLLNode<NavLink> getRoot() { return this.root; }
public void addChild(TLLNode<NavLink> node, NavLink element)
{
TLLNode<NavLink> insert = new TLLNode<>(element);
if (node.child == null)
node.child = insert;
else
{
if (node.child.element.getName().compareTo(insert.element.getName()) > 0)
insert.sibling = node.child;
else
{
TLLNode<NavLink> tmp = node.child;
while (tmp.sibling != null)
{
if (tmp.sibling.element.getName().compareTo(insert.element.getName()) > 0)
{
insert.sibling = tmp.sibling;
break;
}
tmp = tmp.sibling;
}
tmp.sibling = insert;
}
}
insert.parent = node;
}
public void printTree() { printTreeRecursive(this.root, 0); }
private void printTreeRecursive(TLLNode<NavLink> node, int level)
{
if (node == null)
return;
for (int i=0; i < level-1; i++)
System.out.print("...");
if (node.element.getHidden().equalsIgnoreCase("False"))
System.out.println("." + node.element.getName());
TLLNode<NavLink> tmp = node.child;
while (tmp != null)
{
printTreeRecursive(tmp, level+1);
tmp = tmp.sibling;
}
}
}
And finally the Main class, where the problem is situated:
public class Main
{
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] parts;
List<NavLink> list = new LinkedList<>();
NavLink link = new NavLink("NULL", "/", "/", "True", "/" );
Tree tree = new Tree(link);
for (int i=0; i<n; i++)
{
parts = br.readLine().split(";");
link = new NavLink(parts[0], parts[1], parts[2], parts[3], parts[4]);
list.add(link);
}
/*TLLNode<NavLink> current;
for (NavLink item : links)
{
current = new TLLNode<>(item);
System.out.println(item);
for (NavLink tmp : links.subList(1, links.size()))
{
if (tmp.getParentId().equalsIgnoreCase(current.element.getId()))
tree.addChild(current, tmp);
}
}*/
addChildRecursive(tree, list, tree.getRoot());
tree.printTree();
}
public static void addChildRecursive(Tree tree, List<NavLink> list, TLLNode<NavLink> current)
{
if (current == null)
return;
TLLNode<NavLink> insert;
for (NavLink item : list)
{
insert = new TLLNode<>(item);
if (insert.element.getParentId() == current.element.getId())
{
tree.addChild(current, insert.element);
list.remove(insert.element);
addChildRecursive(tree, list, current.child);
}
}
}
}
The method addChildRecursive is the one that is giving me the problems, in the output it doesn't say that there are any errors.
I don't understand what needs to be done here?
P.S. Ignore the isHidden and other attributes, the main problem is with the addChildRecursive method
First of all in java it's recommended that you check if two strings are equal with now equals() function and not the == operator.
Now for your question, it's seems that you only check the child of the current node and because there could be more than one child you don't check them all.
I suggest to use a list of child or some other sort of mechanism to save all the children directly and not thru the "sibling" pointer.
When I create a Node object and call "appendToTail" the Node object has a sequence of nodes via the next attribute (as expected). I tried creating a pop, where it takes the head (aka 'this') and reference it with a variable and overwrite it with its next. However, 'this' remains the same as the original head. What am I doing wrong, or is there no way to modify 'this'?
public class Node {
Node next = null;
int data;
public Node(int d) {
data = d;
}
public void appendToTail(int d) {
Node end = new Node(d);
Node n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
}
public void popHead() {
Node n = this;
n = n.next;
}
}
Basically you need to construct a custom List and add each node at End. Also you need to store first node in order to have the starting point for looping.
public class NodeList
{
Node head=null;
public static void main(String args[])
{
NodeList nl = new NodeList();
nl.addNode(1);
nl.addNode(2);
nl.addNode(3);
nl.listNodes();
}
public void addNode(int data)
{
if(head==null)
{
head = new Node(data);
}
else
{
Node curent = head;
while(curent.next != null)
{
curent = curent.next;
}
curent.next = new Node(data);
}
}
public void listNodes()
{
if(head !=null)
{
Node curent = head;
System.out.println(curent.data);
while(curent.next !=null)
{
curent = curent.next;
System.out.println(curent.data);
}
}
}
class Node
{
Node next = null;
int data;
public Node(int d) {
data = d;
}
}
}
Output
1
2
3
I am trying to create an Iterator implementation for post-order and I am in a slump. I was able to get in-order and pre-order implementations but I can't seem to get a post-order. If you guys can point me in the right direction and give me some tips, that would be amazing.
Here's my in-order class:
public class InOrderIterator<T> implements Iterator<T> {
private final Deque<BinaryTreeNode<T>> stack;
private BinaryTreeNode<T> current;
public InOrderIterator(BinaryTreeNode<T> root){
stack = new LinkedList<BinaryTreeNode<T>>();
this.current = root;
}
#Override
public boolean hasNext() {
return (!stack.isEmpty() || current != null);
}
#Override
public T next() {
while (current != null) {
stack.push(current);
if (current.hasLeftChild())
current = current.getLeftChild();
else
current = null;
}
current = stack.pop();
BinaryTreeNode<T> node = current;
if (current.hasRightChild())
current = current.getRightChild();
else
current = null;
return node.getData();
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Here's a description of pre-, in-, and post-order:
Pre-order
Visit the root.
Traverse the left subtree.
Traverse the right subtree.
In-order
Traverse the left subtree.
Visit root.
Traverse the right subtree.
Post-order
Traverse the left subtree.
Traverse the right subtree.
Visit the root.
http://en.wikipedia.org/wiki/Tree_traversal#Types
I googled for a binary tree postorder iterator implementation but could not find a good one. So I implemented mine using two stacks.
public class BinaryTreePostorderIterator implements Iterator<Integer> {
private TreeNode root;
private Stack<TreeNode> nodes;
private Stack<Boolean> expanded;
public BinaryTreePostorderIterator(TreeNode root) {
this.root = root;
nodes = new Stack<>();
expanded = new Stack<>();
if (root != null) {
nodes.push(root);
expanded.push(false);
}
}
#Override
public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException("End reached");
}
expanded.pop();
return nodes.pop().val;
}
#Override
public boolean hasNext() {
if (nodes.isEmpty()) {
return false;
}
while (!expanded.peek()) {
expanded.pop();
expanded.push(true);
TreeNode node = nodes.peek();
if (node.right != null) {
nodes.push(node.right);
expanded.push(false);
}
if (node.left != null) {
nodes.push(node.left);
expanded.push(false);
}
}
return true;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.left.right = new TreeNode(4);
root.left.left = new TreeNode(2);
root.right = new TreeNode(7);
root.right.right = new TreeNode(8);
root.right.left = new TreeNode(6);
BinaryTreePostorderIterator pi = new BinaryTreePostorderIterator(root);
while (pi.hasNext()) {
System.out.println(pi.next());
}
}
}
One fairly general way to achieve this is by starting from the recursive algorithm, and turning it into an iterative algorithm with an explicit stack. Then, you find points in the recursive algorithm where it would output data, and you pause your computation there (in this example, by returning from the advance() method, and making sure the stack is left in a good state for the next call to advance()).
My recursive algorithm (I'm using Java 8 and a different Node class, but it's along the same lines) was:
private void postorder(Node<V> node, Consumer<V> c) {
// step 0
if (node == null) {
return; // pop
}
postorder(node.left, onTraverse); // push
// step 1
postorder(node.right, onTraverse); // push
// step 2
c.accept(node.data);
// pop
}
which turns into the following iterator:
class PostorderIterator<V> implements Iterator<V> {
class Frame {
int step;
Node<V> node;
public Frame(Node<V> node) {
this.node = node;
step = 0;
}
}
Stack<Frame> st = new Stack<>();
boolean ready;
V result;
public PostorderIterator(Node<V> node) {
st.push(new Frame(node));
}
private V advance() {
while (!st.isEmpty()) {
Frame f = st.peek();
switch (f.step) {
case 0:
if (f.node == null) {
st.pop(); // return
} else {
f.step = 1;
st.push(new Frame(f.node.left)); // ~postorder(node.left, ...)
}
break;
case 1:
f.step = 2;
st.push(new Frame(f.node.right)); // ~postorder(node.right, ...)
break;
case 2:
st.pop(); // ~return
return f.node.data;
default:
throw new RuntimeException();
}
}
return null;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
#Override
public boolean hasNext() {
if (!ready) {
result = advance();
ready = true;
}
return result != null;
}
#Override
public V next() {
if (!ready) {
result = advance();
ready = true;
}
if (result == null) {
throw new NoSuchElementException();
}
ready = false;
return result;
}
}
This approach might be a bit clunkier than necessary, but having an explicit Frame holding your local variables, arguments, and where you are in the code, should be a decent starting point to a cleaner algorithm.
I just played a bit with post order iterator..
This is what I've come up with:
class PostOrderIterator
implements Iterator<T> {
private Stack<Node<T>> stack;
private Node<T> prev;
public PostOrderIterator() {
this.stack = new Stack<>();
recurse(root);
this.prev = this.stack.peek();
}
private void recurse(Node<T> node) {
if(node == null) {
return;
}
while(node != null) {
stack.push(node);
node = node.left;
}
recurse(stack.peek().right);
}
#Override
public boolean hasNext() {
return !stack.isEmpty();
}
#Override
public T next() {
if(stack.peek().right != this.prev) {
recurse(stack.peek().right);
}
Node<T> next = stack.pop();
this.prev = next;
return next.value;
}
}
Basically, the main idea is that you should think how the initialization process puts the first item to print on the top of the stack, while the rest of the stack follow the nodes that would have been touched by the recursion. The rest would just then become a lot easier to nail.
Also, from design perspective, PostOrderIterator is an internal class exposed via some factory method of the tree class as an Iterator<T>.
I am a newbie in Java and OOP, the previous language that I've learned being C.
I am trying to create a Linked List that extends AbstractList and that allows the usage of Collections.sort() function. The problem is that when I call the Collections.sort() function, I get a nullPointerException. My guess is that the exception resides from the fact that the last node in my list is a null one (so I can know where the list ends).
class Node
{
Object o;
Node next;
public Node(Object n)
{
o = n;
next = null;
}
}
class LinkList extends AbstractList
{
Comparator c;
public Node head, last;
public LinkList(Comparator c)
{
this.c = c;
head = null;
last = null;
}
#Override
public boolean add(Object a)
{
Node t = new Node(a);
if(last == null)
{
head = t;
last = t;
last.next = null;
}
else //thanks, hyde
if(last != null)
{
last.next = t;
last = t;
last.next = null;
}
return true;
}
#Override
public Object get(int a)
{
Node it = head;
int contor = 0;
while(it!=null && contor<a)
{
it = it.next;
}
if(it!=null)
{
return it;
}
else
return null;
}
#Override
public Object set(int i, Object a)
{
Node it = head;
int contor = 0;
Node aux;
while(it!=null && contor<i)
{
it = it.next;
}
if(it!=null)
{
aux = it;
it.o = a;
// Collections.sort(this,c);
return aux;
}
else
return null;
}
#Override
public int size()
{
Node it = head;
int contor = 0;
while(it!=null)
{
contor++;
it = it.next;
}
return contor;
}
#Override
public int indexOf(Object a)
{
Node it = head;
int contor = 0;
while(it!=null && it.o.equals(a)==false)
{
it = it.next;
contor++;
}
if(it!=null)
{
return contor;
}
else
return -1;
}
}
public class Test
{
public static void main(String args[])
{
LinkList lista = new LinkList(new Comparator(){
#Override
public int compare(Object o1, Object o2)
{
int s1 = (int) o1;
int s2 = (int) o2;
return s2-s1;
}
});
lista.add(2);
lista.add(3);
Collections.sort(lista); //this is line 156
System.out.println(lista.size());
}
}
Basically, I add two elements and I try to sort the list and I get the nullPointerException. It feels very frustrating, because I have no control over the sort function.
Exception in thread "main" java.lang.NullPointerException
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at Ex6.main(Ex6.java:156)
Java Result: 1
You are missing contor++ in the loop inside the get method so it always returns null.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I implement a Linked List in Java?
We know there is no pointers in java. Then what is the best way to build the link list in java?
The best way is to not build it. Java already has a LinkedList class amongst its rather large selection of collection classes.
You would be better off using what the language/library already provides.
You have an object that essentially contains two variables, no methods (bare minimum; however, you could have methods if you wanted). Something like:
class Link
{
int data;
Link next;
}
Then you create a new Link like any other object. Set the data to the data you want a node to hold. Then set the Link node to the node that it will be "pointing" to (or null if it doesn't point to another one).
Note: you can also have a previous node (which points to the previous node) if need be.
try having this code.
public class Main {
public static void main(String[] args) {
LinkedList theList = new LinkedList();
LinkedListIterator theItr;
theItr = theList.zeroth();
printList(theList);
for (int i = 0; i < 10; i++) {
theList.insert(new Integer(i), theItr);
printList(theList);
theItr.advance();
}
System.out.println("Size was: " + listSize(theList));
}
public static int listSize(LinkedList theList) {
LinkedListIterator itr;
int size = 0;
for (itr = theList.first(); itr.isValid(); itr.advance())
size++;
return size;
}
public static void printList(LinkedList theList) {
if (theList.isEmpty())
System.out.print("Empty list");
else {
LinkedListIterator itr = theList.first();
for (; itr.isValid(); itr.advance())
System.out.print(itr.retrieve() + " ");
}
System.out.println();
}
}
class LinkedList {
public LinkedList() {
header = new ListNode(null);
}
public boolean isEmpty() {
return header.next == null;
}
public void makeEmpty() {
header.next = null;
}
public LinkedListIterator zeroth() {
return new LinkedListIterator(header);
}
public LinkedListIterator first() {
return new LinkedListIterator(header.next);
}
public void insert(Object x, LinkedListIterator p) {
if (p != null && p.current != null)
p.current.next = new ListNode(x, p.current.next);
}
public LinkedListIterator find(Object x) {
ListNode itr = header.next;
while (itr != null && !itr.element.equals(x))
itr = itr.next;
return new LinkedListIterator(itr);
}
public LinkedListIterator findPrevious(Object x) {
ListNode itr = header;
while (itr.next != null && !itr.next.element.equals(x))
itr = itr.next;
return new LinkedListIterator(itr);
}
public void remove(Object x) {
LinkedListIterator p = findPrevious(x);
if (p.current.next != null)
p.current.next = p.current.next.next; // Bypass deleted node
}
private ListNode header;
}
class LinkedListIterator {
LinkedListIterator(ListNode theNode) {
current = theNode;
}
public boolean isValid() {
return current != null;
}
public Object retrieve() {
return isValid() ? current.element : null;
}
public void advance() {
if (isValid())
current = current.next;
}
ListNode current;
}
class ListNode {
public ListNode(Object theElement) {
this(theElement, null);
}
public ListNode(Object theElement, ListNode n) {
element = theElement;
next = n;
}
public Object element;
public ListNode next;
}