You are on page 1of 10

Problem: Suppose that a linked list is Iormed Irom objects that belong to the class

class Node
,
String name; // A String item in the list.
Node link; // Pointer to next item in the list.
,
Write a method that will search Ior a name entered by the user in a Linked List.
















































Problem 1: Suppose that a linked list is Iormed Irom objects that belong to the class
class Node
,
int data; // An item in the list.
Node link; // Pointer to next item in the list.
,

Write a method that will merge two linked lists sorted in ascending order into a third list using
Merge Sort.

Solution:

void MergeSort(List L1,List L2)

Node p1L1.start,p2L2.start;
int m0;
while(p1!null && p2!null)

iI(p1.getdata()p2.getdata())

mp1.getdata();
p1p1.getlink();
}
else

mp2.getdata();
p2p2.getlink();
}
this.InsertatEnd(m);
}
while(p1!null) // storing remaining elements oI List L1

this.InsertatEnd(p1.getdata());
p1p1.getlink();
}
while(p2!null) // storing remaining elements oI List L2

this.InsertatEnd(p2.getdata());
p2p2.getlink();
}
}
public static void helpermergesort()

System.out.println("\I");
List L1new List ();
Ior(int i1;i10;i2)
L1.InsertatEnd(i);
System.out.println("\nFirst List: ");
L1.display();
List L2new List();
Ior(int i2;i16;i2)
L2.InsertatEnd(i);
System.out.println("\n\nSecond List: ");
L2.display();
List L3new List();
L3.MergeSort(L1,L2);
System.out.println("\n\nMerged List: ");
L3.display();
}

Problem 2: Suppose that a linked list is Iormed Irom objects that belong to the class
class ListNode
,
int item; // An item in the list.
ListNode next; // Pointer to next item in the list.
,

Write a method that will append a Linked List to the end oI another Linked List.

Solution:
void append(List L2)

Node p1this.start;
while(p1.getlink()!null)
p1p1.getlink();
p1.setlink(L2.start);
}
static void helperappend()

System.out.println("\I");
List L1new List();
Ior(int i1;i10;i2)
L1.InsertatEnd(i);
System.out.println("\nFirst List: ");
L1.display();
List L2new List();
Ior(int i2;i16;i2)
L2.InsertatEnd(i);
System.out.println("\n\nSecond List: ");
L2.display();
L1.append(L2);
System.out.println("\n\nAppended List: ");
L1.display();
}








Problem 3: Suppose that a linked list is Iormed Irom objects that belong to the class
class ListNode ,
int item; // An item in the list.
ListNode next; // Pointer to next item in the list.
,
Write a subroutine that will Iind the sum oI all the ints in a linked list. The subroutine should
have a parameter oI type ListNode and should return a value oI type int.

Answer: I'll give both a non-recursive solution and a recursive solution. For a linked list, the
recursion is not really necessary, but it does nicely reIlect the recursive deIinition oI ListNode
static int listSum( ListNode head ) ,
int total; // The sum of all the items.
ListNode runner; // For running along the list.
total = 0;
runner = head; // Start at the beginning of the list.
while (runner != null) ,
total += runner.item; // Add in the item in this node.
runner = runner.next; // Advance to the next node.
,
return total;
,

static int recursiveListSum( ListNode head ) ,
if ( head == null) ,
// The sum of the items in an empty list is zero.
return 0;
,
else ,
// Add the item in the head to the sum of the other items.
return head.item + recursiveListSum(head.next);
,
,

What are the three operations on a stack?
Answer: The three stack operations are 5:sh, 545, and isEm5ty. The deIinitions oI these
operations are: push(item) adds the speciIied item to the top oI the stack; pop() removes the
top item oI the stack and returns it; and isEmpty() is a boolean-valued Iunction that returns true
iI there are no items on the stack.

":estion 5: What is the basic diIIerence between a stack and a queue?
Answer: In a stack, items are added to the stack and removed Irom the stack on the same end
(called the "top" oI the stack). In a queue, items are added at one end (the "back") and removed
at the other end (the "Iront"). Because oI this diIIerence, a queue is a FIFO structure (items are
removed in the same order in which they were added), and a stack is a LIFO structure (the item
that is popped Irom a stack is the one that was added most recently).








Suppose that a binary tree is Iormed Irom objects belonging to the class
class TreeNode ,
int item; // Jne item in the tree.
TreeNode left; // Pointer to the left subtree.
TreeNode right; // Pointer to the right subtree.
,
Write a recursive subroutine that will Iind the sum oI all the nodes in the tree. Your subroutine
should have a parameter oI type TreeNode, and it should return a value oI type int.
Answer:
static int treeSum( TreeNode root ) ,
// Find the sum of all the nodes in the
// tree to which root points.
if ( root == null ) ,
// The sum of the nodes in an empty tree is zero.
return 0;
else ,
// Add the item in the root to the sum of the
// items in the left subtree and the sum of the
// items in the right subtree.
int total = root.item;
total += treeSum( root.left );
total += treeSum( root.right );
return total;
,
,

