I came across this block of code when I was studying for java CS61b, which used a helper method. As to why we use helper method, the explanation I got is that it makes it easier to do the recursive task. But I have trouble visualizing the alternative options where we don't use a helper method because I have difficulting write the solution. Does that mean using a helper method is the only way? I wish I could compare the two solutions and better understand the usage of a helper method.
here's the code in question:
//Same as get, but uses recursion.
public int getRecursive(int index) {
if (index>size-1) {
return 0;
}
node p = sentinel;
return getRecursiveHelper(p, index);
}
public int getRecursiveHelper(node p, int i) {
if (i==0) {
return p.next.item;
} else {
p = p.next;
i -= 1;
}
return getRecursiveHelper(p, i);
}
the below is the full code:
public class LinkedListDeque {
public node sentinel;
public int size;
public class node {
public node prev;
public int item;
public node next;
public node(node p, int i, node n) {
prev = p;
item = i;
next = n;
}
}
// Creates an empty list
public LinkedListDeque() {
sentinel = new node(null, 63, null);
sentinel.prev = sentinel;
sentinel.next = sentinel;
size = 0;
}
// Adds an item of type T to the front of the deque.
public void addFirst(int x) {
sentinel.next = new node(sentinel, x, sentinel.next);
sentinel.next.next.prev = sentinel.next;
size += 1;
}
// Adds an item of type T to the back of the deque.
public void addLast(int x) {
sentinel.prev = new node(sentinel.prev, x, sentinel);
sentinel.prev.prev.next = sentinel.prev;
size += 1;
}
// Returns true if deque is empty, false otherwise.
public boolean isEmpty() {
if (size == 0) {
return true;
}
return false;
}
// Returns the number of items in the deque.
public int size() {
return size;
}
// Prints the items in the deque from first to last, separated by a space. Once all the items have been printed, print out a new line.
public void printDeque() {
node p = sentinel.next;
for (int i=0; i<size; i++) {
System.out.print(p.item + " ");
p = p.next;
}
System.out.println();
}
// Removes and returns the item at the front of the deque. If no such item exists, returns null.
public int removeFirst() {
if (size==0) {
return 0;
}
int x = sentinel.next.item;
sentinel.next = sentinel.next.next;
sentinel.next.prev = sentinel;
size -= 1;
return x;
}
// Removes and returns the item at the back of the deque. If no such item exists, returns null.
public int removeLast() {
if (size==0) {
return 0;
}
int x = sentinel.prev.item;
sentinel.prev = sentinel.prev.prev;
sentinel.prev.next = sentinel;
size -= 1;
return x;
}
// Gets the item at the given index, where 0 is the front, 1 is the next item, and so forth. If no such item e
public int get(int index) {
if (index>size-1) {
return 0;
}
node p = sentinel.next;
for (int i=0; i<index; i++) {
p = p.next;
}
return p.item;
}
//Same as get, but uses recursion.
public int getRecursive(int index) {
if (index>size-1) {
return 0;
}
node p = sentinel;
return getRecursiveHelper(p, index);
}
public int getRecursiveHelper(node p, int i) {
if (i==0) {
return p.next.item;
} else {
p = p.next;
i -= 1;
}
return getRecursiveHelper(p, i);
}
public static void main(String[] args) {
LinkedListDeque L = new LinkedListDeque();
L.addFirst(2);
L.addFirst(1);
L.addFirst(0);
L.addLast(3);
L.addLast(4);
L.addLast(5);
System.out.println(L.get(7));
}
}
I am trying to sort a linked list with a bubble sort method, but when I try to sort the elements they remain unsorted. When I call my linked method it builds a linked list with parameters n and m which indicate length of the linked list and it represents a set of random integers m-1
Node class
public class iNode{
public int item;
public iNode next;
public iNode(int i, iNode n){
item = i;
next = n;
}
public iNode(int i){
item = i;
next = null;
}
// Node class
public int getItem() {
return this.item;
}
Node List class
public class iNode_List {
public static iNode head;
public static int size;
public iNode_List(){
this.head = null;
this.size = 0;
}
public static iNode linked(int n, int m){ // builds linked list
iNode previous;
iNode current;
int i = 0;
previous = null;
while (i < n) {
current = new iNode(ThreadLocalRandom.current().nextInt(0, m-1), previous);
previous = current;
head = current;
i++;
}
return previous;
}
public static void print() { // prints linked list
iNode currentNode = head;
while(currentNode != null) {
int data = currentNode.getItem();
System.out.println(data);
currentNode = currentNode.next;
}
}
public static void Bubble_Sort (){ // bubble sort method
if (size > 1) {
for (int i = 0; i < size; i++ ) {
iNode currentNode = head;
iNode next = head.next;
for (int j = 0; j < size - 1; j++) {
if (currentNode.item > next.item) {
int temp = currentNode.item;
currentNode.item = next.item;
next.item = temp;
}
currentNode = next;
next = next.next;
}
}
}
}
List class
public class list {
public static void main (String [] args) throws IOException{
iNode_List x = new iNode_List();
int choice;
x.linked(10, 9);
x.print();
System.out.println();
System.out.println("Which method would you like to implement? "); // method --------
Scanner scan = new Scanner (System.in);
choice = scan.nextInt();
switch (choice) {
case 1 : Compare_Loop(x) ;
break ;
case 2 : Bubble_Sort( x) ;
break ;
case 3 : Merge_Sort( x);
break ;
case 4 : Boolean( x);
break ;
}
}
public static void Compare_Loop (iNode_List x){
System.out.println();
x.Compare_Loop();
x.print();
}
public static void Bubble_Sort(iNode_List x){
System.out.println();
x.Bubble_Sort();
x.print();
}
public static void Merge_Sort(iNode_List x){
System.out.println();
x.Merge_Sort(null);
x.print();
}
public static void Boolean (iNode_List x){
System.out.println();
//x.Boolean();
x.print();
}
So I'm trying to construct a method in Java that when called will take as the parameter how many elements at the end of the LinkedList will be reversed.
So, if I have
{hat cat bat mat}
and I input 2 as my parameters, then the last 2 elements will be reversed like this
{hat cat mat bat}
Here is what I have tried:
public void reverseLastFew(int howMany)
{
int s = size();
LinkedListIterator iter1 = new LinkedListIterator();
LinkedListIterator iter2 = new LinkedListIterator();
for (int i=0;i<s-howMany;i++)
{
iter1.next();
}
for (int i = 0;i<s;i++)
{
iter2.next();
}
Object temp = null;
while (iter2.hasNext())
{
temp = iter2.next();
}
iter2.remove();
iter1.add(temp);
}
I have a solution to a similar question:
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given "1"->"2"->"3"->"4"->"5"->NULL, m = 2 and n = 4,
return "1"->"4"->"3"->"2"->"5"->NULL.
Solution:
/**
* Definition for singly-linked list.
* public class ListNode {
* String val;
* ListNode next;
* ListNode(String x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (head==null) {
return null;
}
ListNode dummy = new ListNode(" ");
dummy.next = head;
head = dummy;
for (int i=1; i<m; i++) {
head = head.next;
}
ListNode pre = head;
ListNode start = head.next;
ListNode end = start;
ListNode post = start.next;
for (int i=m; i<n; i++) {
if (post==null) {
return null;
}
ListNode temp = post.next;
post.next = end;
end = post;
post = temp;
}
start.next = post;
pre.next = end;
return dummy.next;
}
}
So, you can calculate m and n with what you have, or modify this solution to solve your question directly. Anyway, this in-place and one-pass solution is really nice.
you can try this code..........
import java.util.LinkedList;
public class LinkListTry {
public LinkedList<String> linkedlist;
public LinkListTry(){
linkedlist = new LinkedList<String>();
}
public void insertElement(String element){
linkedlist.add(element);
}
public void printListElement(){
System.out.println(linkedlist);
}
public void reverseLastFewElement(int howmany){
LinkedList<String> temp = new LinkedList<String>();
while(howmany > 0){
String str = linkedlist.removeLast();
temp.add(str);
--howmany;
}
linkedlist.addAll(temp);
}
}
public class LinkedListTryMain {
public static void main(String[] args){
LinkListTry test = new LinkListTry();
test.insertElement("hat");
test.insertElement("cat");
test.insertElement("bat");
test.insertElement("mat");
test.printListElement();
test.reverseLastFewElement(2);
test.printListElement();
}
}
I'm practicing basic data structure stuff and I'm having some difficulties with recursion. I understand how to do this through iteration but all of my attempts to return the nth node from the last of a linked list via recursion result in null. This is my code so far:
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
else{
findnthToLastRecursion(node.next(), pos);
if(++i == pos) return node;
return null;
}
Can anyone help me understand where I'm going wrong here?
This is my iterative solution which works fine, but I'd really like to know how to translate this into recursion:
public static Link.Node findnthToLast(Link.Node head, int n) {
if (n < 1 || head == null) {
return null;
}
Link.Node pntr1 = head, pntr2 = head;
for (int i = 0; i < n - 1; i++) {
if (pntr2 == null) {
return null;
} else {
pntr2 = pntr2.next();
}
}
while (pntr2.next() != null) {
pntr1 = pntr1.next();
pntr2 = pntr2.next();
}
return pntr1;
}
You need to go to the end and then count your way back, make sure to pass back the node each time its passed back. I like one return point
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
Link.Node result = node;
if(node != null) {
result = findnthToLastRecursion(node.next, pos);
if(i++ == pos){
result = node;
}
}
return result;
}
Working example outputs 7 as 2 away from the 9th and last node:
public class NodeTest {
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
/**
* #param args
*/
public static void main(String[] args) {
Node first = null;
Node prev = null;
for (int i = 0; i < 10; i++) {
Node current = new Node(prev, Integer.toString(i),null);
if(i==0){
first = current;
}
if(prev != null){
prev.next = current;
}
prev = current;
}
System.out.println( findnthToLastRecursion(first,2).item);
}
public static int i = 0;
public static Node findnthToLastRecursion(Node node, int pos) {
Node result = node;
if (node != null) {
result = findnthToLastRecursion(node.next, pos);
if (i++ == pos) {
result = node;
}
}
return result;
}
}
No need for static variables.
public class List {
private Node head = null;
// [...] Other methods
public Node findNthLastRecursive(int nth) {
if (nth <= 0) return null;
return this.findNthLastRecursive(this.head, nth, new int[] {0});
}
private Node findNthLastRecursive(Node p, int nth, int[] pos) {
if (p == null) {
return null;
}
Node n = findNthLastRecursive(p.next, nth, pos);
pos[0]++;
if (pos[0] == nth) {
n = p;
}
return n;
}
}
You can do this a couple of ways:
recurse through the list once to find the list length, then write a recursive method to return the kth element (a much easier problem).
use an auxiliary structure to hold the result plus the remaining length; this essentially replaces the two recursions of the first option with a single recursion:
static class State {
Link.Node result;
int trailingLength;
}
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
State state = new State();
findnthToLastRecursion(node, pos, state);
return state.result;
}
private static void findnthToLastRecursion(Link.Node node, int pos, State state) {
if (node == null) {
state.trailingLength = 0;
} else {
findnthToLastRecursion(node.next(), state);
if (pos == state.trailingLength) {
state.result = node;
}
++state.trailingLength;
}
}
I misunderstood the question. Here is an answer based on your iterative solution:
public static Link.Node findnthToLast(Link.Node head, int n) {
return findnthToLastHelper(head, head, n);
}
private static Link.Node findnthToLastHelper(Link.Node head, Link.Node end, int n) {
if ( end == null ) {
return ( n > 0 ? null : head);
} elseif ( n > 0 ) {
return findnthToLastHelper(head, end.next(), n-1);
} else {
return findnthToLastHelper(head.next(), end.next(), 0);
}
}
actually you don't need to have public static int i = 0; . for utill method the pos is :
pos = linked list length - pos from last + 1
public static Node findnthToLastRecursion(Node node, int pos) {
if(node ==null){ //if null then return null
return null;
}
int length = length(node);//find the length of the liked list
if(length < pos){
return null;
}
else{
return utill(node, length - pos + 1);
}
}
private static int length(Node n){//method which finds the length of the linked list
if(n==null){
return 0;
}
int count = 0;
while(n!=null){
count++;
n=n.next;
}
return count;
}
private static Node utill(Node node, int pos) {
if(node == null) {
return null;
}
if(pos ==1){
return node;
}
else{
return utill(node.next, pos-1);
}
}
Here node.next is the next node. I am directly accessing the next node rather than calling the next() method. Hope it helps.
This cheats (slightly) but it looks good.
public class Test {
List<String> list = new ArrayList<> (Arrays.asList("Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"));
public static String findNthToLastUsingRecursionCheatingALittle(List<String> list, int n) {
int s = list.size();
return s > n
// Go deeper!
? findNthToLastUsingRecursionCheatingALittle(list.subList(1, list.size()), n)
// Found it.
: s == n ? list.get(0)
// Too far.
: null;
}
public void test() {
System.out.println(findNthToLastUsingRecursionCheating(list,3));
}
public static void main(String args[]) {
new Test().test();
}
}
It prints:
Eight
which I suppose is correct.
I have use List instead of some LinkedList variant because I do not want to reinvent anything.
int nthNode(struct Node* head, int n)
{
if (head == NULL)
return 0;
else {
int i;
i = nthNode(head->left, n) + 1;
printf("=%d,%d,%d\n", head->data,i,n);
if (i == n)
printf("%d\n", head->data);
}
}
public class NthElementFromLast {
public static void main(String[] args) {
List<String> list = new LinkedList<>();
Stream.of("A","B","C","D","E").forEach(s -> list.add(s));
System.out.println(list);
System.out.println(getNthElementFromLast(list,2));
}
private static String getNthElementFromLast(List list, int positionFromLast) {
String current = (String) list.get(0);
int index = positionFromLast;
ListIterator<String> listIterator = list.listIterator();
while(positionFromLast>0 && listIterator.hasNext()){
positionFromLast--;
current = listIterator.next();
}
if(positionFromLast != 0) {
return null;
}
String nthFromLast = null;
ListIterator<String> stringListIterator = list.listIterator();
while(listIterator.hasNext()) {
current = listIterator.next();
nthFromLast = stringListIterator.next();
}
return nthFromLast;
}
}
This will find Nth element from last.
My approach is simple and straight,you can change the array size depending upon your requirement:
int pos_from_tail(node *k,int n)
{ static int count=0,a[100];
if(!k) return -1;
else
pos_from_tail(k->next,n);
a[count++]=k->data;
return a[n];
}
You'll have make slight changes in the code:
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
else{
**Link.Node temp = findnthToLastRecursion(node.next(), pos);
if(temp!=null)
return temp;**
if(++i == pos) return node;
return null;
}
}
I got the following assignment - I have a certain java code for a binary search tree and I need to add methods to do the following things with it:
Transform the BST into an array that's sorted by BST data keys.
Create a balanced BST from an ordered integer array.
Use 1. and 2. to balance an existing BST (randomly generated and presumably somewhat unbalanced)
Display the BST before and after balancing.
Please guys, help me if you're smarter than me and know how can that be achieved!
Here is the code that I need to work with:
import java.util.*;
class BtreeNode {
int data;
BtreeNode L,R;
static int depth=0;
public BtreeNode(){
data = 0; L = null; R=null;
}
public BtreeNode(int key){
this();data = key;
}
public String toString() {
return "["+data+"]";
}
public static BtreeNode insOrd(BtreeNode roo, int key){
if(roo==null)return new BtreeNode(key);
//Не се допуска повторение на ключове
if(key==roo.data)return roo;
if(key<roo.data)roo.L=insOrd(roo.L,key);
else roo.R=insOrd(roo.R,key);
return roo;
}
public static BtreeNode generate(int length) {
BtreeNode start = null;
Random rn = new Random();
for(int i = 0; i < length; i++){
start = insOrd(start,rn.nextInt(10000));
}
return start;
}
public static void spc(int n){
for(int i=0;i<n;i++)System.out.print(" ");
}
public static void print(BtreeNode roo){
if(roo!=null){
depth++;
print(roo.R);
spc(depth);System.out.println(roo);
print(roo.L);
depth--;
}
}
public static BtreeNode find(BtreeNode roo, int key){
BtreeNode r=null;
if(roo==null)return r;
if(roo.data==key)r= roo;
if(key>roo.data)r= find(roo.R,key);
if(key<roo.data)r= find(roo.L,key);
return r;
}
};
public class Main {
public static void main(String[] args){
int N;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the number if tree items:");
N=sc.nextInt();
BtreeNode c = BtreeNode.generate(N);
BtreeNode.print(c);
/*
System.out.println("This tree has "+
BtreeNode.weight(c)+" nodes and "+
BtreeNode.height(c)+" levels.");
*/
}
}
UPDATE:
Thank you soooo much guys for your great help, you can't imagine how grateful I am for your advice!!!
I have the whole program working. I am going to post it because somebody might need something like that sometime.
import java.util.*;
class BtreeNode {
int data;
BtreeNode L,R;
static int depth=0;
public BtreeNode(){
data = 0; L = null; R=null;
}
public BtreeNode(int key){
this();data = key;
}
public String toString() {
return "["+data+"]";
}
public static ArrayList<BtreeNode> asList(BtreeNode node) {
ArrayList<BtreeNode> result = new ArrayList<BtreeNode>();
traverse(node, result);
Collections.sort(result, new Comparator<BtreeNode>() {
#Override
public int compare(BtreeNode arg0, BtreeNode arg1) {
if (arg0.data < arg1.data)
return -1;
else if (arg0.data > arg1.data)
return 1;
return 0;
}
});
return result;
}
private static void traverse(BtreeNode node, ArrayList<BtreeNode> result) {
if (node.L != null) {
traverse(node.L, result);
}
result.add(node);
if (node.R != null) {
traverse(node.R, result);
}
}
public static BtreeNode sortedArrayToBST (ArrayList<BtreeNode> result, int start, int end) {
if (start > end) return null;
// same as (start+end)/2, avoids overflow.
int mid = start + (end - start) / 2;
BtreeNode node = new BtreeNode(result.get(mid).data);
node.L = sortedArrayToBST(result, start, mid-1);
node.R = sortedArrayToBST(result, mid+1, end);
return node;
}
public static BtreeNode insOrd(BtreeNode roo, int key){
if(roo==null)return new BtreeNode(key);
if(key==roo.data)return roo;
if(key<roo.data)roo.L=insOrd(roo.L,key);
else roo.R=insOrd(roo.R,key);
return roo;
}
public static BtreeNode generate(int length) {
BtreeNode start = null;
Random rn = new Random();
for(int i = 0; i < length; i++){
start = insOrd(start,rn.nextInt(10000));
}
return start;
}
public static void spc(int n){
for(int i=0;i<n;i++)System.out.print(" ");
}
public static void print(BtreeNode roo){
if(roo!=null){
depth++;
print(roo.R);
System.out.print("Level "+depth);
spc(depth);
System.out.println(roo);
print(roo.L);
depth--;
}
}
public static BtreeNode find(BtreeNode roo, int key){
BtreeNode r=null;
if(roo==null)return r;
if(roo.data==key)r= roo;
if(key>roo.data)r= find(roo.R,key);
if(key<roo.data)r= find(roo.L,key);
return r;
}
};
public class Main {
public static void main(String[] args){
int N;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the number if tree items:");
N=sc.nextInt();
BtreeNode c = BtreeNode.generate(N);
BtreeNode.print(c);
System.out.println("********************");
/*
System.out.println("This tree has "+
BtreeNode.weight(c)+" nodes and "+
BtreeNode.height(c)+" levels.");
*/
ArrayList<BtreeNode> result = BtreeNode.asList(c);
for (BtreeNode btreeNode : result) {
System.out.println(btreeNode.data);
}
// insert in sorted order
c = result.get(0);
for (int i = 1; i < result.size(); i++) {
BtreeNode.insOrd(c, result.get(i).data);
}
BtreeNode.print(c);
System.out.println("********************");
BtreeNode d = BtreeNode.generate(N);
BtreeNode.print(d);
System.out.println("********************");
ArrayList<BtreeNode> result2 = BtreeNode.asList(d);
for (BtreeNode btreeNode : result2) {
System.out.println(btreeNode.data);
}
System.out.println("********************");
BtreeNode.print(BtreeNode.sortedArrayToBST(result2, 0, result2.size()-1));
}
}
Well for the first point you have to have a global array and a traverse method.
Traverse method shoould work something like this:
in main method at the end add this:
ArrayList<BtreeNode> result = BtreeNode.asList(c);
for (BtreeNode btreeNode : result) {
System.out.println(btreeNode.data);
}
// insert in sorted order
c = result.get(0);
for (int i = 1; i < result.size(); i++) {
c.insOrd(c, result.get(i).data);
}
BtreeNode.print(c);
add this methods to BtreeNode class:
public static ArrayList<BtreeNode> asList(BtreeNode node) {
ArrayList<BtreeNode> result = new ArrayList<BtreeNode>();
traverse(node, result);
Collections.sort(result, new Comparator<BtreeNode>() {
#Override
public int compare(BtreeNode arg0, BtreeNode arg1) {
if (arg0.data < arg1.data)
return -1;
else if (arg0.data > arg1.data)
return 1;
return 0;
}
});
return result;
}
private static void traverse(BtreeNode node, ArrayList<BtreeNode> result) {
if (node.L != null) {
traverse(node.L, result);
}
result.add(node);
if (node.R != null) {
traverse(node.R, result);
}
}
1) Creating the sorted array can be done with an "inorder tree walk" - it's fairly easily implementable as a recursive function that you start on the root node. It would look something like this:
void addToListInOrder(List<BtreeNode> l) {
if(L != null) {
L.addToListInOrder(l);
}
list.add(this);
if(R != null) {
R.addToListInOrder(l);
}
}
2) A recursive algorithm would work well here as well: Pick a point in the middle (round up or down if needed) and pick that as the root node. Then subdivide the remaining points in two lists, those before and those after the chosen node, and then call the algorithm recursively on those. Then set the results as the left and right child of the current node. and finally return the node that was chosen. Be sure to handle lists with only a single or a few nodes correctly
3) Do 1 and then 2 on the BST to get a balanced recreation.
4) I've used graphviz for some nice visualizations in the past, but that's probably beyond the scope of your assignment. In it I used an inorder graph walk to create the source file for graphviz
Just check http://www.roseindia.net/java/java-get-example/java-binary-tree-code.shtml
For all of these operation you should use reqursion with end check for current node if it hasn't got more childs.