Data Structures and Algorithm Design Review Data Structures

  • Slides: 164
Download presentation
Data Structures and Algorithm Design (Review)

Data Structures and Algorithm Design (Review)

Data Structures and Algorithm Design: Graphs Set operations Quick sorting Merge sorting Tree traversal

Data Structures and Algorithm Design: Graphs Set operations Quick sorting Merge sorting Tree traversal Trees and binary trees Vectors, lists and sequences Stacks, queues, and deques Object-oriented design Java basics

Java Basics Class Modifiers abstract, final, public Variable Modifiers public, protected, private, static, final

Java Basics Class Modifiers abstract, final, public Variable Modifiers public, protected, private, static, final Methods Method Modifiers public, protected, private, abstract, final, static Arrays int[] a = new int[ 10 ]; float[][] x = new float[ 8 ][ 10 ]; a[ i ] = 138; x[ i ][ i + 1 ] = 2. 189 + x[ i ];

Object-Oriented Design Inheritance Polymorphism method overriding method overloading Keyword: this Exception Interface, Abstract Classes

Object-Oriented Design Inheritance Polymorphism method overriding method overloading Keyword: this Exception Interface, Abstract Classes Type casting

Stacks, Queues, and Deques Stacks Queues Deques Singly linked lists Doubly linked lists Sample

Stacks, Queues, and Deques Stacks Queues Deques Singly linked lists Doubly linked lists Sample case study application

Stacks Definition: A stack is a container of objects that are inserted and removed

Stacks Definition: A stack is a container of objects that are inserted and removed 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

public interface Stack { public void push( Object element ); public Object pop() throws Stack. Empty. Exception; public int size(); public boolean is. Empty(); public Object top() throws Stack. Empty. Exception; }

