Travelling through maze recursively & inserting nodes in all spaces - c

I have a maze program that takes 5 mazes and inserts nodes into the outlines of those mazes. I'm creating a directed graph that can represent the freespaces in the maze by placing a graph node at each free space grid location and connecting them together with edges.
I'm stuck on a function that actually involves filling the freespaces of the maze with nodes and connecting them. The nodes don't need to follow a certain pattern at the moment, they just need to fill up all empty space like the images shown below. My program right now just displays a blank maze with no nodes.
I'm given a set of guidelines which are commented in computeGraph(), but I am really stumped as to how I would trace a maze recursively. My code under the function is gibberish and doesn't do anything. I'm really lost as to what to do and would appreciate some help or guidance. I'm not asking for anything else in the program to be touched, only computeGraph() as it's my problem right now. Also I should mention that I'm not allowed to create any extra arrays for this task which makes the problem even harder.
If the comments are not enough, basically the function's purpose is to allocate space for the new graph and return it. Each node of the graph must be dynamically-allocated and connected by setting the appropriate Node up/down/left/right pointers.
Thanks again for any help. I can post the full code/all the files for the program if required, but I just posted only what I thought was necessary for this particular problem.
maze.c:
#include <stdio.h>
#include <stdlib.h>
#include "graphSet.h"
#include "mazeDisplay.h"
// Compute the graph for the given maze and add it to the given graph set.
Graph *computeGraph(char maze[HEIGHT][WIDTH]) {
// Create the initially-empty graph
int i, j;
for(i = 0; i < HEIGHT; i++){
for(j = 0; j < WIDTH; j++){
maze[i][j] = '\0';
}
}
// Find a starting node, then trace out the maze recursively. A starting node can be
// found by searching from top to bottom, left to right, for a non-wall maze location.
// You MUST NOT hard-code this start location ... it must be determined by your code.
Node *newNode;
Node *currNode;
Node *prevNode;
currNode = *rootNode;
currPos[0][0];
prevNode = NULL;
while(currNode != NULL){
if(currPos[0][0] == maze[x][y]){
break;
}
prevNode = currNode;
}
newNode = malloc(sizeof(Node));
if(prevNode->up != 1){
prevNode->up = newNode;
}else if(prevNode->down != 1){
prevNode->down = newNode;
}else if(prevNode->left != 1){
prevNode->left = newNode;
}else if(prevNode->right != 1){
prevNode->right = newNode;
}
// To trace out the maze recursively, you will likely want to create a recursive
// procedure that is called by this one. It should take parameters to indicate
// the location in the maze to start tracing from, the maze itself and also the node
// that led to this node (i.e., the previous one in the tree that led here). If you
// start with the root node, then the previous node should be NULL.
//
// As you go through the maze, make sure to mark off maze locations that you have
// visited (perhaps by putting a '2' character at that location) so that you do not
// go back to that location again and end up with infinite recursion. So you can
// stop the recursion when you reach a wall (i.e., a '1' character in the maze) or a
// '2' character. A '0' character means that it is a free space that you just arrived
// at for the first time. Make sure to check recursively in all directions. In my
// solutions (shown on the assignment), I used an ordering of up/down/left/right. So
// if you want solutions to look like mine, you should follow that ordering as well.
//
// As you traverse the maze, make sure to connect the previous node to the current one.
// You'll have to check which direction you can from (i.e., x and y values) so that
// you know whether it is the up/down/left or right pointer to set.
}
// This procedure must clean up graph by removing all nodes in which the previous and
// next nodes have the same x or y value as it.
void cleanUpGraph(Node *n, Node *previousNode) {
}
// This is where it all begins
int main() {
char mazes[5][HEIGHT][WIDTH] = {
{"111111111111111111111",
"100000001000100000001",
"101111111010111011111",
"100000000010000010001",
"101110111111101110111",
"100010001000000000001",
"111011111111111110111",
"101010001000100000001",
"101110111011101011101",
"100010000000001010001",
"101010111011111111111",
"101000001000100000001",
"101111111110101111101",
"100010100000100000101",
"111110101110101111101",
"100010001000000010101",
"101010111111111010111",
"101010001000000010001",
"101111111010111011101",
"100000000010001000001",
"111111111111111111111"},
{"111111111111111111111",
"100000000000000000001",
"101111111111111111111",
"100000000000000000001",
"101111111111111111111",
"100000000000000000001",
"111111111111111111101",
"100000000000000000001",
"101111111111111111111",
"100000000000000000001",
"111111111111111111101",
"100000000000000000001",
"101111111111111111111",
"101111111111111111101",
"101111111111111111101",
"101000100010001000101",
"101010101010101010101",
"101010101010101010101",
"101010101010101010101",
"100010001000100010001",
"111111111111111111111"},
{"111111111111111111111",
"100000000000000000001",
"101010101010101010101",
"100000000000000000001",
"101110111011101110111",
"100000000000000000001",
"101111101111101111101",
"100000000000000000001",
"101111111001111111101",
"100000000000000000001",
"101111111111111111101",
"100111111111111111001",
"100011111111111110001",
"100001111111111100001",
"100000111111111000001",
"100000011111110000001",
"100000001111100000001",
"100000000111000000001",
"100000000010000000001",
"100000000000000000001",
"111111111111111111111"},
{"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111110111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111"},
{"111111111111111111111",
"111100000000000000001",
"111000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"111111111111111111111"}};
// Open a display window
openDisplayWindow();
// Allocate a GraphSet to store the graphs for each maze
GraphSet *gSet;
// Compute the graphs for each maze and add them to a Graph Set
for (int i=0; i<5; i++) {
Graph *g = computeGraph(mazes[i]);
// Add g to gSet properly
// ...
}
// Show the graphs
Graph *g; // ... set this to the first graph in gSet ...
for (int i=0; i<5; i++) {
drawMaze(mazes[i]); // Draw the maze
// drawGraph(g->rootNode); // Draw the graph
getchar(); // Wait for user to press enter
// cleanUpGraph(g->rootNode, NULL); // Clean up the graph
// drawMaze(mazes[i]);
// drawGraph(g->rootNode);
// ... get the next graph in the set ...
// ... INSERT A LINE OF CODE HERE ...
getchar(); // Wait again for the user to press ENTER before going on to the next maze
}
// Free up all allocated memory
// ...
// Close the display window
closeDisplayWindow();
}
graphSet.h:
// This struct represents a single intersection/Node in a maze. It keeps track
// of the x(i.e., column) and y (i.e. row) of the intersection in the maze
// as well as the Nodes in all 4 directions around it). NULL is used to
// indicate that no Node is beside it in a particular direction.
typedef struct nd {
int x;
int y;
struct nd *up;
struct nd *down;
struct nd *left;
struct nd *right;
} Node;
// This struct represents a single maze graph
typedef struct gr {
Node *rootNode;
struct gr *nextGraph;
} Graph;
// This struct represents a set of maze graphs
typedef struct {
Graph *firstGraph;
Graph *lastGraph;
} GraphSet;

The mazes as shown can be interpreted as a series of single-square rooms, which are connected by "doors" whereever two empty squares touch.
That way, this problem is simpliefied to an undirected graph of identical rooms.
I just repeat this, though I am convinced that you already arrived at this view yourself.
The goal is hence to visit each room and know when all have been visited.
Then the goal to malloc for each empty space (but not more than once) can be achieved by mallocing only when visiting a square for the first time, which can be guaranteed by using a flag set when visiting a new room, at the same time when mallocing. These flags can be "added" to each room, by mirroring the data structure which stores the "empty"/"wall" info.
The remaining goal is to make sure that each empty square gets visited, as long as it CAN be visited. For that I propose to use the "left hand rule" for maze visiting: "Always leave a room through the exit to left of where you entered." It is basically a traversal for directed graphs, similar to the most widely used traversal for binary trees. I.e. for possible exits to North, East, Sout, West, North, always exit through the "next" exit in this order.
The lefthand rule is only for directed graphs without "loops"/"circles", with is of course NOT applicable to your kind of mazes.
To solve that problem, use the ariadne thread. It is a path through all the already visited rooms. Note that you need a path data structure, a flag for each room is not sufficient to keep track of the ariadne thread.
If while using the left-hand-rule you enter a room you have already visited (i.e. it is already found in the path you travelled), then do not enter it and select the next exit, as if the first selected exit does not exist. Imagine the "door" to be locked there. When you are out of exits to unvisited rooms, go back along the ariadne thread until you again find yet unused exits to yet unvisited rooms.
When you are forced to go back to the first room you visited, then you have visited all rooms.
As described above, you ariadne thread grows longer while returning during the search for unvisited rooms. For more efficient implementation, you can shorten the ariadne thread on your way back and rely on the mirrored flags for "already malloced". I.e. the room to go back to is found in the previous entry of the path, while the decision whether to enter a room can be based on the flag.
In your sample solutions, imagine the red dots to be the flags, while the blue lines represent the (unshortened) ariadne thread, which is everywhere double (on the way in and the way out).
Take pen and paper (with an empty version of the maze).
Play the person walking through the maze, draw the blue ariadne thread. Like that it will be possible to follow the description I provided.
Then program it.

Related

c - creating a makefile causes error "expected ‘;’, ‘,’ or ‘)’ before ‘*’ token"

So I'm creating a maze game program but in order for me to be able to actually start coding, I'm supposed to create a makefile that compiles and links the mazes.c and mazeDisplay.c files into an executable called mazes. The makefile should allow make all and make clean commands to work properly, and I'm also supposed to include something called the -lX11 library in order for the code to link properly.
I've been trying to compile my program and create my makefile for the past 2 days, and I can't get anything to work. My compiler doesn't seem to recognize what a pointer is. I keep getting the error "error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token Graph *computeGraph(char maze[HEIGHT][WIDTH]) {" and I'm starting to get really anxious as my assignment is due soon and I'm unable to even compile the starting program files which I need to start my task because of this makefile issue. Please, any help would be appreciated. I've been losing my mind trying to do a simple task and I just can't figure out what the problem is. Is there something wrong with my makefile instructions?
Makefile:
GCC = gcc
all: mazes.o mazeDisplay.o
$(GCC) -o mazes mazes.o mazeDisplay.o -lX11
mazes.o: mazes.c mazeDisplay.h
$(GCC) -c mazes.c
mazeDisplay.o: mazeDisplay.c mazeDisplay.h
$(GCC) -c mazeDisplay.c
clean:
rm -f *.o mazes
CODE:
mazes.c:
#include <stdio.h>
#include <stdlib.h>
#include "graphSet.h"
#include "mazeDisplay.h"
// Compute the graph for the given maze and add it to the given graph set.
Graph *computeGraph(char maze[HEIGHT][WIDTH]) {
// Create the initially-empty graph
// Find a starting node, then trace out the maze recursively. A starting node can be
// found by searching from top to bottom, left to right, for a non-wall maze location.
// You MUST NOT hard-code this start location ... it must be determined by your code.
// To trace out the maze recursively, you will likely want to create a recursive
// procedure that is called by this one. It should take parameters to indicate
// the location in the maze to start tracing from, the maze itself and also the node
// that led to this node (i.e., the previous one in the tree that led here). If you
// start with the root node, then the previous node should be NULL.
//
// As you go through the maze, make sure to mark off maze locations that you have
// visited (perhaps by putting a '2' character at that location) so that you do not
// go back to that location again and end up with infinite recursion. So you can
// stop the recursion when you reach a wall (i.e., a '0' character in the maze) or a
// '2' character. A '1' character means that it is a free space that you just arrived
// at for the first time. Make sure to check recursively in all directions. In my
// solutions (shown on the assignment), I used an ordering of up/down/left/right. So
// if you want solutions to look like mine, you should follow that ordering as well.
//
// As you traverse the maze, make sure to connect the previous node to the current one.
// You'll have to check which direction you can from (i.e., x and y values) so that
// you know whether it is the up/down/left or right pointer to set.
// You need not do this recursively, but it will lkely be a lot harder to do it non-
// recursively.
return NULL; // Remove this line when you write your code
}
// This procedure must clean up graph by removing all nodes in which the previous and
// next nodes have the same x or y value as it.
void cleanUpGraph(Node *n, Node *previousNode) {
}
// This is where it all begins
int main() {
char mazes[5][HEIGHT][WIDTH] = {
{"111111111111111111111",
"100000001000100000001",
"101111111010111011111",
"100000000010000010001",
"101110111111101110111",
"100010001000000000001",
"111011111111111110111",
"101010001000100000001",
"101110111011101011101",
"100010000000001010001",
"101010111011111111111",
"101000001000100000001",
"101111111110101111101",
"100010100000100000101",
"111110101110101111101",
"100010001000000010101",
"101010111111111010111",
"101010001000000010001",
"101111111010111011101",
"100000000010001000001",
"111111111111111111111"},
{"111111111111111111111",
"100000000000000000001",
"101111111111111111111",
"100000000000000000001",
"101111111111111111111",
"100000000000000000001",
"111111111111111111101",
"100000000000000000001",
"101111111111111111111",
"100000000000000000001",
"111111111111111111101",
"100000000000000000001",
"101111111111111111111",
"101111111111111111101",
"101111111111111111101",
"101000100010001000101",
"101010101010101010101",
"101010101010101010101",
"101010101010101010101",
"100010001000100010001",
"111111111111111111111"},
{"111111111111111111111",
"100000000000000000001",
"101010101010101010101",
"100000000000000000001",
"101110111011101110111",
"100000000000000000001",
"101111101111101111101",
"100000000000000000001",
"101111111001111111101",
"100000000000000000001",
"101111111111111111101",
"100111111111111111001",
"100011111111111110001",
"100001111111111100001",
"100000111111111000001",
"100000011111110000001",
"100000001111100000001",
"100000000111000000001",
"100000000010000000001",
"100000000000000000001",
"111111111111111111111"},
{"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111110111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111",
"111111111111111111111"},
{"111111111111111111111",
"111100000000000000001",
"111000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"100000000000000000001",
"111111111111111111111"}};
// Open a display window
openDisplayWindow();
// Allocate a GraphSet to store the graphs for each maze
GraphSet *gSet;
// Compute the graphs for each maze and add them to a Graph Set
for (int i=0; i<5; i++) {
Graph *g = computeGraph(mazes[i]);
// Add g to gSet properly
// ...
}
// Show the graphs
Graph *g; // ... set this to the first graph in gSet ...
for (int i=0; i<5; i++) {
drawMaze(mazes[i]); // Draw the maze
// drawGraph(g->rootNode); // Draw the graph
getchar(); // Wait for user to press enter
// cleanUpGraph(g->rootNode, NULL); // Clean up the graph
// drawMaze(mazes[i]);
// drawGraph(g->rootNode);
// ... get the next graph in the set ...
// ... INSERT A LINE OF CODE HERE ...
getchar(); // Wait again for the user to press ENTER before going on to the next maze
}
// Free up all allocated memory
// ...
// Close the display window
closeDisplayWindow();
}
mazeDisplay.c:
#include <stdio.h>
#include <X11/Xlib.h>
#include <unistd.h>
#include "graphSet.h"
#include "mazeDisplay.h"
#define SCALE 25
// These are display-related variables
Display *display;
Window win;
GC gc;
// Draw the Maze on the window.
void drawMaze(char grid[WIDTH][HEIGHT]) {
// First erase background
XSetForeground(display, gc, 0xFFFFFF);
XFillRectangle(display, win, gc, 0, 0, 750, 750);
XFlush(display);
// Draw the grid maze
for (int y=0; y<WIDTH; y++) {
for (int x=0; x<HEIGHT; x++) {
if (grid[y][x] == '1')
XSetForeground(display, gc, 0x333333);
else
XSetForeground(display, gc, 0xFFFFFF);
XFillRectangle(display, win, gc, x*SCALE, y*SCALE, SCALE, SCALE);
}
}
XFlush(display);
}
// Draws an edge with the given color (e.g., 0x0000FF is blue)
// from cell (c1, r1) to cell (c2, r2) of the maze
void drawEdgeWithColor(int c1, int r1, int c2, int r2, int color) {
XSetForeground(display, gc, color);
XDrawLine(display, win, gc, c1*SCALE + SCALE/2, r1*SCALE + SCALE/2, c2*SCALE + SCALE/2, r2*SCALE + SCALE/2);
XFlush(display);
}
// Draws a node with the given color (e.g., 0x0000FF is blue)
// centered at the given cell (c1, r1) of the maze.
void drawNodeWithColor(int c1, int r1, int color) {
XSetForeground(display, gc, color);
XFillArc(display, win, gc,
c1*SCALE-SCALE/4 + SCALE/2,
r1*SCALE-SCALE/4 + SCALE/2,
11, 11, 0, 360*64);
XFlush(display);
}
// Draw a single graph starting at the given root node n.
void drawGraph(Node *n) {
// Quit recursion if there are no Nodes
if (n == NULL)
return;
// Recursively draw in each direction. Draw the edges before the recursive call so that
// vertices are drawn on top of the edges
if (n->up != NULL) {
drawEdgeWithColor(n->x, n->y, n->up->x, n->up->y, 0x0000FF);
drawGraph(n->up);
}
if (n->down != NULL) {
drawEdgeWithColor(n->x, n->y, n->down->x, n->down->y, 0x0000FF);
drawGraph(n->down);
}
if (n->left != NULL) {
drawEdgeWithColor(n->x, n->y, n->left->x, n->left->y, 0x0000FF);
drawGraph(n->left);
}
if (n->right != NULL) {
drawEdgeWithColor(n->x, n->y, n->right->x, n->right->y, 0x0000FF);
drawGraph(n->right);
}
drawNodeWithColor(n->x, n->y, 0xFF0000);
}
// Open a display window
int openDisplayWindow() {
// Opens connection to X server
display = XOpenDisplay(NULL);
// Create a simple window
win = XCreateSimpleWindow(display, // our connection to server
RootWindow(display, 0), // parent window (none in this example)
0, 0, // x,y (w.r.t. parent ... ignored here)
WIDTH*25,HEIGHT*25, // width, height
0, // border width
0x000000, // border color (ignored in this example)
0xFFFFFF); // background color = WHITE
// Set the name of the window
XStoreName(display, win, "Maze Displayer");
// Get the graphics context
gc = XCreateGC(display, win, 0, NULL);
// Make it visible
XMapWindow(display, win);
XFlush(display);
usleep(20000); // sleep for 20 milliseconds.
}
// Close the display window
int closeDisplayWindow() {
// Clean up and close the window
XFreeGC(display, gc);
XUnmapWindow(display, win);
XDestroyWindow(display, win);
XCloseDisplay(display);
}
mazeDisplay.h:
#include <X11/Xlib.h>
#define WIDTH 21
#define HEIGHT 21
// Draw the maze on the window.
extern void drawMaze(char maze[WIDTH][HEIGHT]);
// Draw the graph on the window.
extern void drawGraph(Node *firstNodeOfGraph);
// Open a display window
extern int openDisplayWindow();
// Close a display window
extern int closeDisplayWindow();
// Draws a node with the given color (e.g., 0x0000FF is blue)
// centered at the given cell (c1, r1) of the maze.
extern void drawNodeWithColor(int c1, int r1, int color);
// Draws an edge with the given color (e.g., 0x0000FF is blue)
// from cell (c1, r1) to cell (c2, r2) of the maze
extern void drawEdgeWithColor(int c1, int r1, int c2, int r2, int color);
graphSet.h:
// This struct represents a single intersection/Node in a maze. It keeps track
// of the x(i.e., column) and y (i.e. row) of the intersection in the maze
// as well as the Nodes in all 4 directions around it). NULL is used to
// indicate that no Node is beside it in a particular direction.
typedef struct nd {
int x;
int y;
struct nd *up;
struct nd *down;
struct nd *left;
struct nd *right;
} Node;
// This struct represents a single maze graph
typedef struct gr {
Node *rootNode;
struct gr *nextGraph;
} Graph;
// This struct represents a set of maze graphs
typedef struct {
Graph *firstGraph;
Graph *lastGraph;
} GraphSet;
Log for make:
student#COMP2401-F19:~/Desktop/Mazes$ make
gcc -c mazes.c
mazes.c:11:7: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token
Graph *computeGraph(char maze[HEIGHT][WIDTH]) {
makefile:7: recipe for target 'mazes' failed
make: *** [mazes.o] Error 1
Looking at your pastebin your files that are being compiled are corrupted and not the same as the ones you've show us here.
According to the pastebin output, the mazeDisplay.h file contains this text:
extern void drawMaze(char maze[21][21]);
extern void drawGraph(Node *firstNodeOfGraph);
extern int openDisplayWindow();
extern int closeDisplayWindow();
extern void drawNodeWithColor(int c1, int r1, int color);
extern void drawEdgeWithColor(int c1, int r1, int
(comments etc. are elided by the preprocessor). Note how this file ends right in the middle of the function declaration for drawEdgeWithColor().
This is why you're seeing the syntax error you get: because the end of this last line in the mazeDisplay.h file is missing.
All I can suggest is that when you copied these files over to your virtual machine, you somehow didn't copy the entire file but missed the last few characters.
It's usually better to use something like scp to copy files. But another important lesson here is that when asking for help be sure to provide the actual files you're working with, cut and pasted from the system where you're compiling them, rather than publishing other files you think are the same... they might not be. People cannot help you if the information given to them is not accurate.
In addition to that there's also something odd in your mazes.c file; it looks like you tried to insert the contents of the graphSet.h file directly into the mazes.c file; you don't need to do that and you should definitely not include both of them.
There is something strange about the makefile:
The rule:
all: mazes.o mazeDisplay.o
$(GCC) -o mazes maze.o mazeDisplay.o -lX11
Should refer to mazes.o and not maze.o. Once I've fix that project compiles for me (Mint 19/Gcc 7.4). Running it display the maze.

Finding all possible paths from given start node to finish node

I am trying to print all paths from source to destination in a graph which uses adjacency list.It is weighted and directed. I'm trying to do it in BFS.Thanks for the help. I am getting only one path. How do I get to print other paths?
Here is BFS function:
void BFS(struct Graph *G,QUEUE *q)
{
int j,i=0;
while(!isEmpty(q))
{
int source = dequeue(q);
printf("%d ",source);
path[i]=source;
i++;
if(source==bitis)//source==end
{
for(j=0;j<i;j++)
printf("%d ",path[j]);
}
struct node *head = G->adjList[source]->next;
while(head)
{
if(G->adjList[head->source]->marked)
{
head = head->next;
continue;
}
G->adjList[head->source]->marked = 1;
enqueue(head->source,q);
head = G->adjList[head->source]->next;
}
}
}
Here is structs:
struct node{
int source;
int w;
int marked;
struct node *next;
};
struct Graph{
int V;
int E;
struct node **adjList;
};
Here is adjList:
[0]->[2]->[1]
[1]->[2]
[2]->[3]->[1]
[3]->[0]
[4]->[3]->[2]
Output:4 3 0
this graph:
5 node, 9 edge (A=0,B=1,C=2,D=3,E=4)
start node: 4 end node: 0
this graph:
5 node, 8 edge (A=0,B=1,C=2,D=3,E=4)
start node: 4 end node: 0
I want all paths between the two values entered by the user. If user enter 3 and 2
I want the output to be this way:
3 -> 0 -> 2
3 -> 0 -> 1 -> 2
I hope I could express my question. My english so bad. Thank you.
This idea may be helpful
create a queue which will store path(s) of type vector
initialise the queue with first path starting from src
Now run a loop till queue is not empty
get the frontmost path from queue
check if the lastnode of this path is destination
if true then print the path
run a loop for all the vertices connected to the
current vertex i.e. lastnode extracted from path
if the vertex is not visited in current path
a) create a new path from earlier path and
append this vertex
b) insert this new path to queue
Print all paths from a given source to a destination using BFS
bitis is not clear. If it means end node of path, path may or may not exist in directed graph and it can fail. One approach is to traverse graph starting with one node at a time and every node visited will have queued nodes giving its path. If there are n nodes graph will be traversed n times and queue will become empty n times.

Operation ignoring via pointers in AVL tree

I am building an AVL tree, using this structure:
typedef struct node* nodep;
typedef struct node {
int postal_number;
int h; /* height */
nodep left, right, parent;
} Node;
Everything is working great: rotating, searching and inserting. The problem is with deleting a node. It deletes most of the node, except for few leaves after deleting most of the tree. My delete code (the problematic part) is:
int delete_postal(nodep* t, int in_postal){
nodep to_delete;
nodep* the_parent;
to_delete = search_postal((*t), in_postal);
the_parent = &(to_delete->parent);
/** if the node we want to delete is a leave **/
if (to_delete->right == NULL && to_delete->left == NULL) {
if (to_delete == (*the_parent)->right){ /* the node we want to delete is right son */
(*the_parent)->right = to_delete->right;
else { /* the node we want to delete is left son */
(*the_parent)->left = to_delete->left;
}
I made it so (*the_parent) will be the node himself in the tree, and when debugging it stepping into the if, it acts as if it did the deletion (making the child of the node the child of the node's father - I'm not dealing with malloc right now), but it just does not do it. The father keeps on pointing to the node that I would like to delete and not to NULL.
All the rest of the first deletion (nodes and leaves) works fine with this syntax.
Does somebody know what I am missing?

Last element value appears in first and last position when printing linked list

Happy New Year.
This question arises from a project to program a game called Laby-chiffres in C. To see the game look in the third batch of games on this link: http://www.rci-jeux.com/jeux/labychiffres/laby.swf .
Context:
I am using a linked list to store the path taken by a player through a grid of numbers. The player's aim is to find a path from the departure point to the arrival point, with a given length and given total of the numbers in the path. There is a switch statement for a menu and then one to accept the direction the player wants to move in. This works as I have code that shows that the 'passage' of the player to each number is recorded correctly
Problem:
When I try to print the path (which is a requirement of the assignment - and useful for the player to see) I print the path in the correct order, except that the last element, i.e. where the player most recently moved to, is shown at the start and the end of the list.
Example: Player makes moves through positions with values as follows. Starting with the departure point value 5 -> 8 -> 4-> 1. What is printed at each stage is:
5->
8->8->
4->8->4->
1->8->4->1->
What I have tried
I have looked at several other linked list questions, but none I have seen have the same issue that I have.
I have tried changing lots of things, but to be honest now more experimentally than anything. For example, changing the empiler function to add elements at the wrong end prints the path in the wrong order (as expected) but still prints the most recently reached number twice, just both at the start of the path rather than one at the start and one at the end.
Relevant functions
The lecturer has said explicitly that the printing needs to reverse the order so these are the printing functions:
void affiche_chemin (PLATEAU jeu, PILE pile){
afficher_pile_inverse(&jeu , jeu.chemin.P_sommet);
printf("\n");
}
void afficher_pile_inverse(PLATEAU *P_jeu, ELEMENT *P_cur){
if(P_cur != NULL){
afficher_pile_inverse(P_jeu,P_cur->P_suivant);
printf("%d->",lire_valeur_a(P_jeu,&P_cur->valeur));
}
}
lire_valeur_a reads the value in the grid, which is part of the PLATEAU structure given below and read in from a text file. This appears to work so I am not including it to try to keep the question length down.
The function to add elements is :
ELEMENT* empiler(PILE *P_liste, ELEMENT *P_elt_ajoute){
P_elt_ajoute ->P_suivant = P_liste->P_sommet;
P_liste->P_sommet = P_elt_ajoute;
return P_elt_ajoute;
}
Given the lecturers comments about needing to reverse the order to print correctly I think I am adding elements at the right end of the list.
These functions initialise the path, and allocate a new ELEMENT, and are just given for reference as used in the next extract.
void initialiser_pile(PILE *P_pile){
P_pile->P_sommet = NULL;
}
ELEMENT *nouvel_element (POSITION nouvelle_valeur){
ELEMENT *P_elt;
P_elt =(ELEMENT*) malloc(sizeof(ELEMENT));
if(P_elt ) { /* NULL equivalent to false like 0 */
P_elt->valeur = nouvelle_valeur;
P_elt->P_suivant = NULL;
}
return P_elt;
}
This code sets up the path for the first time when the text file for the game is read, so it is the first time empiler is used to add an element to a path. (This extract is from a long function using fscanf multiple times to read the game text file, and seems to work correctly.)
ELEMENT *P_sommet = nouvel_element(PLAT->dep);
if (P_sommet == NULL){
printf("Erreur d'allocation\n");
return 0;
}
initialiser_pile(&PLAT->chemin);
empiler (&PLAT->chemin,P_sommet);
PLAT->longcur = 1;
PLAT->sumcur=PLAT->grille[PLAT->dep.indl][PLAT->dep.indc];
The following function is used for adding elements during the game.
int choix_indep_jeu_update(PLATEAU *jeu, POSITION *new_pos, int pas, int dir){
ELEMENT *new = nouvel_element(*new_pos);//1 Make new element
if (new == NULL) return 0;
empiler( &jeu->chemin, new );//should add new element
jeu->longcur++;
jeu->sumcur = jeu->sumcur + lire_valeur_a(jeu, new_pos);
affiche_grille(*jeu);
affiche_chemin(*jeu,jeu->chemin);
return 1;
}
Data Structures
typedef struct position_st{
int indl;//indice of ligne
int indc;//indice of colonne
}POSITION;
typedef struct element_st{
POSITION valeur;
struct element_st *P_suivant;
}ELEMENT;
typedef struct pile_st{
ELEMENT * P_sommet;
}PILE;
typedef struct plat_st{
//########## GAME FILE INFORMATION
int nl; //number of lines in grid
int nc; //number of columns in grid
POSITION dep; //position du depart: dep.indl and dep.indc
POSITION arr; //position d'arrive: arr.indl and arr.indc
int longdem; //length demanded
int sumdem; //total demanded
int ** grille; //Playing grid
//#######INFO re GAME IN PROGRESS ########
int longcur; //longueur courant
int sumcur; //totale courant
PILE chemin; //The path
}PLATEAU;
I simplified your code and it seems to be working, assuming that you want empiler() to insert elements into the front of the list, so they end up in reverse order. I added afficher_pile_inverse1() so that the last value doesn't have a "->" after it. So the error is in creating the list or there's an issue with the grid function which you did not show.
#include <stdio.h>
#include <stdlib.h>
typedef int POSITION;
typedef struct element_st{
POSITION valeur;
struct element_st *P_suivant;
}ELEMENT;
typedef struct pile_st{
ELEMENT * P_sommet;
}PILE;
void empiler(PILE *P_liste, ELEMENT *P_elt_ajoute){
P_elt_ajoute ->P_suivant = P_liste->P_sommet;
P_liste->P_sommet = P_elt_ajoute;
}
void afficher_pile_inverse1(ELEMENT *P_cur){
if(P_cur != NULL){
afficher_pile_inverse1(P_cur->P_suivant);
printf("%d->",P_cur->valeur);
}
}
void afficher_pile_inverse(ELEMENT *P_cur){
if(P_cur != NULL){
afficher_pile_inverse1(P_cur->P_suivant);
printf("%d",P_cur->valeur);
}
}
void affiche_chemin (PILE pile){
afficher_pile_inverse(pile.P_sommet);
printf("\n");
}
int main(void){
ELEMENT ae[4] = {{0,NULL},{1,NULL},{2,NULL},{3,NULL}};
PILE P_liste = {NULL};
size_t i;
for(i = 0; i < 4; i++)
empiler(&P_liste, &ae[i]);
affiche_chemin(P_liste);
return 0;
}

Traverse tree without recursion and stack in C

How to traverse each node of a tree efficiently without recursion in C (no C++)?
Suppose I have the following node structure of that tree:
struct Node
{
struct Node* next; /* sibling node linked list */
struct Node* parent; /* parent of current node */
struct Node* child; /* first child node */
}
It's not homework.
I prefer depth first.
I prefer no additional data struct needed (such as stack).
I prefer the most efficient way in term of speed (not space).
You can change or add the member of Node struct to store additional information.
If you don't want to have to store anything, and are OK with a depth-first search:
process = TRUE;
while(pNode != null) {
if(process) {
//stuff
}
if(pNode->child != null && process) {
pNode = pNode->child;
process = true;
} else if(pNode->next != null) {
pNode = pNode->next;
process = true;
} else {
pNode = pNode->parent;
process = false;
}
}
Will traverse the tree; process is to keep it from re-hitting parent nodes when it travels back up.
Generally you'll make use of a your own stack data structure which stores a list of nodes (or queue if you want a level order traversal).
You start by pushing any given starting node onto the stack. Then you enter your main loop which continues until the stack is empty. After you pop each node from the stack you push on its next and child nodes if not empty.
This looks like an exercise I did in Engineering school 25 years ago.
I think this is called the tree-envelope algorithm, since it plots the envelope of the tree.
I can't believe it is that simple. I must have made an oblivious mistake somewhere.
Any mistake regardless, I believe the enveloping strategy is correct.
If code is erroneous, just treat it as pseudo-code.
while current node exists{
go down all the way until a leaf is reached;
set current node = leaf node;
visit the node (do whatever needs to be done with the node);
get the next sibling to the current node;
if no node next to the current{
ascend the parentage trail until a higher parent has a next sibling;
}
set current node = found sibling node;
}
The code:
void traverse(Node* node){
while(node!=null){
while (node->child!=null){
node = node->child;
}
visit(node);
node = getNextParent(Node* node);
}
}
/* ascend until reaches a non-null uncle or
* grand-uncle or ... grand-grand...uncle
*/
Node* getNextParent(Node* node){
/* See if a next node exists
* Otherwise, find a parentage node
* that has a next node
*/
while(node->next==null){
node = node->parent;
/* parent node is null means
* tree traversal is completed
*/
if (node==null)
break;
}
node = node->next;
return node;
}
You can use the Pointer Reversal method. The downside is that you need to save some information inside the node, so it can't be used on a const data structure.
You'd have to store it in an iterable list. a basic list with indexes will work. Then you just go from 0 to end looking at the data.
If you want to avoid recursion you need to hold onto a reference of each object within the tree.

Resources