Graphs --- the Basics

Steven J. Zeil

Old Dominion University, Dept. of Computer Science

Table of Contents

1. Definitions
1.1. Paths
2. Data Structures for Implementing Graphs

We have previously seen that compilers often represent code as trees.

For example, in this case, the expression is

Each non-leaf node represents the application of some operator to one or more subexpressions.

As good C++ programmers, we know that assignment and many other built-in parts of C++ are just more operators, so we can easily extend this idea to entire statements…

This idea can be extended to other kinds of statements as well, if we're willing to be a bit loose in our interpretation of what an operator is.

Here, for example, is a structure that might be used to represent a declaration of a variable

int x = 0;

Now, let's consider what happens just a little bit later in the compilation. We have trees for expressions and statements, and trees for declarations. All of these trees are actually joined together as subtrees of larger trees representing entire functions, classes, and other larger C++ constructs.

So, we have a tree for, say, the assignment

x = (13 + a) * (x - 1);

Now the compiler wants to know just what x actually refers to. In a typical C++ program, we may have lots of objects named x, occurring in different functions, as data members of different classes and structs, etc. Each of these x objects has a unique tree representing its declaration, but which of those declarations are this assignment statement's x's referring to?

Well, the language has various rules allowing the compiler to resolve this question, and typically once the compiler has figured out the answer, it records that answer by adding a pointer from the uses of x to the appropriate declaration, as shown here.

We add pointers

So here we have a perfectly useful data structure. But what is it?

Whatever this is, it's not a tree anymore!

This structure is an example of a graph.

The compiler must traverse this structure, generating code for each node of the tree. Processing graphs requires different kinds of algorithms from what we used for trees. Obviously we don't want to generate code multiple times for the same nodes, but this example shows that in a graph, we can reach the same nodes multiple times using different paths. Even worse, recursion and other constructs can lead to cycles (loops) in the graph, but we still need to make sure that traversals will terminate.

As another example, consider the map representing the flights offered by a small airline.

This is also a graph. It can be used in such practical problems as

In the Forum:

(no threads at this time)