public class Array. Stack implements Stack { public static final int CAPACITY = 1000;

public class Array. Stack implements Stack { public static final int CAPACITY = 1000; private in capacity; private Object [] S; private int top = -1; public Array. Statck() { this( CAPACITY ); } public Array. Stack( int cap ) { capacity = cap; S = new Object[ capacity ]; } public int size() { return ( top + 1 ); }

public boolean is. Empty() { return( top < 0 ); } public void push(

public boolean is. Empty() { return( top < 0 ); } public void push( Object obj ) throws Stack. Full. Exception { if( size() == capacity ) throw new Stack. Full. Exception( "Stack overflow" ); S[ ++top ] = obj; } public Object top() throws Stack. Empty. Exception { if( is. Empty() ) throw new Stack. Empty. Exception( "Stack is empty. " ); return S[ top ]; }

public Object pop() throws Stack. Empty. Exception { Object elem; if( is. Empty() )

public Object pop() throws Stack. Empty. Exception { Object elem; if( is. Empty() ) throw new Stack. Empty. Exception( "Stack is Empty. " ); elem = S[ top ]; S[ top-- ] = null; return elem; } }

public class Node. Stack implements Stack { protected Node top; // reference to the

public class Node. Stack implements Stack { protected Node top; // reference to the head node protected int size; // number of elements in the stack public Node. Stack() { // constructs an empty stack top = null; size = 0; } public int size() { return size; } public boolean is. Empty() { 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 Empty. Stack. Exception { if (is. Empty()) throw new Empty.

public Object top() throws Empty. Stack. Exception { if (is. Empty()) throw new Empty. Stack. Exception("Stack is empty. "); return top. get. Element(); } public Object pop() throws Empty. Stack. Exception { if (is. Empty()) throw new Empty. Stack. Exception("Stack is empty. "); Object temp = top. get. Element(); top = top. get. Next(); // link-out the former top node size--; return temp; } }

Sample Case Study Application (1) We want to write a program to calculate the

Sample Case Study Application (1) We want to write a program to calculate the span of the stock’s price on a given day. The span of the stock’s price on a given day: The maximum number of the consecutive days up to the current day such that the stock price on each of those days has been less than or equal to the price on the current day.

Java Implementation

Java Implementation

Main idea: The span si on a certain day i can be easily computed

Main idea: The span si on a certain day i can be easily computed if we know the closest day preceding day i, such that the price on 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).

si = i – h(i). h(0) h(1) h(2) h(3) h(4) h(5) h(6) -1 0

si = i – h(i). h(0) h(1) h(2) h(3) h(4) h(5) h(6) -1 0 1 1 3 1 0 s 1 1 s 2 1 s 3 2 s 4 1 s 5 4 s 6 6 s 0 1

The problem is how to compute h(i) efficiently? Step 1: p 0 = 48.

The problem is how to compute h(i) efficiently? Step 1: p 0 = 48. 97. h(0) = -1, s 0 = 0 - h(0) = 0 – (-1) = 1 0 Day 0. It is possible that h(1) = 0. Step 2: p 1 = 47. 54. Pop days with prices less than or equal to p 1. At this point of time, we have only one element in the stack. It is 0 and p 0 > p 1. So h(1) = 0, s 1 = 1 - h(1) = 1 – 0 = 1. 1 0 Day 1. It is possible that h(2) = 1.

Step 3: p 2 = 45. 83. Pop days with prices less than or

Step 3: p 2 = 45. 83. Pop days with prices less than or equal to p 2. At this point of time, we have two elements in the stack. The top one is 1 and p 1 > p 2. So h(2) = 1, s 2 = 2 - h(2) = 2 – 1 = 1. 2 1 Day 2. It is possible that h(3) = 2. 0 Step 4: p 3 = 46. 34. Pop days with prices less than or equal to p 3. The top one will be taken out since p 3 > p 2. The second one is 1 and p 1 > p 3. So h(3) = 1, s 3 = 3 - h(3) = 3 – 1 = 2. 3 1 0 Day 3. It is possible that h(4) = 3.

Step 5: p 4 = 45. 68. Pop days with prices less than or

Step 5: p 4 = 45. 68. Pop days with prices less than or equal to p 4. The top one is 3 and p 3 > p 4. So h(4) = 3, s 4 = 4 - h(3) = 4 – 3 = 1. 4 3 Day 4. It is possible that h(5) = 4. 1 0 Step 6: p 5 = 46. 95. Pop days with prices less than or equal to p 3. The top two will be taken out since p 5 > p 4 and p 5 > p 3. The third one is 1 and p 1 > p 5. So h(5) = 1, s 5 = 5 - h(5) = 5 – 1 = 4. 5 1 0 Day 5. It is possible that h(6) = 5.

Step 7: p 6 = 48. 17. Pop days with prices less than or

Step 7: p 6 = 48. 17. Pop days with prices less than or equal to p 3. The top two will be taken out since p 6 > p 5 and p 6 > p 1. The third one is 0 and p 0 > p 6. So h(6) = 0, s 5 = 6 - h(6) = 6 – 0 = 6. 6 0 Day 6. The price on day 6. The process stops.

(2) Calculate the following expression using Array. Stack to control the computation: “ 1+2+3

(2) Calculate the following expression using Array. Stack to control the 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 Array. Stack(); int temp; char operator; int a = 0; data. push (new Integer (1)); for (int x = 1; x < s. length(); x++) { if (s. char. At(x) == '+‘ || s. char. At(x) == ‘-’) data. push(new Character(s. char. At(x))); else { //else it is a number

operator = (Character) data. pop(); a = ((Integer)data. pop()). int. Value(); if (operator ==

operator = (Character) data. pop(); a = ((Integer)data. pop()). int. Value(); if (operator == ‘+’) temp = a + char. At(x); else temp = a – char. At(x); data. push(new Integer(temp)); } System. out. println("The answer is: " + ((Integer) data. pop()). int. Value()); } // end method main }// end class

Queues Definition: A queue is a container of objects that are inserted and removed

Queues Definition: A queue is a container of objects that are inserted and removed according to the first-in first-out (FIFO) principle.

class Array. Queue implements Queue { private Object[] elem; private int front, rear; private

class Array. Queue implements Queue { private Object[] elem; private int front, rear; private static final int DEFAULT_LENGTH = 100; private int length; public Array. Queue() { this(DEFAULT_LENGTH); } public Array. Queue(int length) { elem = new Object[length]; front = rear = 0; length = elem. length; }

public void enqueue(Object element) throws Queue. Full. Exception { if (size()==length-1) throw new Queue.

public void enqueue(Object element) throws Queue. Full. Exception { if (size()==length-1) throw new Queue. Full. Exception(); else { elem[rear] = element; rear = (rear+1)%length; } }

public Object dequeue() throws Queue. Empty. Exception { if (is. Empty()) throw new Queue.

public Object dequeue() throws Queue. Empty. Exception { if (is. Empty()) throw new Queue. Empty. Exception(); else { Object temp = elem[front]; elem[front] = null; front = (front+1)%length; return temp; } } private boolean is. Full() { return (rear-front)==(length-1); }

public int size() { return (length-front+rear)%length; } public boolean is. Empty() { return front==rear;

public int size() { return (length-front+rear)%length; } public boolean is. Empty() { return front==rear; } public Object front() throws Queue. Empty. Exception { if (is. Empty()) throw new Queue. Empty. Exception(); else return elem[front]; } }

public class List. Queue implements Queue { protected Node front, rear; //reference to the

public class List. Queue implements Queue { protected Node front, rear; //reference to the front and rear node protected int size; // number of elements in the queue public List. Stack() { // constructs an empty queue front = null; rear = null; size = 0; } public int size() { return size; } public boolean is. Empty() { 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. set. Next(v); rear = v; size++; }

 public Object front() throws Queue. Empty. Exception { if (is. Empty()) throw new

public Object front() throws Queue. Empty. Exception { if (is. Empty()) throw new Queue. Empty. Exception("Stack is empty. "); return front. get. Element(); } public Object dequeue() throws Queue. Empty. Exception { if (is. Empty()) throw new Queue. Empty. Exception(“Queue is empty. "); Object temp = front. get. Element(); front = front. get. Next(); // 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 Queue. Empty. Exception extends Runtime. Exception { public Queue. Empty. Exception(String err) { super(err); } }

Application case: A breadth-first search traverses a tree as shown in the following Figure.

Application case: A breadth-first search traverses a tree as shown in the following Figure. Write an algorithm (not a Java program) to search a tree in the breadth-first manner by using the queue data structure to control the process.

Algorithm: create a Queue Q; put root of the tree into Q; while (Q

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 Lists

Singly Linked Lists

Class Node

Class Node

How to generate a singly linked list? class Head. Tail { Node head; Node

How to generate a singly linked list? class Head. Tail { Node head; Node tail; Head. Tail(Node x, Node y) { head = x; tail = y; } }

public class Generating. List { public static void main (String[] args) { String []

public class Generating. List { public static void main (String[] args) { String [] arr 1 = {"Winnipeg", "Vancouver", "Bejing", "Athen“ "London", "Berlin", "Toronto", "Seattle“ "Rome", "Baltimore"}; Head. Tail a = linked. List(arr 1); Node x = a. head; while (x != null) { System. out. println(x. get. Element()); x = x. get. Next(); } }

public static Head. Tail linked. List(String[] b) { Node head = null; Node tail

public static Head. Tail linked. List(String[] b) { Node head = null; Node tail = null; Node x = null; for (int i = 0; i < b. length; i++) {x = new Node(); x. set. Element(b[i]); if (i == 0 ) {x. set. Next(null); tail = x; } else x. set. Next(head); head = x; } return new Head. Tail(head, tail); } }

Doubly Linked List Difference from singly linked lists: - each node contains two links.

Doubly Linked List Difference from singly linked lists: - each node contains two links. - two extra nodes: header and trailer, which contain no elements.

Class DLNode

Class DLNode

Deques Definition: A double-ended queue is a queue that supports insertion and deletion at

Deques Definition: A double-ended queue is a queue that supports insertion and deletion at both the front and the rear of the queue. A deque D is an abstract data type that supports the following four fundamental methods:

public interface Deque { void insert. First(Object e); void insert. Last(Object e); Object remove.

public interface Deque { void insert. First(Object e); void insert. Last(Object e); Object remove. First(); Object remove. Last(); Object first(); Object last(); int size(); boolean is. Empty(); }

Class My. Deque

Class My. Deque

Vectors, Lists, and Sequences Vectors Lists Sequences Iterators

Vectors, Lists, and Sequences Vectors Lists Sequences Iterators

Vector (interface) extends impl. Array. Vector (class) extends List (interface) extends Sequence (interface) impl.

Vector (interface) extends impl. Array. Vector (class) extends List (interface) extends Sequence (interface) impl. Array. Sequence (class) impl. Node. List (class) extends Node. Sequence (class)

A Simple Array-Based Implementation Vector ADT Array rank index

A Simple Array-Based Implementation Vector ADT Array rank index

Vectors public interface Vector { public int size(); public boolean is. Empty(); public Object

Vectors public interface Vector { public int size(); public boolean is. Empty(); public Object elem. At. Rank(int r); public Object replace. At. Rank(int r, Object e); public void insert. At. Rank(int r, Object e); public Object remove. At. Rank(int r); }

public class Array. Vector implements Vector { private Object[] A; // array storing the

public class Array. Vector 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 Array. Vector() { A = new Object[capacity]; }

public Object elem. At. Rank (int r) {return a[r]; } public int size() {return

public Object elem. At. Rank (int r) {return a[r]; } public int size() {return size; } public boolean is. Empty {return size()==0; } public Object replace. At. Rank (int r, Object e) { Object temp=a[r]; a[r]=e; return temp; }

 /** Inserts an element at the given rank. */ public void insert. At.

/** Inserts an element at the given rank. */ public void insert. At. Rank(int r, Object e) throws Boundary. Violation. Exception { check. Rank(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 remove. At.

/** Removes the element stored at the given rank. */ public Object remove. At. Rank(int r) throws Boundary. Violation. Exception { check. Rank(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; }

Lists List: A container of elements that stores each element at a position and

Lists List: A container of elements that stores each element at a position and 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 a doubly linked list.

Position element(); impl. Dnode element(){…}; get. Next(){…}; get. Prev(){…}; set. Next(){…}; set. Prev(){…}; set.

Position element(); impl. Dnode element(){…}; get. Next(){…}; get. Prev(){…}; set. Next(){…}; set. Prev(){…}; set. Element(){…};

Doubly Linked List Implementation List ADT position Doubly linked list Dnode

Doubly Linked List Implementation List ADT position Doubly linked list Dnode

public interface List { /** Returns the number of elements in this list. */

public interface List { /** Returns the number of elements in this list. */ public int size(); /** Returns whether the list is empty. */ public boolean is. Empty(); /** 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 Invalid. Position. Exception, Boundary. Violation. Exception; /** Returns the node before a given node in the list. */ public Position prev(Position p) throws Invalid. Position. Exception, Boundary. Violation. Exception;

/** Inserts an element at the front of the list. */ public Position insert.

/** Inserts an element at the front of the list. */ public Position insert. First(Object e); /** Inserts and element at the back of the list. */ public Position insert. Last(Object e); /** Inserts an element after the given node in the list. */ public Position insert. After(Position p, Object e) throws Invalid. Position. Exception; /** Inserts an element before the given node in the list. */ public Position insert. Before(Position p, Object e) throws Invalid. Position. Exception; /** Removes a node from the list. */ public Object remove(Position p) throws Invalid. Position. Exception; /** Replaces the element stored at the given node. */ public Object replace(Position p, Object e) throws Invalid. Position. Exception; }

Class Node. List

Class Node. List

Sequence

Sequence

In Java, the interface for sequences is an example of multiple inheritance: interface Sequence

In Java, the interface for sequences is an example of multiple inheritance: interface Sequence extends List, Vector { public Position at. Rank( int rank ) throws Boundary. Violation. Exception; public int rank. Of( Position position ) throws Invalid. Position. Exception; } Vector interface List interface Sequence interface

Implementation of a sequence with a doubly linked list: Sequence ADT Position rank Doubly

Implementation of a sequence with a doubly linked list: Sequence ADT Position rank Doubly linked list Node at. Rank(r) rank. Of(p)

/** Implementation of a sequence by means of a doubly linked list. */ public

/** Implementation of a sequence by means of a doubly linked list. */ public class Node. Sequence extends Node. List implements Sequence { /** Checks whether the given rank is in the range [0, n - 1] */ protected void check. Rank(int r, int n) throws Boundary. Violation. Exception { if (r < 0 || r >= n) throw new Boundary. Violation. Exception("Illegal rank: " + r); }

 /** Returns the position containing the element at the given rank; * O(n)

/** Returns the position containing the element at the given rank; * O(n) time. */ public Position at. Rank (int rank) { DNode node; check. Rank(rank, size()); if (rank <= size()/2) { // scan forward from the head node = header. get. Next(); for (int i=0; i < rank; i++) node = node. get. Next(); } else { // scan backward from the tail node = trailer. get. Prev(); for (int i=1; i < size()-rank; i++) node = node. get. Prev(); } return node; }

 /** Gets an element at the given rank. */ public Object elem. At.

/** Gets an element at the given rank. */ public Object elem. At. Rank(int r) { return at. Rank(r). element(); } /** Returns the rank of a given position. */ public int rank. Of(Position p) { DNode node; node = header. get. Next(); for (int i=1; i < size(); i++) { if (p == node) return i; else node = node. get. Next(); } } }

 /** Inserts an element at the given rank; O(n) time. */ public void

/** Inserts an element at the given rank; O(n) time. */ public void insert. At. Rank (int rank, Object element) throws Boundary. Violation. Exception { check. Rank(rank, size() + 1); if (rank == size()) insert. Last(element); else { insert. Before(at. Rank(rank), element); } }

 /** Removes the element stored at the given rank; O(n) time. */ public

/** Removes the element stored at the given rank; O(n) time. */ public Object remove. At. Rank (int rank) throws Boundary. Violation. Exception { check. Rank(rank, size()); return remove(at. Rank(rank)); } public Object replace. At. Rank (int rank, object element) throws Boundadry. Violation. Exception { check. Rank(rank); return replace. Element(at. Rank(rank), element); } }

Implementing a Sequence with an Array

Implementing a Sequence with an Array

Iterator

Iterator

An implementation of the Iterator is always related to container, i. e. , a

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 Position. Iterator implements Iterator { protected List list; // the underlying list protected Position cur; // the current (next) position public Position. Iterator() { } // default constructor public Position. Iterator(List L) { // preferred constructor list = L; if (list. is. Empty()) cur = null; // list is empty else cur = list. first(); // start with the first position }

public boolean has. Next() { return (cur != null); } public Object next() throws

public boolean has. Next() { return (cur != null); } public Object next() throws No. Such. Element. Exception { if (!has. Next()) throw new No. Such. Element. Exception("No next position"); Position to. Return = cur; if (cur == list. last()) cur = null; // no positions left else cur = list. next(cur); // move cursor to the next position return to. Return; } } class No. Such. Element. Exception extends Exception { public No. Such. Element. Exception() {super(); } public No. Such. Element. Exception(String s) { super(s); } }

In a similar way, we can establish an Element. Iterator as follows. public class

In a similar way, we can establish an Element. Iterator as follows. public class Element. Iterator implements Iterator { protected List list; // the underlying list protected Position cur; // the current (next) position protected Object element. Cur; // the current (next) element public Element. Iterator() { } // default constructor public Element. Iterator(List L) { // preferred constructor list = L; if (list. is. Empty()) cur = null; // list is empty else cur = list. first(); // start with the first position }

public boolean has. Next() { return (cur != null); } public Object next() throws

public boolean has. Next() { return (cur != null); } public Object next() throws No. Such. Element. Exception { if (!has. Next()) throw new No. Such. Element. Exception("No next position"); element. Cur = cur. element(); if (cur == list. last()) cur = null; // no positions left else cur = list. next(cur); // move cursor to the next position return element. Cur; } }

Trees What is a tree? Tree ADT Basic algorithms on trees Tree traversal

Trees What is a tree? Tree ADT Basic algorithms on trees Tree traversal

What is a tree?

What is a tree?

Tree Interface – Tree ADT public interface Tree { public int size(); public Boolean

Tree Interface – Tree ADT public interface Tree { public int size(); public Boolean is. Empty(); public Element. Iterator elements(); public Position. Iterator positions(); public void swap. Elements( Position v, Position w ); public Object replace. Element( Position v, Object e ); public Position root(); public Position parent( Position v ); public Position. Iterator children( Position v ); public boolean is. Internal( Position v ); public boolean is. External( Position v ); public boolean is. Root( Position v ); }

Ispectable. Container size is. Elements Ispectable. Position. Container positions Inspectable. Tree root parent children

Ispectable. Container size is. Elements Ispectable. Position. Container positions Inspectable. Tree root parent children is. Root is. Internal is. External Position. Container swap. Element replace. Element Tree

A Binary Tree Interface in Java

A Binary Tree Interface in Java

Data Structures for Representing Trees 1. Storing a binary tree in an array 2.

Data Structures for Representing Trees 1. Storing a binary tree in an array 2. Storing a tree as a linked list

1 2 3 4 5 6 7 8 9 10 11 12 13 14

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.

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 following relationships 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) = 2 p(u) If v is the right child of the node u, then p(v) = 2 p(u) + 1.

a b e f c g d

a b e f c g d

Class BTNode

Class BTNode

Interface Hierarchy for Positions Position element(); DNode element(){…}; get. Next(){…}; get. Prev(){…}; set. Next(){…};

Interface Hierarchy for Positions Position element(); DNode element(){…}; get. Next(){…}; get. Prev(){…}; set. Next(){…}; set. Prev(){…}; set. Element(){…}; BTNnode element(){…}; get. Left(){…}; get. Right(){…}; set. Left(){…}; set. Right(){…}; get. Parent(){…} set. Element(){…};

Also see the complete program for “Linked. Binary. Tree” posted on the home page

Also see the complete program for “Linked. Binary. Tree” posted on the home page of Dr. Yangjun Chen.

Ispectable. Container size is. Elements Ispectable. Position. Container positions Position. Container swap. Element replace.

Ispectable. Container size is. Elements Ispectable. Position. Container positions Position. Container swap. Element replace. Element Tree Inspectable. Tree root, parent, children, is. Root is. Internal, is. External Inspectable. Binary. Tree left. Child, right. Child, sibling Binary. Tree imple. Linked. Binary. Tree … …, replace. Element, swap. Element, expand. External, remove. Above. External

Basic Algorithms on Trees

Basic Algorithms on Trees

Inorder tree traversal • Inorder traversal based on recursion:

Inorder tree traversal • Inorder traversal based on recursion:

inorder(T, r) inorder(T, u) inorder(T, w) if … inorder(T, u) “visit” r 6 inorder(T,

inorder(T, r) inorder(T, u) inorder(T, w) if … inorder(T, u) “visit” r 6 inorder(T, w) “visit” u 2 “visit” w If … if … inorder (T, a) inorder (T, v) 1

inorder(T, v) inorder(T, x) if … inorder(T, x) “visit” v 4 If … inorder

inorder(T, v) inorder(T, x) if … inorder(T, x) “visit” v 4 If … inorder (T, y) “visit” x if … 3

inorder(T, y) if … “visit” y if … 5 inorder(T, a) if … inorder(T,

inorder(T, y) if … “visit” y if … 5 inorder(T, a) if … inorder(T, a) inorder(T, b) “visit” a 8 If … inorder (T, c) 7 9

 • Inorder traversal based on Stack data structure Algorithm Stack-control-inorder(T, v) establish stack

• 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 v 1 and v 2 be the left and right child node of v, respectively; S. push(v 2); mark u; S. push(u*); S. push(v 1); } }

r x v* y r* a print(r) a u r* a w u* v

r x v* y r* a print(r) a u r* a w u* v r* a v* y print(x) r* a b a* c u* v print(w) r* a y print(v) r* a a* c v print(u) r* a print(b) print(y) print(a) c print(c)

Preorder Traversal • Preorder traversal based on recursion: Algorithm preorder(T, v): perform the “visit”

Preorder Traversal • Preorder traversal based on recursion: Algorithm preorder(T, v): perform the “visit” action for node v for each child w of v call preorder(T, w) v postorder(T, w) w postorder(T, v)

Algorithm binary. Preorder(T, v): perform the “visit” action for node v if v is

Algorithm binary. Preorder(T, v): perform the “visit” action for node v if v is an internal node call binary. Preorder(T, T. left. Child( v )) call binary. Preorder(T, T. right. Child( v ))

 • Preorder traversal based on Stack data structure Algorithm Preorder. On. Stack(BTree my.

• Preorder traversal based on Stack data structure Algorithm Preorder. On. Stack(BTree my. Tree, BNode v) { Establish a Stack my. Stack; my. Stack. push(v); While (my. Stack is not empty) do { u = my. Stack. pop(); visit(u); if ( u has right child) my. Stack. push(u. rightchild()); if ( u has left child) my. Stack. push(u. leftchild()); } }

Postorder Traversal • Postorder traversal based on recursion: Algorithm Postorder(T, v): for each child

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 postorder(T, w) w postorder(T, v)

 • Postorder traversal based on Stack data structure Algorithm Postorder. On. Stack(T, v):

• Postorder traversal based on Stack data structure Algorithm Postorder. On. Stack(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 u 1, …, 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 File: a b e c f

Load a tree from disk into main memory File: a b e c f g d a; b, c, d. b; e, f. e; f; c; g. g; d;

a b c a d b e e f g public class Node 1

a b c a d b e e f g public class Node 1 { String x; Node 2 y; } public class Node 2 { Node 1 x; Node 2 y; } f c g d

S. push(root, null); While (S is not empty) do { x : = S.

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 null then generate links between n and x. point_to_parent; let x 1, …, xk be the children of x; for i = k to 1 do a; b, c, d. S. push(xi, n); b; e, f. } e; stack S: node_value Point_to_parent f; c; g. g; d;

XML File <book> <title> “The Art of Programming” </title> <author> “D. Knuth” </author> <year>

XML File <book> <title> “The Art of Programming” </title> <author> “D. Knuth” </author> <year> “ 1969” </year> </book> <title> <author> “The Art of “D. Knuth” Programming” <year> “ 1969”

XML File Read a file into a character array A: < b o o

XML File Read a file into a character array A: < b o o k > < t i t l e > “ T h e A r t … stack S: node_value Point_to_node

XML File Algorithm: Scan array A; If A[i] is ‘<’ and A[i+1] is a

XML File Algorithm: 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 i = 0 a d e i = 1

Storing a tree onto disk i = 0 a d e i = 1 h i = 2 node 0 f b node 1 k file: a d e node 2 … … 0 1 2 3 4 5 6 7 8 9

Storing a tree onto disk i = 0 a d e i = 1

Storing a tree onto disk i = 0 a d e i = 1 h i = 2 node 0 f b node 1 k file: a 1 4 d 2 3 e node 2 h … … … 0 1 2 3 4 5 6 7 8 9

Storing a tree onto disk We search a tree in preorder and use a

Storing a tree onto disk We search a tree in preorder and use a special stack data structure to control the traversal in such a way the parent address can be recorded. parent address data flag to indicate left or right child

Storing a tree onto disk Algorithm storing-tree(T, v) -1 indicates that the corresponding establish

Storing a tree onto disk Algorithm storing-tree(T, v) -1 indicates that the corresponding establish stack S; i = 0; node is the root. 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 u 1, u 2 be the left and right child of u, respectively; S. push((u 2, 1, i)); S. push((u 1, 0, i)); i++; }

Merge Sort

Merge Sort

The figure here shows how the sequence is divided in the previous example. 85

The figure here shows how the sequence is divided in the previous example. 85 24 63 45 17 31 96 50 85 24 63 45 17 31 96 50 17 96 31 50

The figure here shows how the sequences are merged in the previous example. 17

The figure here shows how the sequences are merged in the previous example. 17 24 31 45 50 63 85 96 24 45 63 85 24 85 85 24 45 63 63 45 17 31 50 96 17 96 31 50

Quick Sort

Quick Sort

Java implementation (each time choose the middle element as the pivot. ) public class

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

The Set Abstract Data Type

Graphs and Graph Traversal

Graphs and Graph Traversal

Data Structure for Graphs

Data Structure for Graphs