data structures and algorithm design (review). java basics object-oriented design stacks, queues,...
Post on 18-Dec-2015
219 views
TRANSCRIPT
Data Structures andAlgorithm Design
(Review)
Java basicsJava basics
Object-oriented design
Object-oriented design
Stacks, queues, and deques
Stacks, queues, and deques
Vectors, lists and sequences
Vectors, lists and sequences
Trees and binary trees
Trees and binary trees
Data Structures and Algorithm Design:
Tree traversal
Tree traversal
Merge sorting
Merge sorting
Quick sorting
Quick sorting
Set operations
Set operations
Graphs
Graphs
Java BasicsClass
Class Modifiersabstract, final, public
Variable Modifierspublic, protected, private, static, final
MethodsMethod Modifiers
public, protected, private, abstract, final, staticArrays
int[] a = new int[ 10 ];float[][] x = new float[ 8 ][ 10 ];a[ i ] = 138;x[ i ][ i + 1 ] = 2.189 + x[ i ][ i ];
Object-Oriented Design
InheritancePolymorphism
method overridingmethod overloading
Keyword: thisExceptionInterface, Abstract ClassesType casting
Stacks, Queues, and Deques
StacksQueuesDequesSingly linked listsDoubly linked listsSample case study application
Stacks
Definition: A stack is a container of objects that are inserted andremoved according to the last-in first-out (LIFO) principle.
A stack S is an abstract data type (ADT) that supports following two fundamental methods: push(o): Insert object o at the top of the stack
Input: Object; Output: None. pop(): Remove from the stack and return the top object on
the stack; an error occurs if the stack is empty. Input: None; Output: Object
public interface Stack {public void push( Object element );public Object pop()
throws StackEmptyException;public int size();public boolean isEmpty();public Object top()
throws StackEmptyException;}
public class ArrayStack implements Stack {public static final int CAPACITY = 1000;private in capacity;private Object [] S;private int top = -1;
public ArrayStatck() {
this( CAPACITY );}public ArrayStack( int cap ) {
capacity = cap;S = new Object[ capacity ];
}
public int size() {return ( top + 1 );
}
public boolean isEmpty() {return( top < 0 );
}public void push( Object obj )
throws StackFullException{
if( size() == capacity )throw new StackFullException( "Stack overflow" );S[ ++top ] = obj;
} public Object top() throws StackEmptyException {
if( isEmpty() )throw new StackEmptyException( "Stack is empty." );return S[ top ];
}
public Object pop() throws StackEmptyException {Object elem;
if( isEmpty() )throw new StackEmptyException( "Stack is Empty." );elem = S[ top ];S[ top-- ] = null;return elem;}
}
public class NodeStack implements Stack { protected Node top; // reference to the head node protected int size; // number of elements in the stack public NodeStack() { // constructs an empty stack top = null; size = 0; } public int size() { return size; } public boolean isEmpty() { if (top == null) return true; return false; } public void push(Object elem) { Node v = new Node(elem, top);// create and link-in a top = v; //new node size++; }
public Object top() throws EmptyStackException { if (isEmpty()) throw new EmptyStackException("Stack is empty."); return top.getElement(); } public Object pop() throws EmptyStackException { if (isEmpty()) throw new EmptyStackException("Stack is empty."); Object temp = top.getElement(); top = top.getNext(); // link-out the former top node size--; return temp; }}
Sample Case Study Application
(1) We want to write a program to calculate the span of the stock’sprice on a given day.
The span of the stock’s price on a given day: The maximumnumber of the consecutive days up to the current day such that thestock price on each of those days has been less than or equal tothe price on the current day.
Java Implementation
public void computeDailyHighSpan( Quote Q[]) { int prevHigh; Stack D = new ArrayStack(); for( int i = 0; i < Q.length; i++ ) { while( !D.isEmpty() && Q[ i ].getPrice() >= (( Quote )D.top()).getPrice() ) D.pop(); if( D.isEmpty() ) prevHigh = -1; else prevHigh = (( Quote )D.top()).getDay(); Q[ i ].setSpan( i - prevHigh ); D.push( Q[ i ]); } }
public class Quote { private int day, price, span; public Quote( int d, int p ) { setDay( d ); setPrice( p ); } public void setDay( int d ) { day = d; } public int getDay() { return day; } public void setPrice( int p ) { price = p; } public int getPrice() { return price; } public void setSpan( int s ) { span = s; } public int getSpan() { return span; } }
Main idea:The span si on a certain day i can be easily computedif we know the closest day preceding day i, such that the priceon that day is higher than the price on day i.If such a preceding day exists for a day i, let us denote it with h(i), and otherwise let us define h(i) = -1. Then, si = i – h(i).
Example: p0 p1 p2 p3 p4 p5 p6 48.97 47.54 45.83 46.34 45.68 46.95 48.17
h(0)
-1
h(1)
0
h(2)
1
h(3)
1
h(4)
3
h(5)
1
h(6)
0
si = i – h(i).
s0
1
s1
1
s2
1
s3
2
s4
1
s5
4
s6
6
The problem is how to compute h(i) efficiently?
Step 1:p0 = 48.97. h(0) = -1, s0 = 0 - h(0) = 0 – (-1) = 1
0 Day 0. It is possible that h(1) = 0.
Step 2:p1 = 47.54. Pop days with prices less than or equal to p1.At this point of time, we have only one element in the stack.It is 0 and p0 > p1. So h(1) = 0, s1 = 1 - h(1) = 1 – 0 = 1.
Day 1. It is possible that h(2) = 1.01
Step 3:p2 = 45.83. Pop days with prices less than or equal to p2.At this point of time, we have two elements in the stack.The top one is 1 and p1 > p2. So h(2) = 1, s2 = 2 - h(2) = 2 – 1 = 1.
Day 2. It is possible that h(3) = 2.12
0
Step 4:p3 = 46.34. Pop days with prices less than or equal to p3.The top one will be taken out since p3 > p2. The second one is 1 and p1 > p3. So h(3) = 1, s3 = 3 - h(3) = 3 – 1 = 2.
Day 3. It is possible that h(4) = 3.
013
Step 5:p4 = 45.68. Pop days with prices less than or equal to p4.The top one is 3 and p3 > p4. So h(4) = 3, s4 = 4 - h(3) = 4 – 3 = 1.
Day 4. It is possible that h(5) = 4.
0134
Step 6:p5 = 46.95. Pop days with prices less than or equal to p3.The top two will be taken out since p5 > p4 and p5 > p3. The third one is 1 and p1 > p5. So h(5) = 1, s5 = 5 - h(5) = 5 – 1 = 4.
Day 5. It is possible that h(6) = 5.
015
Step 7:p6 = 48.17. Pop days with prices less than or equal to p3.The top two will be taken out since p6 > p5 and p6 > p1. The third one is 0 and p0 > p6. So h(6) = 0, s5 = 6 - h(6) = 6 – 0 = 6.
Day 6. The price on day 6. The process stops.06
(2) Calculate the following expression using ArrayStack to controlthe computation:
“1+2+3-4-5+6-7+8-9”.
public class Expression-computation{ //start class public static void main( String args[] ) //start main body {String s = "1+2+3-4-5+6-7+8-9";
Stack data = new ArrayStack(); int temp; char operator;
int a = 0; data.push (new Integer (1));
for (int x = 1; x < s.length(); x++) { if (s.charAt(x) == '+‘ || s.charAt(x) == ‘-’)
data.push(new Character(s.charAt(x))); else { //else it is a number
operator = (Character) data.pop();a = ((Integer)data.pop()).intValue();if (operator == ‘+’) temp = a + charAt(x);
else temp = a – charAt(x); data.push(new Integer(temp)); }
System.out.println("The answer is: " + ((Integer) data.pop()).intValue());
} // end method main}// end class
QueuesDefinition: A queue is a container of objects that are inserted andremoved according to the first-in first-out (FIFO) principle.
A queue Q is an abstract data type that supports the following two fundamental methods: enqueue(o): Insert object o at the rear of the queue
Input: Object; Output: None. dequeue(): Remove and return from the queue the object at the
front; an error occurs if the queue is empty. Input: None; Output: Object
public interface Queue { public void enqueue( Object element ); public Object dequeue() throws QueueEmptyException; public int size(); public boolean isEmpty(); public Object front() throws QueueEmptyException; } When we define an interface, we just indicate that a class which implements it should provide all the methods specified in it.
class ArrayQueue implements Queue{
private Object[] elem;private int front, rear;private static final int DEFAULT_LENGTH = 100;private int length;public ArrayQueue(){
this(DEFAULT_LENGTH);}public ArrayQueue(int length){
elem = new Object[length];front = rear = 0;length = elem.length;
}
public void enqueue(Object element)throws QueueFullException
{if (size()==length-1)
throw new QueueFullException();else{
elem[rear] = element;rear = (rear+1)%length;
}}
public Object dequeue() throws QueueEmptyException{ if (isEmpty())
throw new QueueEmptyException();else{ Object temp = elem[front];
elem[front] = null;front = (front+1)%length;return temp;
}}private boolean isFull(){
return (rear-front)==(length-1);}
public int size(){
return (length-front+rear)%length;}public boolean isEmpty(){
return front==rear;}public Object front() throws QueueEmptyException{
if (isEmpty())throw new QueueEmptyException();
elsereturn elem[front];
}}
public class ListQueue implements Queue { protected Node front, rear; //reference to the front and rear node protected int size; // number of elements in the queue public ListStack() { // constructs an empty queue front = null; rear = null; size = 0; } public int size() { return size; } public boolean isEmpty() { if (front == null) return true; return false; } public void enqueue(Object elem) { Node v = new Node(elem, null);//create and link-in a new node
if (size == 0) {front = v; rear = v;} else {rear.setNext(v); rear = v; size++; }
public Object front() throws QueueEmptyException { if (isEmpty()) throw new QueueEmptyException("Stack is empty."); return front.getElement(); } public Object dequeue() throws QueueEmptyException { if (isEmpty()) throw new QueueEmptyException(“Queue is empty."); Object temp = front.getElement(); front = front.getNext(); // link-out the former front node size--; return temp; }} /** * Runtime exception thrown when one tries to perform operation
* front or dequeue on an empty queue. */ public class QueueEmptyException extends RuntimeException { public QueueEmptyException(String err) { super(err); }}
Application case: A breadth-first search traverses a tree as shown in the followingFigure. Write an algorithm (not a Java program) to search a treein the breadth-first manner by using the queue data structure tocontrol the process.
2 3
1
5
8
4 6 7
1 09 1 1 1 2 1 3 1 4 1 5
Algorithm:create a Queue Q;put root of the tree into Q;while (Q is not empty){
t Q.dequeue();if (t’s left child is not a leaf)
put t’s left child into Q;if (t’s right child is not a leaf)
put t’s right child into Q;visit t;
}
Singly Linked Listsh e a d
n e x t
e l e m e n t
n e x t n e x tn e x t
e l e m e n t e l e m e n t e l e m e n t
B a l t i m o r e R o m e S e a t t l e T o r o n t o
l i n k : T h e n e x t r e f e r e n c e i n s i d e a n o d e i s a l i n k o r p o i n t e r t o a n o t h e r n o d e .
Class Node
Here is an implementation of nodes in Java: public class Node { private Object element; private Node next; public Node() { this( null, null ); } public Node( Object e, Node n ) { element = e; next = n; }
Object getElement() { return element } Node getNext() { return next; } void setElement( Object newElem ) { element = newElem; } void setNext( Node newNext ) { next = newNext; } }
How to generate a singly linked list?
class HeadTail {Node head;Node tail;
HeadTail(Node x, Node y) {
head = x;tail = y;
}}
public class GeneratingList {public static void main (String[] args){
String [] arr1 ={"Winnipeg","Vancouver","Bejing","Athen“"London","Berlin","Toronto","Seattle“"Rome","Baltimore"}; HeadTail a = linkedList(arr1);
Node x = a.head;while (x != null) {
System.out.println(x.getElement());x = x.getNext();
}
}
public static HeadTail linkedList(String[] b) {Node head = null;Node tail = null;Node x = null;for (int i = 0; i < b.length; i++) {x = new Node(); x.setElement(b[i]);
if (i == 0 ) {x.setNext(null); tail = x;}else x.setNext(head);head = x;
} return new HeadTail(head, tail);
}}
Doubly Linked ListF o r c o n v e n i e n c e , a d o u b l y l i n k e d l i s t h a s a h e a d e r n o d e a n d a t r a i l e r n o d e . T h e y a r e a l s o c a l l e d s e n t i n e l n o d e s , i n d i c a t i n g b o t h t h e e n d s o f a l i s t .
h e a d e r
B a l t i m o r e R o m e S e a t t l e
t r a i l e r
Difference from singly linked lists:- each node contains two links.- two extra nodes: header and trailer, which contain no
elements.
Here is an implementation of nodes for doubly linked lists in Java: public class DLNode { private Object element; private DLNode next, prev; public DLNode() { this( null, null, null ); } public DLNode( Object e, DLNode p, DLNode n ) { element = e; next = n; prev = p; }
Class DLNode
void setElement( Object newElem ) { element = newElem; } void setNext( DLNode newNext ) { next = newNext; } void setPrev( DLNode newPrev ) { prev = newPrev; } Object getElement() { return element; } DLNode getNext() { return next; } DLNode getPrev() { return prev; } }
DequesDefinition: A double-ended queue is a queue that supportsinsertion and deletion at both the front and the rear of the queue.
A deque D is an abstract data type that supports the followingfour fundamental methods:
insertFirst(e): Insert a new element e at the beginning of D.
Input: Object; Output: None. insertLast(e): Insert a new element e at the end of D.
Input: Object; Output: None. removeFirst(): Remove and return the first element of D; an error occurs
if D is empty. Input: None; Output: Object
removeLast(): Remove and return the last element of D; an error occurs if D is empty. Input: None; Output: Object
public interface Deque {void insertFirst(Object e);void insertLast(Object e);Object removeFirst();Object removeLast();Object first();Object last();int size();boolean isEmpty();
}
Class MyDeque
public class MyDeque implements Deque { DLNode header, trailer; int size; public MyDeque() { header = new DLNode(); trailer = new DLNode(); header.setNext( trailer ); trailer.setPrev( header ); size = 0; } … …
header trailer
Vectors, Lists, and Sequences
VectorsListsSequencesIterators
Vector (interface) List (interface)
Sequence (interface)ArrayVector (class) NodeList (class)
ArraySequence (class) NodeSequence (class)
impl. extends extends
impl. impl. extendsextends
impl.
vector: A linear sequence that supports access to its elements by their ranks. The rank of a given element: The number of the elements that are before the given element. Example:
(4, 3, 5, 2, 9)
Element 4 3 5 2 9 Rank 0 1 2 3 4
The ranks are between 0 and n - 1 (n = 5 in this example).
A Simple Array-Based Implementation
Vector ADT rank
Array index
public interface Vector { public int size(); public boolean isEmpty(); public Object elemAtRank(int r); public Object replaceAtRank(int r, Object e); public void insertAtRank(int r, Object e); public Object removeAtRank(int r);}
Vectors
public class ArrayVector implements Vector { private Object[] A; // array storing the elements of the vector private int capacity = 16; // initial length of array A private int size = 0; // number of elements stored in the vector /** Creates the vector with initial capacity 16. */ public ArrayVector() { A = new Object[capacity]; }
public Object elemAtRank (int r) {return a[r];}public int size() {return size;}public boolean isEmpty {return size()==0;}public Object replaceAtRank (int r, Object e) {
Object temp=a[r];a[r]=e;return temp;
}
/** Inserts an element at the given rank. */ public void insertAtRank(int r, Object e) throws BoundaryViolationException { checkRank(r, size() + 1); if (size == capacity) { // an overflow capacity *= 2; Object[] B = new Object[capacity]; for (int i=0; i<size; i++)
B[i] = A[i]; A = B;} for (int i=size-1; i>=r; i--) // shift elements up A[i+1] = A[i]; A[r] = e; size++; }
/** Removes the element stored at the given rank. */ public Object removeAtRank(int r) throws BoundaryViolationException { checkRank(r, size()); Object temp = A[r]; for (int i=r; i<size-1; i++) // shift elements down A[i] = A[i+1]; size--; return temp; } public int size( ) {return size;}
List: A container of elements that stores each element at a positionand that keeps these positions arranged in a linear order.
The position abstract data type supports only one simple method:
public interface Position { Object element();}
The concept of position is similar to the concept of node in adoubly linked list.
Lists
Position element();
Dnode element(){…}; getNext(){…}; getPrev(){…}; setNext(){…}; setPrev(){…}; setElement(){…};
impl.
public class DNode implement Position { private DNode next, prev; private Object element; public DNode( DNode newPrev, DNode newNext, Object elem ){ prev = newPrev; next = newNext; element = elem; } public Object element() throws InvalidPositionException { if(( prev == null ) && ( next == null )) throw new InvalidPositionException(
"Position is not in a list!" ); return element; } public DNode getNext() { return next; } public DNode getPrev() { return prev; }
public void setNext( DNode newNext ) { next = newNext; } public void setPrev( DNode newPrev ) { prev = newPrev; } public void setElement( Object newElement ) { element = newElement; } }
List ADT position
Doubly linked list Dnode
Doubly Linked List Implementation
public interface List {/** Returns the number of elements in this list. */ public int size(); /** Returns whether the list is empty. */ public boolean isEmpty(); /** Returns the first node in the list. */ public Position first(); /** Returns the last node in the list. */ public Position last(); /** Returns the node after a given node in the list. */ public Position next(Position p) throws InvalidPositionException, BoundaryViolationException; /** Returns the node before a given node in the list. */ public Position prev(Position p) throws InvalidPositionException, BoundaryViolationException;
/** Inserts an element at the front of the list. */ public Position insertFirst(Object e); /** Inserts and element at the back of the list. */ public Position insertLast(Object e); /** Inserts an element after the given node in the list. */ public Position insertAfter(Position p, Object e) throws InvalidPositionException; /** Inserts an element before the given node in the list. */ public Position insertBefore(Position p, Object e) throws InvalidPositionException; /** Removes a node from the list. */ public Object remove(Position p) throws InvalidPositionException; /** Replaces the element stored at the given node. */ public Object replace(Position p, Object e)
throws InvalidPositionException;}
Class NodeList
public class NodeList implements List { protected int numElts; protected DNode header, trailer; public NodeList() { numElts = 0; header = new DNode( null, null, null ); trailer = new DNode( header, null, null ); header.setNext( trailer ); }
header trailer
protected DNode checkPosition( Position p ) throws InvalidPositionException { if( p == null ) throw new InvalidPositionException( "Null position passed to NodeList." ); if( p == header ) throw new InvalidPositionException( "The header node is not a valid position." ); if( p == trailer ) throw new InvalidPositionException( "The trailer node is not a valid position." ); try { DNode temp = ( DNode )p; if(( temp.getPrev() == null ) || ( temp.getNext() == null )) throw new InvalidPositionException( "Position does not belong to a valid NodeList." ); return temp; }
catch( ClassCastException e ) { throw new InvalidPositionException( "Position is of wrong type for this container." );
} }
public int size() { return numElts; } public boolean isEmpty() { return( numElts < 1 ); } public boolean isFirst( Position p ) throws InvalidPositionException { DNode v = checkPosition(p); return v.getPrev() == header; } public Position first() throws EmptyContainerException { if( isEmpty() ) throw new EmptyContainerException( "List is empty" ); return header.getNext(); } public Position last() throws EmptyContainerException { if( isEmpty() ) throw new EmptyContainerException( "List is empty" ); return trailer.getPrev(); }
public Position before( Position p ) throws InvalidPositionException, BoundaryViolationException { DNode v = checkPosition( p ); DNode prev = v.getPrev(); if( prev == header ) throw new BoundaryViolationException( "Cannot advance past the beginning of the list" ); return prev; }
public Position insertBefore( Position p, Object element ) throws InvalidPositionException { DNode v = checkPosition( p ); numElts++; DNode newNode = new DNode( v.getPrev(), v, element ); v.getPrev().setNext( newNode ); v.setPrev( newNode ); return newNode; }
header trailerv = p
elem ent
new Node
p u b l i c P o s i t i o n i n s e r t F i r s t ( O b j e c t e l e m e n t ) { n u m E l t s + + ; D N o d e n e w N o d e = n e w D N o d e ( h e a d e r , h e a d e r . g e t N e x t ( ) , e l e m e n t ) ; h e a d e r . g e t N e x t ( ) . s e t P r e v ( n e w N o d e ) ; h e a d e r . s e t N e x t ( n e w N o d e ) ; r e t u r n n e w N o d e ; }
h e a d e r t r a i l e r
e l e m e n t
n e w N o d e
p u b l i c O b j e c t r e m o v e ( P o s i t i o n p ) t h r o w s I n v a l i d P o s i t i o n E x c e p t i o n { D N o d e v = c h e c k P o s i t i o n ( p ) ; n u m E l t s - - ; D N o d e v P r e v = v . g e t P r e v ( ) ; D N o d e v N e x t = v . g e t N e x t ( ) ; v P r e v . s e t N e x t ( v N e x t ) ; v N e x t . s e t P r e v ( v P r e v ) ; O b j e c t v E l e m = v . e l e m e n t ( ) ; v . s e t N e x t ( n u l l ) ; v . s e t P r e v ( n u l l ) ; r e t u r n v E l e m ; }
h e a d e r t r a i l e r
v = p
v P r e v
v E l e m
v N e x t
public Object replaceElement( Position p, Object element ) throws InvalidPositionException { DNode v = checkPosition( p ); Object oldElt = v.element(); v.setElement( element ); return oldElt; } public void swapElements( Position a, Position b ) throws InvalidPositionException { DNode pA = checkPosition( a ); DNode pB = checkPosition( b ); Object temp = pA.element(); pA.setElement( pB.element() ); pB.setElement( temp ); }
Sequence
The sequence abstract data type supports all the methods of both the vector ADT and list ADT, plus the following two “bridging” methods that provide connections between ranks and positions: atRank(r): Return the position of the element with rank r.
Input: Integer; Output: Position rankOf(p): Return the rank of the element at position p.
Input: Position; Output: Integer
In Java, the interface for sequences is an example of multiple inheritance : interface Sequence extends List, Vector { public Position atRank( int rank ) throws BoundaryViolationException; public int rankOf( Position position ) throws InvalidPositionException; }
Vector interface List interface
Sequence interface
Sequence ADT Position rank
Doubly linked list Node atRank(r)rankOf(p)
Implementation of a sequence with a doubly linked list:
/** Implementation of a sequence by means of a doubly linked list. */public class NodeSequence extends NodeList implements Sequence { /** Checks whether the given rank is in the range [0, n - 1] */ protected void checkRank(int r, int n) throws BoundaryViolationException { if (r < 0 || r >= n) throw new BoundaryViolationException("Illegal rank: " + r); }
/** Returns the position containing the element at the given rank; * O(n) time. */ public Position atRank (int rank) { DNode node; checkRank(rank, size()); if (rank <= size()/2) { // scan forward from the head node = header.getNext(); for (int i=0; i < rank; i++)
node = node.getNext(); } else { // scan backward from the tail node = trailer.getPrev(); for (int i=1; i < size()-rank; i++)
node = node.getPrev();} return node; }
/** Gets an element at the given rank.*/ public Object elemAtRank(int r) { return atRank(r).element(); } /** Returns the rank of a given position.*/ public int rankOf(Position p) { DNode node; node = header.getNext(); for for (int i=1; i < size(); i++) {
if (p == node) return i;else node = node.getNext();}
} }
/** Inserts an element at the given rank; O(n) time. */ public void insertAtRank (int rank, Object element) throws BoundaryViolationException { checkRank(rank, size() + 1); if (rank == size()) insertLast(element); else { insertBefore(atRank(rank), element); } }
/** Removes the element stored at the given rank; O(n) time. */ public Object removeAtRank (int rank) throws BoundaryViolationException { checkRank(rank, size()); return remove(atRank(rank)); }
public Object replaceAtRank (int rank, object element) throws BoundadryViolationException { checkRank(rank); return replaceElement(atRank(rank), element); } }
Implementing a Sequence with an Array
0
1 2
3 N - 1
0
1 2
3
B a l t i m o r e N e w Y o r k R o m e P r o v i d e n c e
S
Iterator
The iterator abstract data type supports the following methods:
hasNext(): Test whether there are elements left in the iterator. Input: None; Output: Boolean
nextObject(): Return and remove the next element in the iterator. Input: None; Output: Object
Java provides an Iterator interface.
public interface Iterator { boolean hasNext(); Object next(); }
An implementation of the Iterator is always related to container,i.e., a vector, a list, or a sequence.
The following is an exemplary implementation of the List Iterator.
public class PositionIterator implements Iterator { protected List list; // the underlying list protected Position cur; // the current (next) position public PositionIterator() { } // default constructor public PositionIterator(List L) { // preferred constructor list = L; if (list.isEmpty()) cur = null; // list is empty else cur = list.first(); // start with the first position }
public boolean hasNext() { return (cur != null); } public Object next() throws NoSuchElementException { if (!hasNext())
throw new NoSuchElementException("No next position"); Position toReturn = cur; if (cur == list.last()) cur = null; // no positions left else cur = list.next(cur); // move cursor to the next position return toReturn; }}class NoSuchElementException extends Exception { public NoSuchElementException() {super();} public NoSuchElementException(String s) { super(s); }}
In a similar way, we can establish an ElementIterator as follows.
public class ElementIterator implements Iterator { protected List list; // the underlying list protected Position cur; // the current (next) position protected Object elementCur;// the current (next) element public ElementIterator() { } // default constructor public ElementIterator(List L) { // preferred constructor list = L; if (list.isEmpty()) cur = null; // list is empty else cur = list.first(); // start with the first position }
public boolean hasNext() { return (cur != null); } public Object next() throws NoSuchElementException { if (!hasNext())
throw new NoSuchElementException("No next position"); elementCur = cur.element(); if (cur == list.last()) cur = null; // no positions left else cur = list.next(cur); // move cursor to the next position return elementCur; }}
InspectableContainersizeisEmptyelements
InspectableVectorelemAtRank
InspectableListfirstlastbeforeafterpositions
VectorreplaceAtRankinsertAtRankremoveAtRank
InspectableSequenceatRankrankOf
ListreplaceElementswapElementsinsertFirstinsertLastinsertBeforeinsertAfterremove
Sequence
Trees
What is a tree?Tree ADTBasic algorithms on treesTree traversal
Class Mammalia
Order Carnivora(carnivores)
Order Chiroptera(bats)
...
Order Proboscidea(elephants)
Family Felidae(cats)
Family Phocidae(seals)
...
Family Ursidae(bears)
SubfamilyAcinonychinae(cheetahs)
Subfamily Felinae(small cats)
SubfamilyPantherinae(leopards, lions,and tigers)
What is a tree?
public interface Tree { public int size(); public Boolean isEmpty(); public ElementIterator elements(); public PositionIterator positions(); public void swapElements( Position v, Position w ); public Object replaceElement( Position v, Object e ); public Position root(); public Position parent( Position v ); public PositionIterator children( Position v ); public boolean isInternal( Position v ); public boolean isExternal( Position v ); public boolean isRoot( Position v );}
Tree Interface – Tree ADT
IspectableContainersizeisElementElements
IspectablePositionContainerpositions
PositionContainerswapElementreplaceElement
InspectableTreerootparentchildrenisRootisInternalisExternal
Tree
A Binary Tree Interface in Java
Similar to the interfaces InspectableTree and Tree, we have interfaces InspectableBinaryTree and BinaryTree. public interface InspectableBinaryTree extends InspectableTree { public Position leftChild( Position v ); public Position rightChild( Position v ); public Position sibling( Position v ); } public interface BinaryTree extends InspectableBinaryTree, PositionalContainer { }
InspectablePositionalContainerpositions
InspectableVectorelemAtRank
InspectableListfirstlastbeforeafterpositions
VectorreplaceAtRankinsertAtRankremoveAtRank
InspectableSequenceatRankrankOf
ListinsertFirstinsertLastinsertBeforeinsertAfterremove
Sequence
InspectableContainersizeisEmptyelements
PositionalContainerswapElementsreplaceElement
InspectableTreerootparentchildrenisRootisInternalisExternal
Tree InspectableBinaryTreeleftChildrightChildsibling
BinaryTree
Data Structures for RepresentingTrees
1. Storing a binary tree in an array
2. Storing a tree as a linked list
S in c e a b in a r y t r e e i s a n o r d e r e d t r e e a n d h a s l e v e l s , i t i s c o n v e n ie n t to a s s ig n a n u m b e r to e a c h n o d e .
2 3
1
5
8
4 6 7
1 09 1 1 1 2 1 3 1 4 1 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Where a node v of tree T is stored can be determined as follows.
Let p(v) be the index, where v is stored. The followingrelationships must be satisfied:
If v is the root of T, then p(v) = 1.If v is the left child of the node u, then p(v) = 2p(u)If v is the right child of the node u, then p(v) = 2p(u) + 1.
With a level numbering of the nodes, it is convenient to use a vector S to represent a tree. Recall that we use ranks to access elements in a vector. So we can place the node v in a tree T at rank p(v).
2 31
54
7 10
11 14
15
1
2 3
4 5
7
10
11 14
15
We can also use a linked structure to represent a tree. In this case, the node v of a tree T is represented by an object with four references.
parent
left right
element
Baltimore Chicago New York Providence Seattle
size
root
5
New York
Baltimore Chicago Providence Seattle
a
b
e
f
c
g
d
Class BTNodepublic class BTNode implements Position { private Object element; private BTNode left, right, parent; public BTNode() {} public BTNode( Object o, BTNode u, BTNode v, BTNode w ) { setElement( o ); setParent( u ); setLeft( v ): setRight( w ); } public Object element() { return element; } public void setElement( Object o ) { element = o; } public BTNode getLeft() { return left; } public void setLeft( BTNode v ) { left = v; } public BTNode getRight() { return right; } public void setRight( BTNode v ) { right = v; } public BTNode getParent() { return parent; } public void setParent( BTNode v ) { parent = v; } }
Interface Hierarchy for PositionsPosition element();
DNode element(){…}; getNext(){…}; getPrev(){…}; setNext(){…}; setPrev(){…}; setElement(){…};
BTNnode element(){…}; getLeft(){…}; getRight(){…}; setLeft(){…}; setRight(){…}; getParent(){…} setElement(){…};
public class LinkedBinaryTree implements BinaryTree { private Position root; private int size; public LinkedBinaryTree() { root = new BTNode( null, null, null, null); size = 1; } public int size() { return size; } public boolean isEmpty() { return ( size == 0 ); } public boolean isInternal( Position v ) { return ((( BTNode )v ).getLeft() != null && (( BTNode )v ).getRight() != null ); } public boolean isExternal( Position v ) { return ((( BTNode )v ).getLeft() == null && (( BTNode )v ).getRight() == null ); } public boolean isRoot( Position v ) {
return ( v == root()); } … …
Also see the complete program for “LinkedBinaryTree” posted onthe home page of Dr. Yangjun Chen.
IspectableContainersizeisElementElements
IspectablePositionContainerpositions
PositionContainerswapElementreplaceElement
InspectableTreeroot, parent, children, isRootisInternal, isExternal
Tree
InspectableBinaryTreeleftChild, rightChild, sibling
BinaryTree
LinkedBinaryTree… …, replaceElement, swapElement, expandExternal,removeAboveExternal
imple.
Basic Algorithms on Trees
Tree depth: public static int depth( InspectableTree T, Position v ) { if( T.isRoot( v )) return 0; else return 1 + depth( T, T.parent( v )); }
Tree height: public static int height2( InspectableTree T, Position v ) { if( T.isExternal( v )) return 0; else { int h = 0; PositionIterator children = T.children(v); while( children.hasNext())
h = Math.max( h, height2( T, children.nextPosition() ));
return 1 + h; } }
Algorithm inorder(T,v): if v is an internal node assign the left child of the node v to u call method inorder(T, u) perform the “visit” action for node v if v is an internal node assign the right child of the node v to u call method inorder(T, u)
r
v
u
T
W
X Y
A
B C
Inorder tree traversal• Inorder traversal based on recursion:
inorder(T, r)
if …inorder(T, u)
“visit” r
If …inorder (T, a)
inorder(T, u)
if …inorder(T, w)
“visit” u
If …inorder (T, v)
inorder(T, w)
if …
“visit” w
if …
126
inorder(T, x)
if …
“visit” x
if …
3inorder(T, v)
inorder(T, v)
if …inorder(T, x)
“visit” v
If …inorder (T, y)
4
inorder(T, y)
inorder(T, y)
if …
“visit” y
if …
5
inorder(T, a)
inorder(T, a)
if …inorder(T, b)
“visit” a
If …inorder (T, c)
8
7
9
• Inorder traversal based on Stack data structure
Algorithm Stack-control-inorder(T, v)establish stack S;S.push(v);while (S is not empty) do{u := S.pop(); if u is leaf or u is marked, visit u; else {let v1 and v2 be the left and right child node of
v, respectively; S.push(v2); mark u; S.push(u*); S.push(v1); }
}
ur*ar
wu*vr*a
u*vr*a
print(w) vr*a
print(u)
xv*yr*a
v*yr*a
print(x)yr*a
print(v)r*a
print(y)
a
print(r) ba*c a*
c
print(b)
c
print(a) print(c)
Preorder Traversal
Algorithm preorder(T, v):perform the “visit” action for node vfor each child w of v
call preorder(T, w)
v
w
postorder(T,v)
postorder(T,w)
• Preorder traversal based on recursion:
Algorithm binaryPreorder(T,v): perform the “visit” action for node vif v is an internal node
call binaryPreorder(T, T.leftChild( v ))call binaryPreorder(T, T.rightChild( v ))
• Preorder traversal based on Stack data structure
Algorithm PreorderOnStack(BTree myTree, BNode v){
Establish a Stack myStack;myStack.push(v); While (myStack is not empty) do{
u = myStack.pop();visit(u);if ( u has right child)
myStack.push(u.rightchild());if ( u has left child)
myStack.push(u.leftchild());}}
Postorder Traversal• Postorder traversal based on recursion:
Algorithm Postorder(T,v): for each child w of v
call postorder(T,w)perform the “visit” action for node v
v
w
postorder(T,v)
postorder(T,w)
• Postorder traversal based on Stack data structure
Algorithm PostorderOnStack(T,v): {establish stack D; D.push(D); while (D is not empty) do {u := D.pop();
if u is leaf or marked, then visit u;else {
let u1, …, uk be the children of u;mark u; D.push(u);for (i = k; 0 <= i; i--)D.push(ui):}
}}
Load a tree from disk into main memory
a
c
g
b d
e f
File:
a; b, c, d.b; e, f.e;f;c; g.g;d;
a
c
g
b d
e f
a
b
e
f
c
g
d
public class Node1{ String x;
Node2 y;}public class Node2{ Node1 x;
Node2 y;}
S.push(root, null);While (S is not empty) do{ x := S.pop( );generate a node n for x.node_value;if x.point_to_parent is not nullthen generate links between n and x.point_to_parent;let x1, …, xk be the children of x;for i = k to 1 doS.push(xi, n);
}
node_value Point_to_parent
a; b, c, d.b; e, f.e;f;c; g.g;d;
stack S:
XML File<book>
<title>
“The Art of Programming”
</title><author>
“D. Knuth”
</author><year>
“1969”
</year></book>
<book>
<title> <author> <year>
“The Art ofProgramming”
“D. Knuth” “1969”
XML File
node_value Point_to_node
stack S:
Read a file into a character array A:
< b o o k > < t i t l e > “ T h e A r t …
XML FileAlgorithm:
Scan array A;If A[i] is ‘<’ and A[i+1] is a character then {
generate a node x for A[i..j],where A[j] is ‘>’ directly after A[i];let y = S.top().pointer_to_node;make x be a child of y; S.push(A[i..j], x);
If A[i] is ‘ ‘‘ ’, then {genearte a node x for A[i..j],where A[j] is ‘ ’’ ’ directly after A[i];let y = S.top().pointer_to_node;make x be a child of y;
If A[i] is ‘<’ and A[i+1] is ‘/’, then S.pop();
Storing a tree onto disk
a
d f
e h b k
…
a
d
e
0123456789…
file:
node 0
node 1
node 2
i = 0
i = 1
i = 2
Storing a tree onto disk
a
d f
e h b k
…
a
d
e
0123456789…
file:
node 0
node 1
node 2
i = 0
i = 1
i = 2
1
2
h
3
…4
Storing a tree onto disk
We search a tree in preorder and use a special stack datastructure to control the traversal in such a way the parentaddress can be recorded.
data flag to indicate left or right child
parent address
Storing a tree onto disk
Algorithm storing-tree(T, v)establish stack S; i = 0;S.push((v, 0, -1))while (S in not empty) do {
u := S.pop(); store u.Data in address i*3;if (u.Parent-address is not equal to –1)then {if (u.Flag == 0) then j := 0; else j := 1;
store i in address (u.Parent-address)*3 + 1 + j;}let u1, u2 be the left and right child of u, respectively;S.push((u2, 1, i)); S.push((u1, 0, i)); i++; }
-1 indicates that the correspondingnode is the root.
Merge SortDivide and Conquer The divide-and-conquer approach consists of three steps. 1. Divide: If S has zero or one element, return S immediately; it is already sorted. Otherwise, split S into two
sequences S1 and S2, each containing about half of the elements in S; that is, S1 contains the first n/2 elements of S, and S2 contains the rest.
2. Recur: Recursively sort sequence S1 and S2. 3. Conquer: Put back the elements into S by merging the sorted sequences S1 and S2 into a sorted sequence.
Algorithm merge(S1, S2, S) loop until either S1 or S2 is empty assign the first element in S1 to e1 assign the first element in S2 to e2 if e1 is less than or equal to e2 remove e1 from S1 and insert it into S as the last element else remove e2 from S2 and insert it into S as the last element loop until S1 is emtpy remove the first element from S1 and insert it into S as the last element loop until S2 is emtpy remove the first element from S2 and insert it into S as the last element
The figure here shows how the sequence is divided in the previous example.
6385 24 45 17 31 5096
6385 24 45 17 31 5096
85 24 63 45 17 31 5096
85 24 63 45 17 31 96 50
The figure here shows how the sequences are merged in the previous example.
63 8524 4517 31 50 96
63 8524 45 17 31 50 96
8524 6345 17 31 50 96
85 24 63 45 17 31 96 50
A Java Implementation of Merge Sort public static void mergeSort( Sequence S, Comparator c ) { int n = S.size(); if( n < 2 ) return; int i = n; Sequence S1 = new NodeSequence(); do { S1.insertLast( S.first()); i--; } while( i > n/2 ); Sequence S2 = new NodeSequence(); do { S2.insertLast( S.first()); i--; } while( i > 0 ); mergeSort( S1, c ); mergeSort( S2, c ); merge( S1, S2, c, S ); }
public static void merge( Sequence S1, Sequence S2, Comparator c, Sequence S ) { while( !S1.isEmpty() && !S2.isEmpty()) if(c.isLessThanOrEqualTo( S1.first().element(), S2.first().element())) S.insertLast( S1.remove( S1.first())); else S.insertLast( S2.remove( S2.first())); while( !S1.isEmpty()) S.insertLast( S1.remove( S1.first())); while( !S2.isEmpty()) S.insertLast( S2.remove( S2.first())); }
Quick Sort 1. Divide: If S has at least two elements (nothing needs to be
done if S has zero or one element), select a specific element x from S, which is called the pivot. As is common practice, choose the pivot x to be the last element in S. Remove all the elements from S and put them into three sequences: 1) L, storing the elements in S less than x 2) E, storing the elements in S equal to x 3) G, storing the elements in S greater than x. Of course, if the elements of S are all distinct, then E holds just one element - the pivot itself.
2. Recur: Recursively sort sequence L and G. 3. Conquer: Put back the elements into S in order by first
inserting the elements of L, then those of E, and finally those of G
Algorithm inPlaceQuickSort(S, a, b) Input: Sequence S of distinct elements; integers a and b Output: Sequence S with elements originally from ranks
from a to b, inclusive, sorted in nondecreasing order from ranks a to b
if a is greater than or equal to b return assign the element at rank b to variable p (pivot) assign a to variable l assign b - 1 to variable r while l is less than or equal to r while l is less than or equal to r and the element at rank l is less than or equal to p increase l by 1
while r is greater than or equal to l and the element at rank r is greater than or equal to p decrease r by 1 if l is less than r swap the elements at ranks l and r swap the elements at ranks l and b inPlaceQuickSort(S, a, l - 1) inPlaceQuickSort(S, l + 1, b)
W h a t d o w e w a n t : T h e t w o s m a l l e r s e q u e n c e s a r e s e p a r a t e d b y t h e p i v o t . F o r e x a m p l e :
6 38 52 4 4 51 73 1 5 0 9 6
H o w c a n w e d o i t : U s i n g t w o i n d i c e s , s t a r t i n g f r o m b o t h e n d s . W e s e a r c h f o r a p a i r o f e l e m e n t s s u c h t h a t o n e i s s m a l l e r t h a n t h e p i v o t a n d t h e o t h e r i s l a r g e r t h a n t h e p i v o t . T h e n , s w a p t h e m . W e r e p e a t t h i s p r o c e s s u n t i l t h e t w o i n d i c e s m e e t .
6 3
r
2 4 4 5 1 7 3 1 5 09 68 5
l
E x a m p l e :
6 3
r
2 4 4 5 1 7 3 1 5 09 68 5
l
6 3
r
2 4 4 5 1 7 3 1 5 09 68 5
l
6 3
r
2 4 4 5 1 73 1 5 09 68 5
l
6 3
r
2 4 4 5 1 73 1 5 09 68 5
l
6 3
r
2 4 4 51 73 1 5 09 68 5
l
6 3
r
2 4 4 51 73 1 5 09 68 5
l
6 3
r
2 4 4 51 73 1 5 0 9 68 5
l
Java implementation (each time choose the last element as the pivot.) public static void quickSort( Sequence S, Comparator c ) { if( S.size() < 2 ) return; quickSortStep( S, c, 0, S.size() - 1 ); } private static void quickSortStep( Sequence S, Comparager c, int leftBound, int rightBound ) { if( leftBound >= rightBound ) return; Object pivot = S.atRank( rightBound ).element(); int leftIndex = leftBound; int rightIndex = rightBound - 1; while(( leftIndex <= rightIndex ) {
while(( leftIndex <= rightIndex ) && c.isLessThanorEqualTo( S.atRank( leftIndex ).element(), pivot )) leftIndex++;
while((rightIndex >= leftIndex ) && c.isGreaterThanorEqualTo(
S.atRank( rightIndex ).element(), pivot )) rightIndex--; if( leftIndex < rightIndex ) S.swapElements( S.atRank( leftIndex ), S.atRank( rightIndex ));
} S.swapElements( S.atRank( leftIndex ), S.atRank( rightBound )); quickSortStep( S, c, leftBound, leftIndex - 1 ); quickSortStep( S, c, leftBound + 1, rightBound ); }
Java implementation(each time choose the middle element as the pivot.)
public class Sorter {public static void sort (int[] a, int from, int to) {
if ((a == null) || (a.length < 2)) return;int i = from, j = to;int center = a[(from + to)/2];do {
while ((i < to) && (a[i] < center)) i++;while ((j > from) && (a[j] > center)) j--;if (i < j) { int tmp =a[i]; a [i] = a[j]; a[j] = tmp;}i++; j--;}while (i <= j);
if (from < j) sort(a, from, j);if (i < to) sort(a, i, to);
}}
The Set Abstract Data Type
set: A container of distinct objects.
1. There are no duplicate elements in a set. 2. There is no explicit notion of keys or even an order.
Union of two sets A and B
}or :{ BxAxxBA
63 5
0
A
63
1
2B
49A B
63
50
9 4
2
1
Intersection of two sets A and B
} and :{ BxAxxBA
63 5
0
A
63
B
49A B
63
2
1
Subtraction of two sets A and B
} and :{ BxAxxBA
63
5
0
A
63
B
4
9
A B2
1
9
0
5
The set abstract data type supports the following fundamental methods acting on a set A.
union(B): Replace A with the union of A and B, that is, assign A B to A. Input: Set; output: None
intersect(B): Replace A with the intersection of A and B, that is, assign A B to A. Input: Set; output: None
subtract(B): Replace A with the difference of A and B, that is, assign A - B to A. Input: Set; output: None
Algorithm genericMerge(A,B): Input: Sets represented by sorted sequences A and B Output: Set represented by a sorted sequence C copy A to A' copy B to B' loop until either A' or B' is empty get the first element from A' and assign it to a get the first element from B' and assign it to b if a < b action for this case remove a from A' else if a = b action for this case remove a from A' remove b from B' else action for this case remove b from B'
loop until A' is empty get the first element from A' and assign it to a action as if a < b remove a from A' loop until B' is empty get the first element from B' and assign it to b action as if b < a remove a from B' The actions for the three cases are listed below for set operations. Case union intersection subtraction a < b insert a to C no action insert a to C a = b insert a to C insert a to C no action b < a insert b to C no action no action
A Java implementation public abstract class Merger { private Object a, b; private PositionIterator iterA, iterB; public void merge( Sequence A, Sequence B, Comparator comp, Sequence C ) { iterA = A.elements(); iterB = B.elements(); boolean aExists = advanceA(); boolean bExists = advanceB(); while( aExists && bExists ) { if( comp.isLessThan( a, b )) { aIsLess( a, C ); aExists = advanceA(); } else if( comp.isEqualTo( a, b )) { bothAreEqual( a, b, C ); aExists = advanceA(); bExists = advanceB(); } else { bIsLess( b, C ); bExists = advanceB(); } }
while( aExists ) { aIsLess( a, C ); aExists = advanceA();
} while( bExists ) {
bIsLess( b, C ); bExists = advanceB(); } } protected void aIsLess( Object a, Sequence C ) {} protected void bothAreEqual( Object a, Object b, Sequence C ) { } protected void bIsLess( Object b, Sequence C ) {} private boolean advanceA() { if( iterA.hasNext()) { a = iterA.next(); return true; } return false; } private boolean advanceB() { if( iterB.hasNext()) { b = iterB.next(); return true; } return false; } }
Implementation of union with class Merger public class UnionMerger extends Merger { protected void aIsLess( Object a, Sequence C ) { C.insertLast( a ); } protected void bothAreEqual( Object a, Object b, Sequence C ) { C.insertLast( a ); } protected void bIsLess( Object b, Sequence C ) { C.insertLast( b ); } }
Implementation of intersection with class Merger public class IntersectMerger extends Merger { protected void aIsLess( Object a, Sequence C ) {} protected void bothAreEqual( Object a, Object b, Sequence C ) { C.insertLast( a ); } protected void bIsLess( Object b, Sequence C ) {} }
Implementation of subtraction with class Merger public class SubtractMerger extends Merger { protected void aIsLess( Object a, Sequence C ) { C.insertLast( a ); } protected void bothAreEqual( Object a, Object b, Sequence C ) { } protected void bIsLess( Object b, Sequence C ) {} }
Graphs and Graph Traversal •Graph ADT - What is a graph? - Graph methods •Data structure for graphs - Edge list structure, adjacency list structure, adjacency matrix •Graph Traversal - Depth-first search - Breadth-first search •Directed graphs
graph: A set V of vertices (nodes) and a collection E of pairs of vertices from V, called edges (arcs).
directed edge: The edge (u, v) is ordered, with the node u preceding v. undirected edge: The edge (u, v) is not ordered. undirected graph: All the edges are undirected. directed graph (digraph): All the edges are directed. mixed graph: The graph have both directed and undirected edges. end vertices: The two vertices joined by an edge. If the edge is directed, its first endpoint is its origin and the other is the destination. adjacent vertices: Endpoints of the same edge.
outgoing edge of a vertex: The vertex is the origin of the directed edge.
incoming edge of a vertex: The vertex is the destination of the directed edge. degree of a vertex v: The number of incident edges of v. Denoted as deg(v). in-degree of a vertex v: The number of the incoming edges. Denoted as indeg(v). out-degree of a vertex v: The number of the outgoing edges. Denoted as outdeg(v).
R e c a l l t h a t i n a s e t , a l l e l e m e n t s a r e u n i q u e . W e r e f e r t o t h e g r o u p o f e d g e s i n a g r a p h a s a c o l l e c t i o n , n o t a s e t . T h i s a l l o w s d u p l i c a t e d e d g e s c a l l e d p a r a l l e l e d g e s o r m u l t i p l e e d g e s .
s e l f - l o o p : A n e d g e w h o s e t w o e n d p o i n t s c o i n c i d e .
s i m p l e g r a p h : A g r a p h w i t h o u t p a r a l l e l e d g e s o r s e l f - l o o p s .
P r o p o s i t i o n 1 2 . 6 : I f G i s a s i m p l e g r a p h w i t h m e d g e s , t h e n
mvGv
2)deg(
P r o p o s i t i o n 1 2 . 7 : I f G i s a d i r e c t e d g r a p h w i t h m e d g e s , t h e n
mvvGvGv
)(outdeg)(indeg
Proposition 12.8: Let G be a simple graph with n vertices and m edges. If G is undirected, then m n(n – 1)/2, and if G is directed, m n(n – 1). path of a graph: A sequence of alternating vertices and edges, which starts at a vertex and ends at a vertex such that each edge is incident to its predecessor and successor vertex. cycle: A path such that its start and end vertices are the same. simple path: Each vertex on the path is distinct. simple cycle: Each vertex on the cycle is distinct, except for the first and last one.
directed path: A path such that all the edges are directed and are traversed along their direction. directed cycle: A cycle such that all the edges are directed and are traversed along their direction. subgraph of a graph G: a graph H whose vertices and edges are subsets of the vertices and edges of G, respectively. spanning subgraph of G: A subgraph of G that contains all the vertices of the graph G. connected graph: For any two vertices, there is a path between them.
connected components of G: Its connected subgraphs.
forest: A graph without cycles. tree: A connected forest, that is, a connected graph without cycles Note: The trees in graph theory do not have root. They are called free trees. Those trees we have learned before are called rooted trees. spanning tree of a graph: A spanning subgraph that is a tree.
Data Structure for Graphs
Calgary
AC112
Winnipeg
Toronto
Ottawa
Vancouver
WJ35
JG131
JG130
AC201
WJ75
JG120AC200
V
E d g e l i s t s t r u c t u r e :
C a lg a r y O t ta w a T o r o n t o V a n c o u v e r W in n ip e g
W J 3 5A C 1 1 2 J G 1 2 0 W J 7 5 A C 2 0 1J G 1 3 0 J G 1 3 1 A C 2 0 0
E
N o w i f w e w a n t t o f i n d o u t t h e n u m b e r o f i n c i d e n t e d g e s t o t h e v e r t e x T o r o n t o , w e h a v e t o s e a r c h t h e e n t i r e c o n t a i n e r V .
V
E
Calgary Ottawa Toronto Vancouver Winnipeg
WJ35AC112 JG120 WJ75 AC201JG130 JG131 AC200
WJ35
JG131WJ75
in out
JG120
AC200
AC201 JG130AC200
AC112WJ35AC112JG120
WJ75JG130 JG131AC201
in out in out in out in out
Adjacent list structure:
A d ja c e n t m a t r i x :
C a lg a r y O t ta w a T o r o n t o V a n c o u v e r W in n ip e g
0 1 2 3 4
0
1
2
3
4 J G 1 2 0
W J 3 5
A C 1 1 2
W J 7 5
J G 1 3 1
J G 1 3 0
A C 2 0 1
A C 2 0 0
Depth-First-Searching: Algorithm DFS(G, v): Input: A graph G and a vertex v of G Output: A labeling of the edges as discovery/back edges loop for every edge e incident on v if edge e is unexplored assign the opposite vertex to w if vertex w is unexplored label e as discovery edge call DFS(G, w) else label e as a back edge