For an assignment, I need to create an iterable that contains all keys for a symbol table backed by a binary search tree. I'm familiar with how to do this for a linked list, but can't seem to find any examples online about how to do this for a BST. For a linked list, for example, I'd use something like this:
public Iterable<Key> keys() {
Queue<Key> queue = new Queue<Key>();
for (Node x = first; x != null; x = x.next)
queue.enqueue(x.key);
return queue;
}
But I'm not quite sure how to convert that so it holds all keys for my BST. Can someone provide guidance or a link to a source that covers this topic?
If you want to traverse left first, you can implement it using a stack.
static class Node<T> {
T value;
Node<T> left, right;
Node(T value, Node<T> left, Node<T> right) {
this.value = value;
this.left = left;
this.right = right;
}
}
and
static class BST<T> implements Iterable<T> {
Node<T> root;
public BST(Node<T> root) {
this.root = root;
}
#Override
public Iterator<T> iterator() {
return new Iterator<>() {
Deque<Node<T>> stack = new LinkedList<>();
{ pushAllLeft(root); }
private void pushAllLeft(Node<T> node) {
for ( ; node != null; node = node.left)
stack.push(node);
}
#Override
public boolean hasNext() {
return !stack.isEmpty();
}
#Override
public T next() {
Node<T> current = stack.pop();
pushAllLeft(current.right);
return current.value;
}
};
}
}
and
public static void main(String[] args) {
BST<Integer> bst = new BST<>(
new BST.Node<>(3,
new BST.Node<>(1,
new BST.Node<>(0, null, null),
new BST.Node<>(2, null, null)),
new BST.Node<>(5,
new BST.Node<>(4, null, null),
new BST.Node<>(6, null, null))));
for (int n : bst)
System.out.println(n);
}
output:
0
1
2
3
4
5
6
Related
In the below code I am trying to insert a node at the beginning of the linked list
When I try to insert a value 2 it should be inserted at the beginning of the LL that is before the start node as it is the smallest value
class Main{
public static void main(String args[]) {
class Node{
int data;
Node next;
Node(int data){
this.data = data;
}
Node(int data, Node next){
this.data=data;
this.next=next;
}
public Node insert(Node start, int x){
if (start == null || start.data > x) {
start = new Node(x,start.next);
return start;
}
Node p = start;
while (p.next != null) {
if (p.next.data > x)
break;
p = p.next;}
p = p.next = new Node(x,p.next);
return start;
}
}
Node start = new Node(10);
Node p = start;
for(int i=0;i<3;i++) {
p = p.next=new Node(20+10*i);
}
p.insert(start,2);
for(p=start;p!=null;p=p.next) {
System.out.println(p.data);
}
}
}
Output:
10
20
30
40
Desired Output:
2
10
20
30
40
The typical solution to this is that you need a class that wraps around your nodes and maintains a reference to the head of the list:
public class SortedLinkedList<T extends Comparable<T>> {
private Node head = null;
private class Node {
private final T value;
private Node next;
private Node(T value, Node next) {
this.value = value;
this.next = next;
}
public void insert(T value) {
assert value.compareTo(this.value) >= 0;
if (next == null || value.compareTo(next.value) <= 0)
next = new Node(value, next);
else
next.insert(value);
}
}
public void add(T value) {
if (head == null || value.compareTo(head.value) <= 0)
head = new Node(value, head);
else
head.insert(value);
}
public Stream<T> stream() {
return Stream.iterate(head, n -> n != null, n -> n.next)
.map(n -> n.value);
}
}
Alternatively, you can use a 'dummy' head node. Arguably not as elegant but does avoid some code repetition. Here's that alternative (with recursion changed to iteration for good measure).
public class SortedLinkedList<T extends Comparable<T>> {
private final Node head = new Node(null, null);
private class Node {
private final T value;
private Node next;
private Node(T value, Node next) {
this.value = value;
this.next = next;
}
}
public void add(T value) {
Node previous = head;
while (previous.next != null && previous.next.value.compareTo(value) < 0)
previous = previous.next;
previous.next = new Node(value, previous.next);
}
public Stream<T> stream() {
return Stream.iterate(head.next, n -> n != null, n -> n.next)
.map(n -> n.value);
}
}
I created a method that is suppose to balance a BinarySearchTree.
The instructions were that the balance method should update the tree so that it is balanced, meaning that the largest difference between subtree heights is no more than 1.
With the following process:
• Get an array of sorted values in the tree (we have a method that can do this)
• Assign the tree's root to the result of the buildTreeUtil helper method (described below)
• Call assignFirst to update the tree's "first" attribute
The buildTreeUtil(E[], int, int, BSTNode parent) helper method rebuilds the tree using a sorted list of values. Since it has this sorted list, it doesn't have to search for where to insert new values, so it doesn't (and shouldn't) call the add method. Instead, it selectively grabs values from the sorted list of values when adding new nodes. It's algorithm is as follows:
• If the "start" parameter is greater than the "end" parameter, the recursion should stop
• Create a new node storing the middle element in the list
• Assign the new node's left reference to a recursive call using the left half of the list
• Assign the new node's right reference to a recursive call using the right half of the list
Here is the following code:
public void balance()
{
this.root = buildTreeUtil(toArray(), 0, size(), first);
assignFirst();
}
private BSTNode<E> buildTreeUtil(E[] values, int start, int end, BSTNode<E> parent)
{
if(start > end)
{
return null;
}
int mid = (start + end)/2;
BSTNode<E> node = new BSTNode<E>(values[mid]);
node.left = buildTreeUtil(values, start, mid - 1, parent.left);
node.right = buildTreeUtil(values, mid + 1, end, parent.right);
return node;
}
private void assignFirst()
{
if (root.left != null)
{
first.left = first;
}
else
{
first = root;
}
}
#SuppressWarnings("unchecked")
public E[] toArray()
{
ArrayList<E> aList = new ArrayList<E>();
E[] arr = (E[]) new Comparable[this.numElements];
toArray(this.root, aList);
return aList.toArray(arr);
}
private void toArray(BSTNode<E> node, List<E> aList)
{
if (node != null)
{
toArray(node.left, aList);
aList.add(node.data);
toArray(node.right, aList);
}
}
This is just the rest of my code cut short so there is some valuable background information.
public class BinarySearchTree<E extends Comparable<E>>
{
private BSTNode<E> root; // root of overall tree
private int numElements;
private BSTNode<E> first;
// post: constructs an empty search tree
public BinarySearchTree()
{
this.root = null;
this.numElements = 0;
}
public class Iterator
{
private BSTNode<E> currentNode;
public Iterator()
{
currentNode = first;
}
public boolean hasNext()
{
return currentNode != null;
}
public E next()
{
E value = currentNode.data;
currentNode = currentNode.next;
return value;
}
}
private static class BSTNode<E>
{
public E data;
public BSTNode<E> left;
public BSTNode<E> right;
public BSTNode<E> parent;
public BSTNode<E> next;
public BSTNode(E data)
{
this(data, null, null, null, null);
}
public BSTNode(E data, BSTNode<E> left, BSTNode<E> right, BSTNode<E> parent, BSTNode<E> next)
{
this.data = data;
this.left = left;
this.right = right;
this.parent = parent;
this.next = next;
}
}
}
I'm not sure where the error occurs or if I'm assigning the incorrect values inside the parameters for buildTreeUtil.
End of a long night and I'm having trouble with copying a linked list recursively, I was able to do so with a simple iterative method, but I am having trouble with a stack overflow error when I try to set it up with recursion. Yet, this makes sense to me conceptually. Can anyone steer me in the right direction? This is what I have so far:
public LinkedList<E> createCopyRecursive(Node<E> aNode) {
LinkedList<E> copyList = new LinkedList<E>();
copyList.myStart = myStart;
if (copyList.size() == 0) {
aNode = myStart.getLink();
}
if (aNode.getLink() == null) {
return copyList;
}
else {
copyList.add(aNode.getValue());
return createCopyRecursive(aNode.getLink());
}
}
You're creating a new LinkedList every time you recurse into the method.
I suspect you want to instantiate it outside the method, pass it in and add to it each time through.
I think it can be as simple as this:
private LinkedList<E> copyRecursive(final Node<E> node, final LinkedList<E> accumulator) {
if (node == null) {
// all nodes traversed, return the result.
return accumulator;
}
// add current node to the copy list that is under construction.
accumulator.add(node.getElement());
// recursive call to copy the rest of the nodes to the copy list and return it when finished.
return copyRecursive(node.getNext(), accumulator);
}
First create an empty new linked list, which will contain the copy and then copy node by node into it recursively. You could also not pass an accumulator to it like this:
private LinkedList<E> copyRecursive(final Node<E> node) {
if (node == null) {
return new LinkedList<>();
}
final LinkedList<E> accumulator = copyRecursive(node.getNext());
accumulator.add(node.getElement());
return accumulator;
}
But that will reverse the order of the nodes in the list.
Here is a fully working example with recursive copy and recursive reverse:
public class RecursiveCopyTest {
public static void main(String[] args) {
final LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("first");
linkedList.add("next");
linkedList.add("last");
System.out.println(linkedList);
System.out.println(linkedList.copyRecursive());
System.out.println(linkedList.reverse());
}
private static class LinkedList<E> {
private Node<E> first;
public LinkedList() {
first = null;
}
public LinkedList<E> copyRecursive() {
return copyRecursive(first, new LinkedList<E>());
}
public LinkedList<E> reverse() {
return reverse(first);
}
public void add(E element) {
final Node<E> node = new Node<>(element);
if (first == null) {
first = node;
} else {
Node<E> current = first;
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(node);
}
}
private LinkedList<E> reverse(final Node<E> node) {
if (node == null) {
return new LinkedList<>();
}
final LinkedList<E> accumulator = reverse(node.getNext());
accumulator.add(node.getElement());
return accumulator;
}
private LinkedList<E> copyRecursive(final Node<E> node, final LinkedList<E> accumulator) {
if (node == null) {
return accumulator;
}
accumulator.add(node.getElement());
return copyRecursive(node.getNext(), accumulator);
}
#Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
Node current = first;
while (current != null) {
stringBuilder.append(current.getElement().toString()).
append(" -> ");
current = current.getNext();
}
stringBuilder.append(" _ ");
return stringBuilder.toString();
}
private static final class Node<E> {
private final E element;
private Node<E> next;
public Node(final E element) {
this.element = element;
}
public E getElement() {
return element;
}
public void setNext(final Node<E> next) {
this.next = next;
}
public Node<E> getNext() {
return next;
}
}
}
}
If you want to use a recursive method to copy your linked list, I think you should first initialize copyList in another mehod that calls createCopyRecursive().
createCopy(Node<E> aNode) {
LinkedList<E> copyList = new LinkedList<E>();
createCopyRecursive(aNode, copyList) {
....
}
}
Rather than passing around whole linkedlist object you can just worry about head node.
Call to recursive method copy()
Node<Integer> copiedHead = copy(head);
Recursive method copy, accepts the head node and returns the copied head node.
private static Node<Integer> copy(Node<Integer> head) {
if(head == null){
return null;
}
return new Node<>(head.getData(), copy(head.getNext()));
}
I am trying to Implement a Linked List Using Java.
The code I have used is as follow
public class LinkNode
{
private int data;
public LinkNode next;
public LinkNode (int data)
{
this.data = data;
}
public void setData(int data)
{
this.data = data;
}
public int getData()
{
return this.data;
}
public void setNext(LinkNode next)
{
this.next = next;
}
public LinkNode getNext()
{
return this.next;
}
public static void main (String [] args)
{
LinkNode Node1 = new LinkNode(3);
LinkNode Head = Node1;
LinkNode Node2 = new LinkNode(4);
LinkNode Node3 = new LinkNode(5);
LinkNode Node4 = new LinkNode(6);
Head.setNext(Node1);
Node1.setNext(Node2);
Node2.setNext(Node3);
Node3.setNext(Node4);
int iCounter =0;
LinkNode currentNode= Head;
while (currentNode.getNext()!=null)
{
int data = currentNode.getData();
System.out.println(data);
currentNode = currentNode.getNext();
iCounter=iCounter+1;
}
System.out.println("No Of Nodes are"+iCounter);
}
}
The Problem here I am getting No of Nodes 3
The code is not counting the last Node that is Node4.
The out put is as follow
3
4
5
No Of Nodes are3
Please let me know what is the problem in the code.
To make Head point to Node1 write
Head = Node1;
If you write Head=null it means that Head doesn't point to any node, and you get a null pointer exception because you then try to get the next node from a node that doesn't exist.
The second problem is that you exit the loop when currentNode.getNext() returns null. The getNext() method returns null when you have reached the last node of the list; if you exit the loop then you won't count the last node. Change the loop condition into:
while (currentNode != null)
And please don't edit the question to ask followup questions. Nobody is notified when a question is edited, so you won't get new answers. It also makes the site less useful for future visitors. Post a new "question" for each question that you have.
Head, should not be null. Instead the data in head should be null, otherwise you have no way to find next.
Here is implementation of Singly Linked List I've developed years ago:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* #author sergiizagriichuk
*/
public class Node<T> {
private T value;
private Node<T> next;
public Node(T value) {
this.value = value;
}
public static <T> Node<T> createLinkedListFromArray(T... array) {
if (checkIfArrayIsNullOrEmpty(array)) return new Node<T>(null);
Node<T> head = new Node<T>(array[0]);
createLinkedList(array, head);
return head;
}
private static <T> boolean checkIfArrayIsNullOrEmpty(T[] array) {
return array == null || array.length == 0;
}
private static <T> void createLinkedList(T[] array, Node<T> head) {
Node<T> node = head;
for (int index = 1; index < array.length; index++) {
T t = array[index];
node.setNext(new Node<T>(t));
node = node.getNext();
}
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return value != null && value.equals(node.value);
}
#Override
public int hashCode() {
return value.hashCode();
}
#Override
public String toString() {
List ret = createList();
return Arrays.toString(ret.toArray());
}
private List createList() {
Node root = this;
List ret = new ArrayList();
while (root != null) {
ret.add(root.getValue());
root = root.getNext();
}
return ret;
}
}
And some Tests:
/**
* #author sergiizagriichuk
*/
public class NodeTest {
#Test
public void testCreateList() throws Exception {
Node<Integer> node = Node.createLinkedListFromArray(1, 2, 3, 4, 5);
Assert.assertEquals(Integer.valueOf(1), node.getValue());
Assert.assertEquals(Integer.valueOf(2), node.getNext().getValue());
}
#Test
public void testCreateListSize() throws Exception {
Integer[] values = new Integer[]{1, 2, 3, 4, 5};
int size = values.length - 1;
Node<Integer> node = Node.createLinkedListFromArray(values);
int count = 0;
while (node.getNext() != null) {
count++;
node = node.getNext();
}
Assert.assertEquals(size, count);
}
#Test
public void testNullNode() throws Exception {
Node<Integer> nullNode = new Node<Integer>(null);
assertNullNode(nullNode);
}
#Test
public void testNullArray() throws Exception {
Node<Integer> nullArrayNode = Node.createLinkedListFromArray();
assertNullNode(nullArrayNode);
}
#Test
public void testSetValue() throws Exception {
Node<Integer> node = new Node<Integer>(null);
assertNullNode(node);
node.setValue(1);
Assert.assertEquals(Integer.valueOf(1), node.getValue());
}
private void assertNullNode(Node<Integer> nullNode) {
Assert.assertNotNull(nullNode);
Assert.assertNull(nullNode.getValue());
}
}
Try to use or redevelop for your situation
I have been diligently watching YouTube videos in an effort to understand linked lists before my fall classes start and I am uncertain how to proceed with iterating over the following linked list. The 'node' class is from a series of videos (same author), but the 'main' method was written by me. Am I approaching the design of a linked list in an illogical fashion (assuming of course one does not wish to use the predefined LinkedList class since the professor will expect each of us to write our own implementation)?:
class Node
{
private String data;
private Node next;
public Node(String data, Node next)
{
this.data = data;
this.next = next;
}
public String getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void setData(String d)
{
data = d;
}
public void setNext(Node n)
{
next = n;
}
public static String getThird(Node list)
{
return list.getNext().getNext().getData();
}
public static void insertSecond(Node list, String s)
{
Node temp = new Node(s, list.getNext());
list.setNext(temp);
}
public static int size(Node list)
{
int count = 0;
while (list != null)
{
count++;
list = list.getNext();
}
return count;
}
}
public class LL2
{
public static void main(String[] args)
{
Node n4 = new Node("Tom", null);
Node n3 = new Node("Caitlin", n4);
Node n2 = new Node("Bob", n3);
Node n1 = new Node("Janet", n2);
}
}
Thanks for the help,
Caitlin
There are some flaws in your linked list as stated by some of the other comments. But you got a good start there that grasps the idea of a linked list and looks functional. To answer your base question of how to loop over this particular implemention of the linked list you do this
Node currentNode = n1; // start at your first node
while(currentNode != null) {
// do logic, for now lets print the value of the node
System.out.println(currentNode.getData());
// proceed to get the next node in the chain and continue on our loop
currentNode = currentNode.getNext();
}
Maybe this will be useful:
static void iterate(Node head) {
Node current = head;
while (current != null) {
System.out.println(current.getData());
current = current.getNext();
}
}
// or through recursion
static void iterateRecursive(Node head) {
if (head != null) {
System.out.println(head.getData());
iterateRecursive(head.getNext());
}
}
class List {
Item head;
class Item {
String value; Item next;
Item ( String s ) { value = s; next = head; head = this; }
}
void print () {
for( Item cursor = head; cursor != null; cursor = cursor.next )
System.out.println ( cursor.value );
}
List () {
Item one = new Item ( "one" );
Item two = new Item ( "three" );
Item three = new Item ( "Two" );
Item four = new Item ( "four" );
}
}
public class HomeWork {
public static void main( String[] none ) { new List().print(); }
}
Good luck!!
You can have your linked list DS class implement 'Iterable' interface and override hasNext(), next() methods or create an inner class to do it for you. Take a look at below implementation:
public class SinglyLinkedList<T>{
private Node<T> head;
public SinglyLinkedList(){
head = null;
}
public void addFirst(T item){
head = new Node<T>(item, head);
}
public void addLast(T item){
if(head == null){
addFirst(item);
}
else{
Node<T> temp = head;
while(temp.next != null){
temp = temp.next;
}
temp.next = new Node<T>(item, null);
}
}
private static class Node<T>{
private T data;
private Node<T> next;
public Node(T data, Node<T> next){
this.data = data;
this.next = next;
}
}
private class LinkedListIterator implements Iterator<T>{
private Node<T> nextNode;
public LinkedListIterator(){
nextNode = head;
}
#Override
public boolean hasNext() {
return (nextNode.next != null);
}
#Override
public T next() {
if(!hasNext()) throw new NoSuchElementException();
T result = nextNode.data;
nextNode = nextNode.next;
return result;
}
}
}