Title: The List ADT
1The List ADT
- Definition A list is a collection of objects,
called nodes, connected in a chain - by links. There may or may not be an ordering
relationship between data in the - nodes. Depending on this, we distinguish between
ordered and unordered - lists. For now, we consider only unordered
lists. - Operations (methods) on lists
- insertFirst (node) Inserts a new node at the
beginning of the list - deleteFirst (node) Deletes a node from the
beginning of the list - size () Returns the number
of nodes in the list - empty () Returns true if the
list is empty - search (key) Searches for a node with
the specified key - traverse () Processes each node on
the list (for example, - prints it out)
2A linked list interface and the Node class
- public interface LList
- public void insertFirst (int item)
- public Node deleteFirst ()
- public int size()
- public boolean empty ()
- public boolean search (int item)
- public void traverse ()
-
- class Node
- private int data
- private Node next
- public Node ()
- this(0, null)
- public Node (int d, Node n)
- data d
- next n
- public void setData (int newData)
- data newData
- public void setNext (Node newNext)
- next newNext
- public int getData ()
- return data
- public Node getNext ()
- return next
- public void displayNode ()
- System.out.print (data)
3Implementation of an unordered linked list ADT
- public Node deleteFirst ()
- Node temp first
- first first.getNext()
- return temp
- public boolean search (int key)
- boolean result false
- Node current first
- while (current ! null)
- if (current.getData () key)
- result true
- return result
- else
- current current.getNext()
-
- return result
- public void traverse ()
- System.out.print ("Current list ")
- class LinkListADT implements LList
- private Node first
- public LinkListADT ()
- first null
- public boolean empty ()
- return (first null)
-
- public int size ()
- int count 0
- Node current first
- while (current ! null)
- count
- current current.getNext()
-
- return count
-
4Efficiency of linked list operations
- empty, insertFirst and deleteFirst methods are
O(1), while size, search and - traverse methods are O(N). The size method can be
rewritten in a more - efficient, O(1), form, but the (linear) search
and traverse methods do require - a loop to process each of the nodes on the list.
- If we want to insert a node in a place different
than the beginning of the list, - we must first find that place by means of the
search method, and then insert - (or delete) the node. Although the actual insert
/ delete process involves - simply an exchange of two pointers, the overall
efficiency of these method - will be O(N) because of the search involved.
- Ordered linked lists rely on an insertN method to
add the new node in the - appropriate place according to the prescribed
ordering relationship. Therefore, - the insertion in an ordered linked list will also
be O(N) operation (if linear - search is used).
5The Queue ADT -- a linked list implementation
- public interface LLQueue
- public void enqueue (int item)
- public int dequeue()
- public int size()
- public boolean empty()
- public int front()
-
- class LLQueueADT implements LLQueue
- private int size
- private Node front
- private Node rear
- public LLQueueADT ()
- size 0
- front null
- rear null
- public void enqueue (int number)
- Node newNode new Node ()
- newNode.setData(number)
- newNode.setNext(null)
- if (this.empty())
- front newNode
- else
- rear.setNext(newNode)
- rear newNode
- size
-
- public int dequeue ()
- int i
- i front.getData()
- front front.getNext()
- size--
- if (this.empty())
- rear null
6The Stack ADT -- a linked list implementation
- public interface LLStack
- public void push (int item)
- public int pop()
- public int size()
- public boolean empty()
- public int ontop()
-
- class LLStackADT implements LLStack
- private Node top
- private int size
- public LLStackADT ()
- top null
- size 0
-
- public void push (int number)
- Node newNode new Node ()
- newNode.setData(number)
- newNode.setNext(top)
- top newNode
- size
-
- public int pop ()
- int i
- i top.getData()
- top top.getNext()
- size--
- return i
-
- public int ontop ()
- int i pop()
- push(i)
7Double-ended Queues
- The double-ended queue (or dequeu) supports
insertions and deletions at the - front and at the rear of the queue. Therefore, in
addition to enqueue, dequeue - (which we call now insertLast and deleteFirst,
respectively), and first - methods, we must also provide insertFirst,
deleteLast and last methods. - The Dequeue ADT can be used for implementing both
stacks and queues. - Dequeue methods Stack methods
Queue methods - size()
size() size() - empty() empty()
empty() - last()
ontop() -- - first() --
front() - insertFirst() --
-- - insertLast()
push(item) enqueue(item) - deleteLast() pop()
-- - deleteFirst() --
dequeue()
8An implementation of a doubly linked list
- Nodes in a doubly linked list have pointers to
both, the next node and the previous - node. For simplicity, we can add two dummy nodes
to the list the header node, - which comes before the first node, and the
trailer node, which comes after the - last node.
- The doubly linked list ADT has the following
interface - public interface DLList
- public void insertFirst (int item)
- public void insertLast (int item)
- public DLNode deleteFirst ()
- public DLNode deleteLast ()
- public int size()
- public int last ()
- public int first ()
- public boolean empty ()
- public void traverse ()
9Implementation of a doubly linked list (cont.)
- class DLNode
- private int data
- private DLNode next, prev
- public DLNode ()
- this(0, null, null)
-
- public DLNode (int d)
- data d
- next null
- prev null
-
-
- public DLNode (int newData, DLNode newNext,
DLNode newPrev) - data newData
- next newNext
- prev newPrev
- public void setNext (DLNode newNext)
- next newNext
-
- public void setPrev (DLNode newPrev)
- prev newPrev
-
- public int getData ()
- return data
-
- public DLNode getNext ()
- return next
-
- public DLNode getPrev ()
- return prev
-
10Implementation of a doubly linked list (cont.)
- class DLListADT implements DLList
- private DLNode header
- private DLNode trailer
- private int size
- public DLListADT ()
- header new DLNode()
- trailer new DLNode()
- header.setNext(trailer)
- header.setPrev(null)
- header.setData(0)
- trailer.setPrev(header)
- trailer.setNext(null)
- trailer.setData(0)
- size 0
- public boolean empty ()
- return (size 0)
- public void insertFirst (int newData)
- DLNode oldFirst header.getNext()
- DLNode newFirst new DLNode (newData,
oldFirst, header) - oldFirst.setPrev(newFirst)
- header.setNext(newFirst)
- size
- public void insertLast (int newData)
- DLNode oldLast trailer.getPrev()
- DLNode newLast new DLNode (newData,
trailer, oldLast) - oldLast.setNext(newLast)
- trailer.setPrev(newLast)
- size
-
- public DLNode deleteFirst ()
- DLNode oldFirst header.getNext()
- DLNode newFirst oldFirst.getNext()
- newFirst.setPrev(header)
- header.setNext(newFirst)
11Implementation of a doubly linked list (cont.)
- public DLNode deleteLast ()
- DLNode oldLast trailer.getPrev()
- DLNode newLast oldLast.getPrev()
- trailer.setPrev(newLast)
- newLast.setNext(trailer)
- size--
- return oldLast
-
- public boolean search (int key)
- boolean result false
- DLNode current header.getNext()
- while (current ! trailer)
- if (current.getData () key)
- result true
- return result
-
- else
- current current.getNext()
- public int last ()
- return (trailer.getPrev().getData())
-
- public int first ()
- return (header.getNext().getData())
-
-
- public void traverse ()
- System.out.print ("Current list ")
- DLNode current header.getNext()
- while (current ! trailer)
- current.displayDLNode ()
- System.out.print (" ")
- current current.getNext()
-
- System.out.println ()
-
-
12Application of stacks and queues parsing and
evaluation of arithmetic expressions
- Parsing of an expression is a process of checking
its syntax and representing it in - a form which can be uniquely interpreted.
- Example
- Infix forms A B / C D ? (A B) / C
D ? ((A B) / C) D - Postfix form A B C / D
- Prefix form / A B C D
- Postfix and prefix forms are unique expression
can be evaluated by scanning its - postfix form from left to right, or its prefix
form from right to left.
13Algorithm for converting infix expressions into
postfix form
- Data structures needed
- A queue containing the infix expression (call
it infix). - A stack which may contain , -, , /, (,
(call it operator stack). - A queue containing the final postfix expression
(call it postfix). - Methods needed
- InfixPriority, given a non-operand token,
returns an integer associated with its priority
according to the table below. - StackPriority, given a token returns integer
associated with its priority according to the
table below. - Token / -
( ) - Priority 2 2 1 1
3 0 (undefined 0 - Value
for the stack)
14Algorithm for converting infix to postfix
- Initialize operator
stack - by pushing
- Dequeue next
token - from infix
- Token is an
operand? -
Token right parenthesis? - Enqueue the Pop all entries
remaining - operand on on the operator
stack and - postfix queue enqueue them on
postfix Pop entries from operator
Pop operator stack -
stack and
enqueue them and enqueue on -
on postfix
queue until a postfix operators whose -
matching
left parenthesis stack priority is gt -
is popped
infix priority of
the -
token,
except if "("
15 - Example 1 Translate the following infix form to
a postfix form A B (C - D / E) - Infix queue Operator stack
Postfix queue - A
A -
A - B
A B -
A B - ( (
A B - C (
A B C - - - (
A B C - D - (
A B C D
16The algorithm adapted for logical expressions
- Same data structures needed
- The infix queue.
- The operator stack, which now may contain ?, ?,
?, ?, ?, (, . - The postfix queue.
- Methods needed
- InfixPriority, given a non-operand token,
returns an integer associated with its priority
according to the table below. - StackPriority, given a token returns integer
associated with its priority according to the
table below. - Token ? ? ? ? ?
( ) - Priority 1 2 4 3
5 6 0 (undefined 0 - Value
for the stack)
17 - Example 2 Translate the following infix form to
a postfix form (P ? Q) ? (? P ? Q) - Infix queue Operator stack
Postfix queue - (
- P
( P - ? ? (
P - Q ? (
P Q - )
P Q ? - ? ?
P Q ? - ( ( ?
P Q ? - ? ? ( ?
P Q ?
18Evaluation of postfix expressions
- The idea given the postfix expression, get a
token and - If the token is an operand, push its value on the
(value) stack. - If the token is an operator, pop two values from
the stack and apply that operator to them then
push the result back on the stack. - Example 1 A B C D E / -
- Let A 5, B 3, C 6, D 8, E
2. - value
stack - push (5) 5
- push (3) 5 3
- push (pop pop) 15
- push (6) 15 6
- push (8) 15 6 8
- push (2) 15 6 8 2
- push (pop / pop) 15 6 4
- push (pop - pop) 15 2
- push (pop pop) 17
19Evaluation of postfix expressions (contd.)
- Example 2 P Q ? P ? Q ? ?
- Let P true, Q true
-
value stack - push (true) true
- push (true) true
true - push (pop ? pop) true
- push (true) true
true - push (? pop) true false
- push (true) true
false true - push (pop ? pop) true true
- push (pop ? pop) true
- To determine if the expression is a tautology, it
must evaluate to true for all - combinations of truth values of its components,
i.e for P false and Q true - P true and Q false P false and Q false.