550 likes | 558 Views
Dynamically Extensible Data Structures. Discrete Mathematics and Its Applications Baojian Hua bjhua@ustc.edu.cn. Information Association. In processing data structures, one often need to associate information with some kind of items Examples from graphs:
E N D
Dynamically Extensible Data Structures Discrete Mathematics and Its Applications Baojian Hua bjhua@ustc.edu.cn
Information Association • In processing data structures, one often need to associate information with some kind of items • Examples from graphs: • Vertex: data, value, degree (in, out), … • Edge: weight, … • BFS: visited, distance, …, • DFS: visited, discover, finish, … • MST: tree edges, … • Dijkstra: tree edges, … • …
Several Methods • Monomorphic data in item • Polymorphic data in item • Auxiliary table (dictionary) • Dynamically extensible space in item Next, I’ll take DFS as a running example
0 0->1 0->2 0->3 1 2 3 Graph Representation: Adjacency List #include “linkedList.h” #include “graph.h” struct graph { linkedList vertices; }; typedef struct vertex *vertex; typedef struct edge *edge; struct vertex { poly data; linkedList edges; }; struct edge { vertex from; vertex to; }
DFS Algorithm dfs (vertex start, tyVisit visit) { visit (start); markVisited (start); for (each adjacent vertex u of “start”) if (not visited u) // but how do we know? dfs (u, visit); }
DFS Algorithm void dfsMain (graph g, poly start, tyVisit visit) { vertex startV = searchVertex (g, start); dfs (startV, visit); for (each vertex u in graph g) if (not visited u) // but how do we know? dfs (u, visit); }
0 0->1 0->2 0->3 1 2 3 Method #1: Monomorphic Data in Vertex #include “linkedList.h” #include “graph.h” struct graph { linkedList vertices; }; typedef struct vertex *vertex; typedef struct edge *edge; struct vertex { poly data; int visited; // a flag linkedList edges; }; struct edge { vertex from; vertex to; }
Adjacency List-based:Creating New Vertex vertex newVertex (poly data) { vertex v = malloc (sizeof (*v)); v->data = data; v->visited = 0; v->edges = newLinkedList (); return v; } data v data visited=0 edges ### /\
DFS Algorithm dfs (vertex start, tyVisit visit) { visit (start); start->visited = 1; for (each adjacent vertex u of “start”) if (0==u->visited) // Easy! :-) dfs (u, visit); }
DFS Algorithm void dfsMain (graph g, poly start, tyVisit visit) { vertex startV = searchVertex (g, start); dfs (startV, visit); for (each vertex u in graph g) if (0==u->visited) dfs (u, visit); }
Sample Graph DFS dfs (g, “a”, strOutput); a 0 b 0 c 0 d 0 e 0 f 0
Sample Graph DFS dfs (g, “a”, strOutput); print a; a 1 b 0 c 0 d 0 e 0 f 0
Sample Graph DFS dfs (g, “a”, strOutput); print a; // a choice print b; a 1 b 1 c 0 d 0 e 0 f 0
Sample Graph DFS dfs (g, “a”, strOutput); print a; // a choice print b; print e; a 1 b 1 c 0 d 0 e 1 f 0
Sample Graph DFS dfs (g, “a”, strOutput); print a; // a choice print b; print e; print d; a 1 b 1 c 0 d 1 e 1 f 0
Sample Graph DFS dfs (g, “a”, strOutput); print a; // a choice print b; print e; print d; // a choice print c; a 1 b 1 c 1 d 1 e 1 f 0
Sample Graph DFS dfs (g, “a”, strOutput); print a; // a choice print b; print e; print d; // a choice print c; print f; a 1 b 1 c 1 d 1 e 1 f 1
0 0->1 0->2 0->3 1 2 3 Method #2: Polymorphic Data in Vertex #include “linkedList.h” #include “graph.h” #include “poly.h” struct graph { linkedList vertices; }; typedef struct vertex *vertex; typedef struct edge *edge; struct vertex { poly data; poly visited; // a hook linkedList edges; }; struct edge { vertex from; vertex to;}
Adjacency List-based:Creating New Vertex vertex newVertex (poly data) { vertex v = malloc (sizeof (*v)); v->data = data; v->visited = newNat (0); v->edges = newLinkedList (); return v; } data v data 0 visited edges ### /\
DFS Algorithm dfs (vertex start, tyVisit visit) { visit (start); start->visited = newNat (1); for (each adjacent vertex u of “start”) if (natIsZero ((nat)(u->visited))) dfs (u, visit); }
DFS Algorithm void dfsMain (graph g, poly start, tyVisit visit) { vertex startV = searchVertex (g, start); dfs (startV, visit); for (each vertex u in graph g) if (natIsZero ((nat)(u->visited))) dfs (u, visit); }
Sample Graph DFS dfs (g, “a”, strOutput); a b c 0 0 0 d e f 0 0 0
A garbage! A style of functional programming! Sample Graph DFS dfs (g, “a”, strOutput); print a; a b c 0 0 0 1 d e f 0 0 0
Sample Graph DFS 1 dfs (g, “a”, strOutput); print a; // a choice print b; a b c 0 0 0 1 d e f 0 0 0 The rest is left as an exercise!
0 0->1 0->2 0->3 1 2 3 Method #3: Auxiliary Table (Memoization) #include “linkedList.h” #include “graph.h” struct graph { linkedList vertices; }; // Data structure definitions unchanged! :-) typedef struct vertex *vertex; typedef struct edge *edge; struct vertex { poly data; linkedList edges; }; struct edge { vertex from; vertex to; }
Interface for the “table” ADT // We need a table to memoize the data items that // satisfy some conditions. #ifndef TABLE_H #define TABLE_H typedef struct tableStruct *table; table newTable (); void tableInsert (table t, poly key, poly value); void tableLookup (table t, poly key); #endif // Implementation is any dictionary-like data // structure, such as linkedList, bst, hash, etc.
DFS Algorithm dfs (vertex start, tyVisit visit, table tb) { visit (start); tableInsert (tb, start, 1); for (each adjacent vertex u of “start”) if (0==tableLookup (tb, u)) dfs (u, visit, tb); }
DFS Algorithm void dfsMain (graph g, poly start, tyVisit visit) { vertex startV = searchVertex (g, start); table tb = newTable (); dfs (startV, visit, tb); for (each vertex u in graph g) if (!tableLookup (tb, u)) dfs (u, visit, tb); }
Sample Graph DFS dfs (g, “a”, strOutput); a b c d e f tb = newTable(); tb
Sample Graph DFS dfs (g, “a”, strOutput); print a; a b c d e f tableEnter(tb, “a”, newNat(1)); tb
Sample Graph DFS dfs (g, “a”, strOutput); print a; a b c d e f tableLookup (tb, “b”); // ==NULL tb
Sample Graph DFS dfs (g, “a”, strOutput); print a; // a choice print b; a b c d e f tableEnter (tb, “b”, newNat(1)); tb The rest left to you!
0 0->1 0->2 0->3 1 2 3 Method #4: Dynamically Extensible Space (DES) in Vertex #include “linkedList.h” #include “graph.h” #include “plist.h” struct graph { linkedList vertices; }; typedef struct vertex *vertex; typedef struct edge *edge; struct vertex { poly data; plist list; // a list of hooks linkedList edges; }; struct edge { vertex from; vertex to;}
What’s a “plist”? • A “plist” stands for “property list” • Property: some kind of value we care • A generalization of polymorphic data fields data v data ### plist /\ edges ### /\
What’s a “plist”? • A “plist” stands for “property list” • it’s just a list of hooks • A hook holds some property • Dynamically extensible data v1 v2 v3 v data … ### plist edges ### /\
Sample Vertex After DFS visited==1, discover==3, finish=6; // Suppose the function adding property p to // vertex v is: attach (vertex v, poly p); // which is roughly equivalent to: linkedListInsertHead (v->plist, p); “a” 1 3 6 v data ### plist /\ edges ###
Sample Vertex After DFS visited==1, discover==3, finish=6; linkedListInsertHead (v->plist, p); // the calls: attach (“a”, newNat (6)); attach (“a”, newNat (3)); attach (“a”, newNat (1)); “a” 1 3 6 v data ### plist /\ edges ###
6 1 data v data ### plist /\ edges ### /\ What’s a “plist”? data v Suppose we have two calls: attach (v, newNat (1)); // discover attach (v, newNat (6)); // finish data ### plist /\ edges ### /\
6 1 data v data ### plist /\ edges ### /\ How to Find a Property? data v Suppose we have two functions: attach (v, newNat (1)); // discover attach (v, newNat (6)); // finish // How to find v’s finish time? findPlist (v->plist);??? data ### plist /\ edges ### /\ Associate every data item with a tag (think a key).
How to Find a Property? Modifications to attach functions: k1 = attach (v, newNat (1)); // discover k2 = attach (v, newNat (6)); // finish // How to find v’s finish time? findPlist (v, k1); // return 1 findPlist (v, k2); // return 6 data v data ### plist /\ edges ### /\ k2 6 k1 1 data v data Associate every data item with a tag (think of a key). (k1, 1), (k2, 6) All ks are unique. ### plist /\ edges ### /\
Property List Interface // In file “plist.h” #ifndef PLIST_H #define PLIST_H #include “key.h” typedef struct plistStruct *plist; // essentially a list of tuples: (key, data) void plistInsert (plist list, key k, poly data); poly plistLookup (plist list, key k); #endif // Read the offered code for implementation.
0 0->1 0->2 0->3 1 2 3 Representation Revisited #include “linkedList.h” #include “graph.h” #include “plist.h” struct graph { linkedList vertices; }; typedef struct vertex *vertex; typedef struct edge *edge; struct vertex { poly data; plist list; // a list of hooks linkedList edges; }; struct edge { vertex from; vertex to;}
DFS with DES dfsMain (graph g, vertex start, tyVisit visit) { key visited = newKey (); dfs (start, visit, visited); for (each vertex u in graph g) if (!(find (u, visited)) dfs (u, visit, visited); }
DFS with DES dfs (vertex v, tyVisit visit, key visited) { visit (v); attach (v, visited, newNat (1)); for (each successor t of v) if (!(find (t, visited))) dfs (t, visit, visited); }
A Case Study: Order Statistics on Red-Black Tree
Red-Black Tree in C // In file “rbTree.h” #ifndef RED_BLACK_TREE #define RED_BLACK_TREE typedef struct rbTree *rbTree; rbTree newRbTree (); void rbTreeInsert (rbTree t, poly data); void rbTreeDelete (rbTree t, poly data); #endif
Red-Black Tree in C // In file “rbTree.c” #include “rbTree.h” struct rbTree { poly data; int color; // 0 for black, 1 for red rbTree left; rbTree right; }; // functions left to you
Rank • We want to add a “rank” field (property) to the red-black tree: • to maintain the tree vertex’s order statistics • may after the red-black tree and its operations have been implemented • after the fact • How to implement this?
Red-Black Tree with Rank // In file “rbTree.h” #ifndef RED_BLACK_TREE #define RED_BLACK_TREE typedef struct rbTree *rbTree; rbTree newRbTree (); void rbTreeInsert (rbTree t, poly data); void rbTreeDelete (rbTree t, poly data); void rbTreeInsertRank(rbTree t, poly data, key k); void rbTreeDeleteRank(rbTree t, poly data, key k); int rbTreeRank (rbTree t, poly data, key k); #endif
Red-Black Tree in C // In file “rbTree.c” #include “plist.h” #include “rbTree.h” struct rbTree { poly data; enum {RED, BLACK} color; plist plist; rbTree left; rbTree right; }; // functions left to you