How to search a specific node in a graph structure in C? - c

Not that I have time to discuss this properly to reach a conclusion and adapt my code because the phase one (of three) of a school project is in 24hrs, but at least I need to know if I did the correct decision.
I'm using linked lists and here's my structures:
typedef struct sCity {
int cityID;
char *cityName;
struct sCityLink *links;
struct sCity *next;
} nCity, *City;
typedef struct sCityLink {
City cityLinkParent;
City cityLinkTo;
struct sCityLink *next;
} nCityLink, *CityLink;
Basically, I have lots of cities and those cities are linked all together, like a graph. For instance, A, B, C, D and E they are inserted in this order into the structure City. Then, I connect A to B, C and D, B to C, D, E, C to D and E and D to E.
Now, let's say I need to go to city E. This is the last one in the linked list and it takes time to traverse the linked list all the way. Maybe not on this example with 5 cities but in the real app I'm supposed to support like 10,000 cities at least. But the shortest route is from A (which is the starting point) from C to E (or it could be A-D-E or A-B-E, doesn't matter).
Do my structures allow me to find the shortest route from A to E without traversing the whole linked list one by one? If not, what I'm doing wrong?
If yes, how can I do that? I don't have a clue how can I find such a path...

There are two separate issues - one, you probably want to find a City pointer for a city ID (eg. "E"). You cannot do that in less than linear time with your structures; if you need it faster, use a hashtable or binary search tree.
Two, you want to find a path between two given cities. For this you'd probably use the BFS algorithm, for which your data structure is just fine. Note that BFS takes O(V+E) time where V and E are the vertex and edge count of the induced subgraph whose vertices' distance from the start vertex is not greater than the distance from start to end vertex. Which means in the worst case, it takes more time than traversing the list of cities.

You can use an algorithm called Breadth-First Search (BFS). You need to implement a "color" flag on each node to use it. Note that this algorithm only works if your edges are unweighted -- if 2 cities are connected, then they are of equal distance.
If the edges have weight (which it does not look like they do), you need something like Dijkstra's Algorithm or A*.

Related

Traversing directed graph breadth first with vertexes having longest paths first

Given a directed graph of dependencies, I want to traverse this graph from the root node level by level (that is breadth first) however taking the nodes on each level in a certain order. In my case, the order of nodes on each level must be sorted after their depth taking deepest nodes first.
Simple example:
A -> B
B -> C
A -> C
Starting at node A, I want the travseral to give me order A, B, C (and not A, C, B because B has C under it). No cycles.
Any hints much appreciated. I'm new to the excellent JGraphT library so may have overlooked some simple solution.
One way to solve this problem would be to:
Find all paths from root (A)
Sort the paths according to length (tallest first)
For each path travers the nodes and put node in right place in a list.
The right place is determined by a linear search of list at first position where new node is not found in the list
But maybe there is already some built in algorithm, so I don't have to encode the above? :-)
It sounds like you can simply use a topological sort of your graph. In jgrapht you can accomplish this with the TopologicalOrderIterator

How to make an array of arrays in C?

Is it possible to make an array of arrays in C?
More specifically, is it possible to make a list (array) of adjacency lists (arrays)?
And if so, how?
My textbook uses a list of adjacency lists for Dijkstra's algorithm (and in a lot of other algorithms) instead of using an adjacency matrix, though the book is in pseudocode and even then it makes no reference whatsoever on how to implement the list...
Supposedly, list of adjacency lists are more efficient in a lot of algorithms than adjacency matrices. I thought of using linked lists, but AFAIK it would be the same as using an adjacency matrix, so it would make no point at all to implement it this way...
Did you mean a multidimensional array?
int mdarr[10][20];
Is it possible to make an array of arrays in C?
Yes.
More specifically, is it possible to make a list (array) of adjacency
lists (arrays)?
Yes, it can be implemented using a linked list (or array in your case) of linked lists.
And if so, how?
One list (or array) could maintain nodes, each of which will point to the actual adjacency list as well as contain information about the current point of the graph. This can be implemented creating a struct with the relevant data (one information field and one next pointer, and one pointer to adjacency list)
The second list will be the actual adjacency list of each node. It will be pointed to by the corresponding nodes of the first list. It will contain nodes, each of which will be a graph point connected to the corresponding point in the initial list. It can be implemented similarly, by creating a struct having the relevant data (one field for the next pointer, and one information field).
This is not a multi-dimensional array but is completely different. This will use less space than an adjacency matrix, if your graph is sparse.
As an example, lets take A, B, C, D to be the nodes of an undirected graph such that A is connected to B and C.
Then the lists will be like this :
A -> B -> C -> D
| | |
B A A
|
C
Did you mean a three-dimensional array?.
Yo define an adjacency matrix like this aMat[3][3] (graph of three elements).
So, you could define, for example 4 graphs of three elements each like this: aMatMulti[4][3][3].

kruskal implement in c adjacency list or adjacency matrix

I am reading the textbook Introduction to Algorithms aka CLRS, I want to implement the mst using kruskal algorithm in c, what I want to know is, which graph implementation should I use, the adjacency list or adjacency matrix? I think it is not intuitive to sort the edges when using the adjacency list, the represent of edge in adjacency list is confusing when define the adjacency list like this:
typedef struct tagAdjList
{
int endPointIndex;
struct tagAdjList * next;
}AdjNode, *AdjList, *AdjPNode;
when sorting the edges, I want to using an array of pointers to pointing to the nodes defined above, the question is the struct defined above can't find the start point of the edge but the end point. So I changed the struct like this:
typedef struct tagAdjList
{
int startPointIndex;
int endPointIndex;
struct tagAdjList * next;
}AdjNode, *AdjList, *AdjPNode;
what I want to ask is: is OK to define the adjancency list like this? or there are better practice? or I just should use the adjacency matrix(since I saw some people implement the kruskal using the matrix when searching the Internet)? why?
Sorry for the poor English. any help will be appreciated.
For the purposes of implementing Kruskal's algorithm it does not matter in what way you represent your graph, because you never sort edges that belong to a vertex. Rather, you put all edges into a single array, and then sort that array in ascending order.
The representation of your graph does not matter, as long as you can walk it, and collect all edges into a single array (first, you walk the graph to count the edges, then allocate an array of sufficient capacity, and finally you walk the graph again, putting pointers to the edges into the dynamically allocated array).
Once the pointers to your edges are in an array, sort the array (for example, with qsort) and run Kruskal's algorithm. You will need to implement Disjoint Sets in order to merge forests efficiently; as long as you have no trouble implementing linked lists, implementing disjoint sets should give you absolutely no trouble.
The first structure you mention is the standard representation of (sparse) graphs. Note that you will need a weight field as well. I would keep this as the permanent representation of the graph, as long as it is sparse at least.
Yes, for Kruskal's you'll need a structure more like the latter as you need an explicit source vertex. I would define a different structure that doesn't have the linked list just for Kruskal's:
int startPointIndex;
int endPointIndex;
int weight;
You'll allocate an array of those structures, fill them in with the edges from the graph, sort them by weight, then scan through them doing disjoint set unions of the endpoints.

C programming language Graph Structure

I have some trouble with building Graph Structure. I know how to build a simply linked list and doubly too. But I want to construct a graph structure like in this site (the pic. output) http://www.cs.sunysb.edu/~algorith/files/graph-data-structures.shtml
You have three common solutions:
an adjacency matrix (in which you store a matrix of N*N where N is the number of vertices and in matrix[x][y] you will store a value if x has an edge to y, 0 otherwise
an edge list, in which you just keep a long lists of edges so that if the couple (x,y) is in the list, then there is an edge from x to y
an adjacency list, in which you have a list of vertices and every vertex x has a list of edges to the nodes for which x has an edge to.
Every different approach is good or bad according to
space required
computational complexity related to specific operations more than other
So according to what you need to do with the graph you could choose any of those. If you want to know specific characteristic of the above possible implementations take a look at my answer to another SO question.

Writing top 10 scores to file

I'm writing a blackjack program and would like to be able to write the top scores to a file. Obviously the first few times the program is run it will populate the high score list with every score, after which I'd like only scores that are greater than the number 10 score to be added, and the initial number 10 score (now number 11) to be deleted. I've been thinking of using a linked list like this:
struct highScore
{
char name;
int score;
highScore *next;
};
My knowledge of linked lists is pretty basic so I intend on doing my research before I can actually code it.
I'm wondering if I'm overcomplicating this and if there's a simpler way to get the job done, or am I on the right track here?
I do not think that linked list is best approach. Do not take me wrong, but linked list is used to add and to remove at random position, most commonly at beginning or end. Problem whit linked list is that it has same inefficiency to find element as ordinary array, becuase it has to check each element until it finds one.
I think that using array will make your program having same efficiency and less complicated code.
Comparing both data structures (linked list and array):
Finding element is in both case proportional to length in average.
Inserting element at end is constant in both structures.
Linked lists are efficient to add element at any position, but position has to be found, so this compensates whit problem that array has, where you have to move right elements by one position on right.
I think that something like
typedef struct
{
int score;
char name[51]; //name should hold 50 chars and null
} highScore;
highScore scores[10]; // voilla 10 scores
//or if you need little bit of complications
//and more speed when moving array during insertion
highScore * scorespointer[10]; //array of 10 pointers on score
Will make simple solution whit same efficiency as linked list.
If you implement your structure as linked list you will not be able to serialize this directly in file, because you can store only name and score, but not pointer on next highScore. Pointers can not be stored in file, because they are dynamical allocated and are valid only during program lifetime.
If you are disappointed whit this solution, you can check heap and tree for ultimate efficency for more than few (like in your case) scores.
I think your approach looks good. Using a linked list for this makes sense, or even a queue (which can be implemented using a linked list).
A linked list is certainly a good way to do this. It keeps the data related to a score together and with some basic bookkeeping you can keep it up to date. When you keep it sorted, you can easily insert new scores at the right place and remove too low scores from the linked list.
An alternative is to maintain two arrays with 10 elements each, one for the names and one for the scores but this has several drawbacks:
If you're going to add more information later, you'll need another array and more importantly,
Any operation that you do on one array also needs to be done on the other which can cause trouble later on (bugs).
So, in short, your solution looks good.
Just to understand your requirement:
the program runs and a score is obtained
you read the scores file into a list and check the new score against the old top scores
you modify the list and write it back to the file
program exits.
If this is correct, then a linked list seems like overkill. An array would do the job fine. Read each entry from the file into the array, inserting the new score as you go. You could forego the array altogether and just write out to a file each score you read in, again inserting the new score as you go. Then rename the files (scores.txt becomes scores.bak, scores.new becomes scores.txt) - this way you get a backup of the scores file too. Note that your file is best written as text (ie. not binary).
As has been stated, your structure will not compile as pure C code. If you want to write in C as opposed to C++, you should make your compiler reject C++. How you do that depends upon your platform, but it might just be a matter of naming the file scores.c instead of scores.cpp.

Resources