data structures and algorithm design (review). java basics object-oriented design stacks, queues,...

Post on 18-Dec-2015

219 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

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

top related