What is a 54st47/07 t7av07sal oI a binary tree?
Answer: In a traversal oI a binary tree, all the nodes are processed in some way. (For example,
they might be printed.) In a postorder traversal, the order oI processing is deIined by the rule: For
each node, the nodes in the leIt subtree oI that node are processed Iirst. Then the nodes in the
right subtree are processed. Finally, the node itselI is processed.
Suppose that linked lists oI integers are made Irom objects belonging to the class
class ListNode ,
int item; // An item in the list.
ListNode next; // Pointer to the next node in the list.
,
Write a subroutine that will make a copy oI a list, with the order oI the items oI the list reversed.
The subroutine should have a parameter oI type ListNode, and it should return a value oI type
ListNode. The original list should not be modiIied.
You should also write a main() routine to test your subroutine.

isc:ssion

To make any linked list Irom scratch, you have to create nodes one-by-one and link them
together. In this case, we want to make nodes that contain copies oI the items Irom the original
list. We can run through the original list, look at each item, create a new node that contains a
copy oI that item, and link that new node into the reversed list that we are constructing. We just
have to make sure that the nodes in the new list are in the desired order.
In Iact this is pretty easy: As we run down the original list Irom start to Iinish, we need to build
the reversed list Irom back to Iront. The Iirst item in the original list should be at the back oI the
reversed list, the second item Irom the original goes in Iront oI that item, and so on. This is
equivalent to "pushing" the items onto the reversed list, using the same push operation that is
used Ior a stack. An algorithm Ior this is:
Let rev be an empty list
for each item in the original list:
Push the item onto rev
Move on to the next item
This can be coded into the subroutine we need as Iollows:
static ListNode reverse( ListNode list ) ,
// Return a new list containing the same items as the list,
// but in the reverse order.
ListNode rev = null; // rev will be the reversed list.
ListNode runner = list; // For running through the nodes of list.
while (runner != null) ,
// "Push" the next node of list onto the front of rev.
ListNode newNode = new ListNode();
newNode.item = runner.item;
newNode.next = rev;
rev = newNode;
// Move on to the next node in the list.
runner = runner.next;
,
return rev;
, // end reverse()

The exercise lets you design your own routine Ior testing the subroutine. It should be tested on
several lists, including an empty list. It's important to test it on the empty list since a null pointer
oIten represents a special case in an algorithm, and thereIor a common source oI bugs. It's also a
good idea to test a list oI length one, Ior similar reasons. In my main() routine, I build up a
random list one node at a time and test the reverse() subroutine on the list at each step. The
main() routine was probably harder to write than the subroutine!

%e Sol:tion

// This program includes a subroutine that makes a reversed copy of a
// list of ints. The main program simply tests that routine on a few
lists.

public class ReverseListDemo ,


static class ListNode ,
// Jbjects of type ListNode are linked together into linked
lists.
int item; // An item in the list.
ListNode next; // Pointer to the next node in the list.
,


static ListNode reverse( ListNode list ) ,
// Return a new list containing the same items as the list,
// but in the reverse order.
ListNode rev = null; // rev will be the reversed list.
ListNode runner = list; // For running through the nodes of list.
while (runner != null) ,
// "Push" the next node of list onto the front of rev.
ListNode newNode = new ListNode();
newNode.item = runner.item;
newNode.next = rev;
rev = newNode;
// Move on to the next node in the list.
runner = runner.next;
,
return rev;
, // end reverse()


static void printList(ListNode start) ,
// Prints the items in the list to which start points.
// They are printed on one line, separated by spaces.
ListNode runner; // For running along the list.
runner = start;
while (runner != null) ,
System.out.print(" " + runner.item);
runner = runner.next;
,
, // end printList()


static void main(String, args) ,

