INFORMATION & COMPUTER SCIENCE DEPARTMENT, KFUPM
ICS201, SECTIONS 52 (002
Semester)
INTRODUCTION TO COMPUTER SCIENCE
LAB #08 Stacks, Queues & Lists
Instructor: Bashir M. Ghandi
Click
on each of the following links to visualize the various ADT’s in action:
The implementation of Stack ADT using array of characters as discussed in the lectures can be found in the file, StackArray.java. This implementation uses StackOutOfBoundsException class defined in the file StackOutOfBoundsException.java. Open both these files and study them closely to understand them.
Example
1: The following example,
StackArrayTest.java,
makes use of the above class to implement a menu-driven program that allows the
user to test the methods of the stack ADT.
Open it, study it, compile and test-run it.
import
java.io.*; public class StackArrayTest { public static void main(String[] args)
throws IOException { BufferedReader stdin = new
BufferedReader(new InputStreamReader(System.in)); StackArray s = new StackArray(10); while (true) {
System.out.println("\n1\tPush\n2\tPop\n3\tPeek\n4\tDisplay\n5\tQuit"); System.out.print("Enter your
choice: ");
char choice = stdin.readLine().charAt(0); try {
switch (choice) { case '1':
System.out.print("Enter Character Element: "); char ele = stdin.readLine().charAt(0); s.push(ele); break; case '2':
System.out.println("popped: "+s.peek()); s.pop(); break; case '3':
System.out.println("top element is: "+s.peek()); break; case '4': s.print(); System.out.println();
break; case '5': return; default:
System.out.println("invalid command..");
} // end switch
} //end try catch(StackOutOfBoundsException e) { System.out.println(e); } // end catach
} } } |
The implementation of Queue ADT using array of characters as discussed in the lectures can be found in the file, QueueArray.java. This implementation does not handle exceptions. Thus, the user must check for possible errors when using this class.
Example
2: The following example, QueueArrayTest.java,
makes use of the above class to implement a menu-driven program that allows the
user to test the methods of the Queue ADT. Open it, study it, compile and test-run it.
import
java.io.*; public class QueueArrayTest { public static void main(String[] arg)
throws IOException { BufferedReader stdin = new
BufferedReader(new InputStreamReader(System.in)); QueueArray q = new QueueArray(10); while (true) { System.out.println("1\tEnqueue\n2\tDequeue\n3\tFront\n4\tDisplay\n5\tSize\n6\tQuit");
System.out.print("Enter your choice: ");
char choice = stdin.readLine().charAt(0); switch (choice) { case '1':
System.out.print("Enter Character Element: "); char ele = stdin.readLine().charAt(0); if (!q.isFull()) q.enqueue(ele); else System.out.println("Sorry, Queue is Full"); break; case '2': if (!q.isEmpty()) { System.out.println("Dequed: "+q.front()); q.dequeue(); } else System.out.println("Sorry, Queue
is Empty"); break; case '3': if (!q.isEmpty()) System.out.println("front element is:
"+q.front()); else System.out.println("Sorry,
Queue is Empty"); break; case '4': q.print(); break; case '5':
System.out.println("Queue size="+q.size()); break; case '6': return; default:
System.out.println("invalid command.."); } } } } |
Notes:
Comparing
Example 1 and Example 2 we can observe two major advantages of using Exception
handling provided by Java.
1.
Security: Because
StackOutOfBoundsException is derived from Exception which is a checked
exception, the compiler will not allow any applications that makes use of any
of the methods push(), pop() and peek() to compile unless
there is some specification on what to do if StackOutOfBoundsException occurs. Thus, using exceptions as in Example 1 forces
the programmer to write a more secure programs.
2.
Shorter Code: Using exception handling, we can use one try-catch statement to handle
multiple calls of the methods that throw exceptions as seen in Example 1: In example 2 we had to use an if
statement for each call to any of the methods that throw exceptions.
The
file LinkedList.java implements the dynamic List ADT as discussed in the lectures. It makes use of the files: Node.java and
LinkedListIterator.java.
Open each of these files and study them closely. Notice the use of the standard Exception class
IndexOutOfBoudsException.
Example
3: The following example, LinkedListTest.java,
shows how LinkedList may be used.
import
java.io.*; public
class LinkedListTest { private BufferedReader stdin; private LinkedList list; public LinkedListTest() throws IOException
{ stdin
= new BufferedReader(new InputStreamReader(System.in)); list = new LinkedList(); while (true) { System.out.println("1\tAdd\n2\tChange\n3\tDelete\n4\tFind
Element\n5\tGet Element At\n6\tPrint\n7\tReset\n8\tQuit"); System.out.print("Enter your
Choice: "); int choice =
Integer.parseInt(stdin.readLine()); switch (choice) { case 1: add(); break; case 2: change(); break; case 3: delete(); break; case 4: findObject(); break; case 5: get(); break; case 6: list.print(); break; case 7: list.clear(); System.out.println("list cleared"); break; case 8: return; default:
System.out.println("invalid command.."); } } } private void add() throws IOException { try { System.out.print("Add at
Position : "); int pos =
Integer.parseInt(stdin.readLine()); System.out.print("Enter Integer
Element: "); int ele =
Integer.parseInt(stdin.readLine()); list.insert(pos,new Integer(ele)); } catch (IndexOutOfBoundsException e) { System.out.println(e); } } private void change() throws IOException { try { System.out.print("Change at
Position : "); int pos =
Integer.parseInt(stdin.readLine()); System.out.print("New Element:
"); int ele =
Integer.parseInt(stdin.readLine()); list.update(pos,new Integer(ele)); } catch (IndexOutOfBoundsException e) { System.out.println(e); } } private void delete() throws IOException { try { System.out.print("Delete At
Position : "); int pos =
Integer.parseInt(stdin.readLine()); list.remove(pos); } catch (IndexOutOfBoundsException e) { System.out.println(e); } } private void get() throws IOException { try { System.out.print("Get at
Position : "); int pos =
Integer.parseInt(stdin.readLine()); System.out.println(list.retrieve(pos)); } catch (IndexOutOfBoundsException e) { System.out.println(e); } } private void findObject() throws
IOException { System.out.print("Find element :
"); int e =
Integer.parseInt(stdin.readLine()); LinkedListIterator iterator = find(new
Integer(e),new LinkedListIterator(list)); if (iterator.isPastEnd()) System.out.println(e+" not
found");
else System.out.println(iterator.retrieve()+" found"); } LinkedListIterator find(Object e,
LinkedListIterator iterator) { if (iterator.isPastEnd() ||
e.equals(iterator.retrieve()))
return iterator; else { iterator.next(); return find(e, iterator); } }
public static void main(String[] arg)
throws IOException { new LinkedListTest(); } } |
The
file StackList.java in the following example shows how Stack ADT can be implemented
using LinkedList. Notice that in this
case, there is no need to have the isFull() method.
Example
4:
public
class StackList { private LinkedList list; public StackList() {
list = new LinkedList(); } public boolean isEmpty() { return list.isEmpty(); } public void push(Object e) { list.insert(0,e);
} public Object peek(){ if
(isEmpty()) throw new
StackOutOfBoundsException("Sorry!
Stack is Empty"); else return list.retrieve(0); } public void pop() { if (isEmpty()) throw new
StackOutOfBoundsException("Opps!
Stack is Empty"); else
list.remove(0); } public String toString() { return list.toString(); } public void print() { System.out.println(this); } } |
Example
5: The following example, StackListTest.java, modifies
example 1 to use StackList.
import
java.io.*; public class StackListTest { public static void main(String[] args)
throws IOException { BufferedReader stdin = new
BufferedReader(new InputStreamReader(System.in)); StackList s = new StackList(); while (true) {
System.out.println("\n1\tPush\n2\tPop\n3\tPeek\n4\tDisplay\n5\tQuit");
System.out.print("Enter your choice: ");
char choice = stdin.readLine().charAt(0);
try {
switch (choice) { case '1':
System.out.print("Enter Character Element: "); String ele = stdin.readLine(); s.push(ele); break; case '2':
System.out.println("popped: "+s.peek()); s.pop(); break; case '3':
System.out.println("top element is: "+s.peek()); break; case '4': s.print(); System.out.println();
break; case '5': return; default:
System.out.println("invalid command..");
} // end switch
} //end try
catch(StackOutOfBoundsException e) {
System.out.println(e);
} // end catach } } } |
1.
(a) Write a class, QueueOutOfBoundsException,
similar to StackOutOfBoundsException and use it to modify the Array
implementation of Queue ADT so that the methods, enqueue(), dequeue()
and front() thow this exception.
(b)
Modify Example 2, QueueArrayTest.java, so
that it handle QueueOutOfBoundsException instead of using if statements.
2.
Complete
the Program in the File, StackBracketTest.java, so that is checks whether the
brackets, {}, [], and (), in a given string match or not.
3.
(a) Write a class, QueueList that uses LinkedList
to implement the Queue ADT. You must
use QueueOutOfBoundsException where appropriate.
(b)
Write
an application, QueueListTest, similar to StackListTest to test your
implementation.
Provide
an implementation of a FirstLastLinkedList. This is an extended version
of a LinkedList class which not only maintains a reference to the
first node in the list, but also a reference to the last node in the list. This
can help the performance of inserting new nodes at the end of the list.
Use the existing LinkedList.java
class and modify to provide a reference to the last list node and also amend
any methods as necessary.