190 likes | 207 Views
Operations on Data Structures. Notes for Ch.9 of Bratko For CSCE 580 Sp03 Marco Valtorta. Quicksort. Delete some element X from L and split the rest of the list into two lists, Small and Big, as follows: Big contains all elements of L that are bigger than X; Small contains all other elements
E N D
Operations on Data Structures Notes for Ch.9 of Bratko For CSCE 580 Sp03 Marco Valtorta
Quicksort • Delete some element X from L and split the rest of the list into two lists, Small and Big, as follows: Big contains all elements of L that are bigger than X; Small contains all other elements • Sort Small obtaining SortedSmall • Sort Big obtaining SortedBig • The whole sorted list is the concatenation of SortedSmall, [X], and SortedBig • fig9_2.pl
Quicksort with Difference Lists • quicksort1 in fig9_3.pl (with split in fig9_2.pl) • concat( A1-Z1,Z1-Z2,A1-Z2) • Example: unify • concat( A1-Z1,Z1-Z2,A1-Z2) • concat( [a,b,c|T1]-T1,[d,e|T2]-T2,L) • Obtain: • A1 = [a,b,c|T1] • T1 = Z1 = [d,e|T2] • Z2 = T2 • L = [a,b,c,d,e|T2]-T2
Mergesort • ch9_1.pl • mergesort is faster than quicksort on large arrays, on average, at least in some Prolog implementations • mergesort has much better worst-case behavior than quicksort
Binary Trees • Binary trees • Binary search trees • All nodes in the left subtree are less than the root • All nodes in the right subtree are greater than the root • Good implementation of dictionaries (if balanced)
Binary Tree Representation • Use an atom to represent the empty tree • nil • Use a special functor to indicate a non-empty tree • t( L,X,R) • Where X is the root, L is the left subtree and R is the right subtree • E.g., • t( t( nil,b,nil),a,t( t( nil,d,nil),c,nil)) a c b d
Binary Search Trees • Search in BST: • in( X,S): fig9_7.pl • Inserting a leaf in the BST: • addleaf( Tree,X,NewTree): fig9_10.pl • Deleting from the BST • del( Tree,X,NewTree): fig9_13.pl • Inserting anywhere in the BST • add( Tree,X,NewTree): fig9_15.pl • Reversible: can be used to delete! • Use the program of fig9_17.pl to display
Adding a Leaf • addleaf( D, X, D1)—adding X as a leaf to D gives D1 • Adding X to the empty tree is t( nil,X,nil) • If X is the root of D then D1 = D (no duplicates) • If the root of D is greater than X than add X into the left subtree of D; if the root of D is less than X, then insert into the right subtree of D • fig9_10.pl
Deleting from a BST • Reversing addleaf does not work • addleaf only adds at the leaf level • addleaf does not correctly remove an internal node • We take the minimum item in the right subtree of the node to be deleted and replace the deleted node with it (cf. Fig 9.12) • delmin( Tree,Y,Tree1) if Y is the minimal (i.e., leftmost) node in Tree and Tree1 is Tree with Y deleted • del( Tree,X,NewTree): fig9_13.pl
General add and delete • To add X to a binary dictionary D, either • (1) add X at the root of D, or • (2) if the root of D is greater than X then insert X into the left subtree, else insert X into the right subtree of D • The difficult part is (1) • addroot( D,X,D1)--- add X to D obtaining D1 • See Fig. 9.14
Figure 9.14 • L1 and L2 must be BSTs • The union of L1 and L2 is L • All nodes in L1 are less than X, and all nodes in L2 are greater than X • addroot imposes these constraints: • If X were added as the root into L, then the subtrees of the resulting tree would be L1 and L2 • Fig9_15.pl
Representing Graphs • By edges, e.g. • connected( a,b). connected( b,c). • arc( s,t,3). arc( t,v,1). arc( u,t,2). • (weighted digraph) • Analogous to representation for FSAs • As a pair of sets, each represented by a list: • G1 = graph([a,b,c,d],[e(a,b),e(b,d),e(b,c),e(c,d)]). • G2 = digraph([s,t,u,v], [a(s,t,3),a(t,v,1),a(t,u,5),a(u,t,2),a(v,u,2)]).
Representing Graphs II • Using adjacency lists • G1 = [a->[b],b->[a,c,d],c->[b,d],d->[b,c]] • G2 = [s->[t/3],t->[u/5,v/1],u->[t/2],v->[u/2]]
Finding a (Simple) Path • path( A,Z,G,P) if • P is a (simple) path from A to Z in G • A path is defined here as a list of nodes (not a list of edges) • If A = Z then P [A], otherwise • Find a path P1 from some node Y to Z, and find a path from A to Y avoiding the nodes in P1
Simple Paths in Graphs • Program to find a simple path: fig9_20.pl • Program includes code for Hamiltonian paths • Extra parentheses are needed for not (in SWI-Prolog, as usual) • Spanning trees (fig9_22.pl, fig9_23.pl)
Paths in Weighted Graphs • Extra arguments for costs: • path( A,Z,G,P,C) • path1( A,P1,C1,G,P,C) • Program 9_21 • Extra parentheses needed for not (as usual) • Test1: any path • Test2: shortest path (very inefficient: will see better ways soon) • Test3: longest path (very inefficient)
Spanning Trees • A spanning tree of a graph G = (V,E) is a graph T = (V,E’) such that • T is connected • There is no cycle in T • E’ is a subset of E
Spanning Trees: a Procedural Solution • stree(G,T) if T is a spanning tree of G • Spread( Tree1,Tree,Graph) if • Tree is a spanning tree of Graph obtaining by adding zero or mode edges to Tree1 • Program fig9_22.pl • Program uses “edge list” representation of graphs • Program can easily be modified to implement the Jarník-Prim-Dijkstra algorithm for minimum spanning trees
Spanning Trees: a Declarative Solution • G and T are represented as lists of edges • T is a spanning tree of G if • T is a subset of G • T is a tree • T covers G, i.e. each node of G is also in T • A set of edges T is a tree if • T is connected • T has no cycle • Program fig9_23.pl • Is inefficient • Modification can compute minimum spanning trees