System.out.println("I will print out a list and its reverse, for");
System.out.println("several different lists. The first list is
empty.\n");

ListNode list = null; // A list, initially empty.
ListNode reversedList; // The reversed list.

int ct = 0; // How many lists have we processed.

while (true) ,
// Print the current list and its reverse. Then
// add a new node onto the head of the list before
// repeating.
System.out.print("The list: ");
printList(list);
System.out.println();
reversedList = reverse(list);
System.out.print("The reversed list: ");
printList(reversedList);
System.out.println();
System.out.println();
ct++;
if (ct == 6)
break;
ListNode head = new ListNode(); // A new node to add to the
list.
head.item = (int)(Math.random()100); // A random item.
head.next = list;
list = head;
,

, // end main()


, // end class ReverseListDemo
Explain what is meant by a 70c:7siv0 subroutine.
":estion 2: Consider the Iollowing subroutine:
static void printStuff(int level) ,
if (level == 0) ,
System.out.print("");
,
else ,
System.out.print("");
printStuff(level - 1);
System.out.print(",");
printStuff(level - 1);
System.out.println(",");
,
,
Show the output that would be produced by the subroutine calls printStuff(0),
printStuff(1), printStuff(2), and printStuff(3).

Next, we turn to a problem that is easy to solve with recursion but diIIicult to solve without it.
This is a standard example known as "The Towers oI Hanoi". The problem involves a stack oI
various-sized disks, piled up on a base in order oI decreasing size. The object is to move the
stack Irom one base to another, subject to two rules: Only one disk can be moved at a time, and
no disk can ever be placed on top oI a smaller disk. There is a third base that can be used as a
"spare". The situation Ior a stack oI ten disks is shown in the top halI oI the Iollowing picture.
The situation aIter a number oI moves have been made is shown in the bottom halI oI the picture.
These pictures are Irom the applet at the end oI Section 10.5, which displays an animation oI the
step-by-step solution oI the problem.

The problem is to move ten disks Irom Stack 0 to Stack 1, subject to certain rules. Stack 2 can be
used a spare location. Can we reduce this to smaller problems oI the same type, possibly
generalizing the problem a bit to make this possible? It seems natural to consider the size oI the
problem to be the number oI disks to be moved. II there are N disks in Stack 0, we know that we
will eventually have to move the bottom disk Irom Stack 0 to Stack 1. But beIore we can do that,
according to the rules, the Iirst N-1 disks must be on Stack 2. Once we've moved the N-th disk to
Stack 1, we must move the other N-1 disks Irom Stack 2 to Stack 1 to complete the solution. But
moving N-1 disks is the same type oI problem as moving N disks, except that it's a smaller
version oI the problem. This is exactly what we need to do recursion! The problem has to be
generalized a bit, because the smaller problems involve moving disks Irom Stack 0 to Stack 2 or
Irom Stack 2 to Stack 1, instead oI Irom Stack 0 to Stack 1. In the recursive subroutine that
solves the problem, the stacks that serve as the source and destination oI the disks have to be
speciIied. It's also convenient to speciIy the stack that is to be used as a spare, even though we
could Iigure that out Irom the other two parameters. The base case is when there is only one disk
to be moved. The solution in this case is trivial: Just move the disk in one step. Here is a version
oI the subroutine that will print out step-by-step instructions Ior solving the problem:



void TowersJfHanoi(int disks, int from, int to, int spare) ,
// Solve the problem of moving the number of disks specified
// by the first parameter from the stack specified by the
// second parameter to the stack specified by the third
// parameter. The stack specified by the fourth parameter
// is available for use as a spare.
if (disks == 1) ,
// There is only one disk to be moved. Just move it.
System.out.println("Move a disk from stack number "
+ from + " to stack number " + to);
,
else ,
// Move all but one disk to the spare stack, then
// move the bottom disk, then put all the other
// disks on top of it.
TowersJfHanoi(disks-1, from, spare, to);
System.out.println("Move a disk from stack number "
+ from + " to stack number " + to);
TowersJfHanoi(disks-1, spare, to, from);
,
,
This subroutine just expresses the natural recursive solution. The recursion works because each
recursive call involves a smaller number oI disks, and the problem is trivial to solve in the base
case, when there is only one disk. To solve the "top level" problem oI moving N disks Irom Stack
0 to Stack 1, it should be called with the command TowersJfHanoi(N,0,1,2). Here is an applet
that uses this subroutine. You can speciIy the number oI disks. Be careIul. The number oI steps
increases rapidly with the number oI disks.
What this applet shows you is a mass oI detail that you don't really want to think about! The
diIIiculty oI Iollowing the details contrasts sharply with the simplicity and elegance oI the
recursive solution. OI course, you really want to leave the details to the computer. It's much more
interesting to watch the applet Irom Section 10.5, which shows the solution graphically. That
applet uses the same recursive subroutine, except that the System.out.println statements are
replaced by commands that show the image oI the disk being moved Irom one stack to another.
You can Iind the complete source code in the Iile TowersOIHanoi.java.
There is, by the way, a story that explains the name oI this problem. According to this story, on
the Iirst day oI creation, a group oI monks in an isolated tower near Hanoi were given a stack oI
64 disks and were assigned the task oI moving one disk every day, according to the rules oI the
Towers oI Hanoi problem. On the day that they complete their task oI moving all the disks Irom
one stack to another, the universe will come to an end. But don't worry. The number oI steps
required to solve the problem Ior N disks is 2
N
- 1, and 2
64
- 1 days is over 50,000,000,000,000
years. We have a long way to go.

You might also like