Based on the BFS algorithm, I am required to write a function SD() to find the shortest distance from vertex $v$ to $w$, in an undirected graph. Vertices ranged from 1 to $|V|$. The distance is measured by the number of edges. If there is no path from $v$ to $w$, then -1 is returned. You may assume that the input graph is always valid (no duplicate or any invalid link, etc.). The function prototype is given as follows:
int SD (Graph G, int v, int w);
For the sample input and output below, my code outputs 1 instead of 2 and I don't know what I'm doing wrong, more like I don't know what I am doing at this point, help would be appreciated thank you! (Please refer to the int SD(Graph g, int v, int z) section of the code below).
#include <stdio.h>
#include <stdlib.h>
typedef struct _listnode
{
int vertex;
struct _listnode *next;
} ListNode;
typedef struct _graph{
int V;
int E;
int *visited;
int **matrix;
}Graph;
typedef ListNode QueueNode;
typedef struct _queue{
int size;
QueueNode *head;
QueueNode *tail;
} Queue;
int SD (Graph G, int v, int w);
void printGraphMatrix(Graph );
// You should not change the prototypes of these functions
void enqueue(Queue *qPtr, int item);
int dequeue(Queue *qPtr);
int getFront(Queue q);
int isEmptyQueue(Queue q);
void removeAllItemsFromQueue(Queue *qPtr);
int main()
{
Graph g;
int i,j;
printf("Enter the number of vertices:\n");
scanf("%d",&g.V);
g.E = 0;
g.matrix = (int **)malloc(g.V*sizeof(int *));
for(i=0;i<g.V;i++)
g.matrix[i] = (int *)malloc(g.V*sizeof(int));
for(i=0;i<g.V;i++)
for(j=0;j<g.V;j++)
g.matrix[i][j] = 0;
g.visited = (int *) malloc(sizeof(int)*g.V);
for(i=0;i<g.V;i++) g.visited[i] = 0;
int V1, V2;
printf("Enter two vertices which are adjacent to each other:\n");
while(scanf("%d %d",&V1,&V2)==2)
{
if(V1>0 && V1<=g.V && V2>0 && V2<=g.V)
{
g.matrix[V1-1][V2-1] = 1;
g.matrix[V2-1][V1-1] = 1;
g.E++;
}
else
break;
printf("Enter two vertices which are adjacent to each other: (press a to stop)\n");
}
scanf("%*c");
// printGraphMatrix(g);
printf("Enter two vertices for finding their shortest distance: (press a to stop)\n");
scanf("%d %d", &i, &j);
int d = SD(g,i,j);
if(d==-1)
printf("%d and %d are unconnected.\n",i,j);
else
printf("The shortest distance is %d\n",d);
return 0;
}
int SD(Graph g, int v, int z){
int * distance;
distance = (int *) malloc(sizeof(int)*g.V);
// Initialize distances
for(int i = 0; i < g.V; i++)
{
distance[i] = -1;
}
// queue to do BFS.
Queue q;
q.size = 0;
q.head = NULL;
q.tail = NULL;
int w;
int i;
enqueue(&q,v);
distance[v-1] = distance[v-1] + 1;
g.visited[v-1] = 1;
while(isEmptyQueue(q)==0){
w = dequeue(&q);
for(i=0;i<g.V;i++)
{
if(g.matrix[w-1][i] == 1 && g.visited[i]==0)
{
g.visited[i]=1;
distance[i] = distance[i] + 3;
enqueue(&q,i+1);
}
}
}
if(z <= g.V) return distance[z-1];
return -1;
}
void printGraphMatrix(Graph g)
{
int i,j;
for(i=0;i<g.V;i++){
for(j=0;j<g.V;j++)
printf("%d\t",g.matrix[i][j]);
printf("\n");
}
}
void enqueue(Queue *qPtr, int item) {
QueueNode *newNode;
newNode = malloc(sizeof(QueueNode));
if(newNode==NULL) exit(0);
newNode->vertex = item;
newNode->next = NULL;
if(isEmptyQueue(*qPtr))
qPtr->head=newNode;
else
qPtr->tail->next = newNode;
qPtr->tail = newNode;
qPtr->size++;
}
int dequeue(Queue *qPtr) {
if(qPtr==NULL || qPtr->head==NULL){ //Queue is empty or NULL pointer
return 0;
}
else{
int headValue = qPtr->head->vertex;
QueueNode *temp = qPtr->head;
qPtr->head = qPtr->head->next;
if(qPtr->head == NULL) //Queue is emptied
qPtr->tail = NULL;
free(temp);
qPtr->size--;
return headValue;
}
}
int getFront(Queue q){
return q.head->vertex;
}
int isEmptyQueue(Queue q) {
if(q.size==0) return 1;
else return 0;
}
void removeAllItemsFromQueue(Queue *qPtr)
{
while(dequeue(qPtr));
}
Related
So I'm trying to print the truth table of a gate with n inputs using linked lists. I tried the following but I'm running into a problem. If I use the for loops with bincombs, to print all possible combinations and to calculate the result, on both report and myandlst as shown below, it crashes. The problem is easily fixed if I print everything in myandlst but I want to avoid it. Here is my code so far:
#include <stdio.h>
#include <stdlib.h>
typedef struct data
{
int value;
struct data * next;
} Data;
typedef Data * DataList;
typedef int (*CallBack)(DataList *inlist, int n);
int report(CallBack f, int n);
int getbit(int x, int p);
void bincombs(int * x, int n);
int myandlst(DataList *list, int n);
int main( )
{
CallBack f ;
report(myandlst, 4);
return 0;
}
int getbit(int x, int p)
{
return (x & (1<<p))!=0;
}
void bincombs(int * x, int n)
{
static int state = 0 ;
int i;
for (i=0; i<n; i++)
{
*x = getbit (state, i);
x++;
}
state ++;
return;
}
Data * createData( int value)
{
Data * dataptr;
dataptr = malloc(sizeof (Data));
dataptr->value = value;
dataptr->next = NULL;
return dataptr;
}
void appendData(DataList *lstptr, Data *newptr)
{
if (*lstptr==NULL)
{
*lstptr = newptr;
return;
}
appendData( &((*lstptr)->next), newptr);
return;
}
int myandlst (DataList *inlist, int n)
{
int i,j,k;
int * x = malloc (n*sizeof(int));
k=1;
for (i=0; i< (1<<n) ; i++)
{
bincombs(x, n);
for (j=n-1; j>=0; j--)
{
k*=x[j];
}
appendData(inlist,createData(k));
k=1;
}
return 0;
}
int report(CallBack f, int n)
{
DataList temp ;
int * x = malloc (n*sizeof(int));
int i,j;
f(&temp, n);
for (i=0; i< (1<<n) ; i++)
{
bincombs(x, n);
for (j=n-1; j>=0; j--)
printf("%d ", x[j]);
printf("%d\n", temp -> value);
temp = temp->next;
}
printf("\n");
return 0;
}
P.S This is an assignment and therefore the structure of the program is standard. I can't avoid using linked lists or changing the format of the functions too much.
I have recently started to study this particular book for algorithms and data structure SkienaTheAlgorithmDesignManual.pdf, from which I've heard a lot of praise not only on the Internet,but from my Algorithms Design teacher as well at college,and I ended up having some errors with some code used from the book on page 153(on the book itself) or 165(pdf format).
Here's the code:
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#define MAXV 1000
typedef struct {
int y;
int weight;
struct edgenode *next;
}edgenode;
typedef struct {
edgenode *edges[MAXV + 1];
int degree[MAXV + 1];
int nvertices;
int nedges;
bool directed;
}graph;
void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
int i;
g->nvertices = 0;
g->nedges = 0;
g->directed = directed;
for (i = 1; i <= MAXV; i++) {
g->degree[i] = 0;
g->edges[i] = NULL;
}
}
void read_graph(graph *g, bool directed) {
int i;
int m;
int x, y;
initialize_graph(g, directed);
scanf("%d %d", &(g->nvertices), &m);
for (i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
insert_edge(g, x, y, directed);
}
}
void insert_edge(graph *g, int x, int y, bool directed) {
edgenode *p;
p = malloc(sizeof(edgenode));
p->weight = NULL;
p->y = y;
p->next = g->edges[x];
g->edges[x] = p;
g->degree[x]++;
if (directed == false)
insert_edge(g, y, x, true);
else
g->nedges++;
}
void print_graph(graph *g) {
int i;
edgenode *p;
for (i = 1; i <= g->nvertices; i++) {
printf("%d ", i);
p = g->edges[i];
while (p != NULL) {
printf(" %d", p->y);
p = p->next;
}
printf("\n");
}
}
main() {
bool directed = true;
graph *g;
read_graph(g, directed);
print_graph(g);
system("pause");
}
Here are the errors:
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(47): warning C4047: '=': 'int' differs in levels of indirection from 'void *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(49): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(65): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(73): error C4700: uninitialized local variable 'g' used
1>Done building project "LearningGraph.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I think that the main problem is the "incompatible types",but I may be as very well be wrong.
In insert_edge
p->weight = NULL;
is invalid because weight is an int but NULL a pointer (typically (void*)0)
In insert_edge
p->next = g->edges[x];
is invalid because next is the undefined type struct edgenode * but edges[x] is edgenode *. To solve that you have to replace
typedef struct {
int y;
int weight;
struct edgenode *next;
}edgenode;
by
typedef struct edgenode {
int y;
int weight;
struct edgenode *next;
}edgenode;
The reason is the same in print_graph line
p = p->next;
Explicitly set the return type of main as int
In main you call read_graph with g never set/initialized so when it is dereferenced in read_graph the behavior is undefined, and this is also the case in print_graph. Just replace
graph *g;
read_graph(g, directed);
print_graph(g);
by
graph g;
read_graph(&g, directed);
print_graph(&g);
Full modified version :
#include <stdlib.h>
#include<stdio.h>
#include<stdbool.h>
#define MAXV 1000
typedef struct edgenode {
int y;
int weight;
struct edgenode *next;
}edgenode;
typedef struct {
edgenode *edges[MAXV + 1];
int degree[MAXV + 1];
int nvertices;
int nedges;
bool directed;
}graph;
void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
int i;
g->nvertices = 0;
g->nedges = 0;
g->directed = directed;
for (i = 1; i <= MAXV; i++) {
g->degree[i] = 0;
g->edges[i] = NULL;
}
}
void read_graph(graph *g, bool directed) {
int i;
int m;
int x, y;
initialize_graph(g, directed);
scanf("%d %d", &(g->nvertices), &m);
for (i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
insert_edge(g, x, y, directed);
}
}
void insert_edge(graph *g, int x, int y, bool directed) {
edgenode *p;
p = malloc(sizeof(edgenode));
p->weight = 0;
p->y = y;
p->next = g->edges[x];
g->edges[x] = p;
g->degree[x]++;
if (directed == false)
insert_edge(g, y, x, true);
else
g->nedges++;
}
void print_graph(graph *g) {
int i;
edgenode *p;
for (i = 1; i <= g->nvertices; i++) {
printf("%d ", i);
p = g->edges[i];
while (p != NULL) {
printf(" %d", p->y);
p = p->next;
}
printf("\n");
}
}
int main() {
bool directed = true;
graph g;
read_graph(&g, directed);
print_graph(&g);
system("pause");
}
Compilation :
pi#raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra g.c
pi#raspberrypi:/tmp $
You never allocated any memory for graph *g.
There's no need for this to be a pointer, make it a normal variable and pass its address to the functions.
int main() {
bool directed = true;
graph g;
read_graph(&g, directed);
print_graph(&g);
system("pause");
}
I can scan the matrix and determine the size but the output is blank.
Here is my code:
int createTripplesArrayAndList(int** mat, int row, int colum, Tripple **arr, Node** ls) {
int i, j, count=0, k = 0;
Node* head = *ls;
Node* tmp=NULL;
//count how many elements would be in the required array\list
for (i = 0; i < row; i++) {
for (j = 0; j < colum; j++) {
if (mat[i][j] == i + j) {
count++;
}
}
}
//going over the matrix and add the relevant elements to the array and to the list
(*arr) = (Tripple*)calloc(count, sizeof(Tripple));
for (i = 0; i < row; i++) {
for (j = 0; j < colum; j++) {
if (mat[i][j] == i + j) {
//add element to array
(*arr)[k].argument = mat[i][j];
(*arr)[k].i = i;
(*arr)[k].j = j;
//add element to the list
if (!head) {
tmp = (Node*)malloc(sizeof(Node));
tmp->value = (*arr)[k];
tmp->next = NULL;
head = tmp;
} else {
Node *new_node = (Node*)malloc(sizeof(Node));
new_node->value = (*arr)[k];
new_node->next = NULL;
head->next = new_node;
head = new_node;
}
k++;
}
}
}
*ls = tmp;
return count;
}
void printTrripleArrAndList(Tripple* arr, int n, Node** ls) {
int i, j;
Node* curr = *ls;
printf("The tripple list is: ");
while (curr != NULL) {
printf("%d+%d=%d ->", curr->value.i, curr->value.j, curr->value.argument);
curr = curr->next;
}
printf("\nThe tripple array is: ");
for (i = 0; i < n; i++) {
printf("%d+%d = %d\n", arr[i].i,arr[i].j,arr[i].argument);
}
}
int ** createMat(int*n,int*m) {
int** mat = NULL;
int i, j, row, column;
//allocate and the matrix
printf("please enter size of row and colum: ");
scanf("%d%d", &row, &column);
mat = (int**)calloc(row, sizeof(int*));
for (i = 0; i < row; i++) {
mat[i] = (int*)calloc(column, sizeof(int));
}
//fill the matrix
printf("enter numbers for the matrix: ");
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
scanf("%d", &mat[i][j]);
}
}
*n = row;
*m = column;
return mat;
}
I used to get an error saying a value of type Node* cannot be assigned to an entity of type list* so I had to change them both to Node* The problematic area was:
head->next = new_node;
and:
curr = curr->next;
Please help.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define M 2
#define N 3
#define R 4
typedef struct Tripple {
int i;
int j;
int argument;
} Tripple;
typedef struct Node {
Tripple value;
struct Node* next;
} Node;
int* powerArray(int n);
void printPowArr(int* p, int n);
int** MatrixMultiplication(int firstMat[M][N], int secondMat[N][R]);
void printMatrix(int** p);
int createTripplesArrayAndList(int** mat, int row, int colum, Tripple **arr, Node** ls);
void printTrripleArrAndList(Tripple* arr, int n, Node** ls);
int** createMat(int* n, int*m);
This is my main :
void main() {
int *p;
int** newMat;
int p1[M][N] = { { 1, 4, 2 }, { 0, 3, 1 } };
int p2[N][R] = { { 1, 3, 1, 4 }, { 0, 2, 6, 4 }, { 4, 1, 0, 7 } };
int **mat=NULL;
int count;
int n = 0, m = 0, i = 0, j = 0;
p = powerArray(10);
printPowArr(p, 10);
newMat = MatrixMultiplication(p1, p2);
printMatrix(newMat);
Tripple* arr=NULL;
Node* ls=NULL;
mat=createMat(&n,&m);
count = createTripplesArrayAndList(mat, n, m, &arr, &ls);
printTrripleArrAndList(arr, count, &ls);
system("pause");
}
You are pointing both the head and head->next to new_node! This is absurd. Remove head->next = new_node.
I am implementing Kruskal's algorithm.
After I call graph() in the following code, the value of nodes change. I'm not quite sure why -- if anyone could clear this up I would greatly appreciate it. I'm not accessing the value of nodes from within graph, and both nodes & edges, the array being accessed, are allocated outside of the stack!
struct node {
int parent, rank;
};
typedef struct node node;
struct edge {
int fromvertex, tovertex;
float weight;
};
typedef struct edge edge;
node* nodes;
edge* edges;
typedef enum {Unvisited, Visited} vertexstate;
int main (int argc, char const *argv[])
{
void getcount(int*, int*);
void graph(int, int);
void makeset(int);
int hasspantree(int, int, int);
void kruskal(int, int);
int printmcst(int);
int nodecount, edgecount, i, totalcost=0;
getcount(&nodecount, &edgecount);
for (i = 1; i <= nodecount; i++)
makeset(i);
printf("%d \t %d\n", nodes[6].parent, nodes[6].rank );
graph(nodecount, edgecount);
printf("%d \t %d\n", nodes[6].parent, nodes[6].rank );
printf("Has a spanning tree?");
if(hasspantree(1, nodecount, edgecount)) {
printf("\t Yes.\n");
kruskal(nodecount, edgecount);
printf("MCST found:\n\n");
totalcost = printmcst(nodecount);
printf("\nCost: %d", totalcost);
}
else {
printf("No.");
exit(0);
}
return 0;
}
void graph(int nodecount, int edgecount)
{
for (int i = 0; i < edgecount; i++) {
scanf("%d", &edges[i].fromvertex);
scanf("%d", &edges[i].tovertex);
scanf("%f", &edges[i].weight);
}
}
void getcount(int *nodecount, int *edgecount)
{
scanf("%d", nodecount);
scanf("%d", edgecount);
nodes = malloc(*nodecount * sizeof(node));
edges = malloc(*edgecount * sizeof(edge));
}
void makeset(int x)
{
nodes[x].parent = x;
nodes[x].rank = 0;
}
one obvious error is accessing the nodes array starting at index 1 instead of 0 and this would cause buffer overrun when you access the last element
for (i = 1; i <= nodecount; i++) <-- here i should start at 0 and access only up to nodecount-1
makeset(i);
i declare a global variable and use and modify its value in the function. Then i want to get the modified value of this global variable, it has some problem. Can anyone help me?
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#define MAX 10
struct link
{
int freq;
char value[MAX];
struct link* right;
struct link* left;
};
typedef struct link node;
void sort(node *[], int);
node* create(char[], int);
void sright(node *[], int);
void Assign_Code(node*, int [], int);
void Delete_Tree(node *);
int test[720][720];
main()
{
node* ptr, * head;
int i, n, total = 0, u, c[256];
char str[MAX];
node* a[256];
int freq;
printf( "Huffman Algorithm\n");
printf("\nEnter the no. of letter to be coded:");
/*input the no. of letters*/
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter the letter & frequency:");
/*input the letter & frequency*/
scanf("%s %d", str, &freq);
a[i] = create(str, freq);
}
while (n > 1)
{
sort(a, n);
u = a[0]->freq + a[1]->freq;
strcpy(str,a[0]->value);
strcat(str,a[1]->value);
ptr = create(str, u);
ptr->right = a[1];
ptr->left = a[0];
a[0] = ptr;
sright(a, n);
n--;
}
Assign_Code(a[0], c, 0);
//getch();
printf("Code: ");
for (i = 1; i <= n; i++)
{
printf("%d", test[0][i]);
}
printf("\n");
Delete_Tree(a[0]);
}
node* create(char a[], int x)
{
node* ptr;
ptr = (node *) malloc(256*sizeof(node));
ptr->freq = x;
strcpy( ptr->value , a);
ptr->right = ptr->left = NULL;
return(ptr);
}
void sort(node* a[], int n)
{
int i, j;
node* temp;
for (i = 0; i < n - 1; i++)
for (j = i; j < n; j++)
if (a[i]->freq > a[j]->freq)
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
void sright(node* a[], int n)
{
int i;
for (i = 1; i < n - 1; i++)
a[i] = a[i + 1];
}
void Assign_Code(node* tree, int c[], int n)
{
int i;
if ((tree->left == NULL) && (tree->right == NULL))
{
printf("%s code: ", tree->value);
test[0][0]=tree->value;
for (i = 0; i < n; i++)
{
test[0][i+1]=c[i];
printf("%d", c[i]);
}
printf("\n");
}
else
{
c[n] = 1;
n++;
Assign_Code(tree->left, c, n);
c[n - 1] = 0;
Assign_Code(tree->right, c, n);
}
}
void Delete_Tree(node * root)
{
if(root!=NULL)
{
Delete_Tree(root->left);
Delete_Tree(root->right);
free(root);
}
}
Let me highlight the problem:
while (n > 1)
{
...
n--;
}
...
for (i = 1; i <= n; i++)
{
printf("%d", test[0][i]);
}
By the time the second loop starts n is one, and the printf is executed only once, so that you print the value of test[0][1] and only that.
The value of test[0][1] is overwritten many times (as many as the number of leaf nodes in the tree) in Assign_Code:
void Assign_Code(node* tree, int c[], int n)
{
if ((tree->left == NULL) && (tree->right == NULL))
{
...
for (i = 0; i < n; i++)
{
test[0][i+1]=c[i];
}
}
...
}
Now, because of the way you are traversing the tree the last time test[0][1] is overwritten is for a Huffman code that has a '0' as first character.
As a side note:
node* create(char a[], int x)
{
node* ptr;
ptr = (node *) malloc(256*sizeof(node)); // <--- This is wrong
ptr->freq = x;
strcpy( ptr->value , a);
ptr->right = ptr->left = NULL;
return(ptr);
}
There is no reason to allocate 256 times the size of node to store one node. You are creating a node and storing it in an array of pointers to nodes. Allocate one node there, like this:
malloc (sizeof (node)); or malloc ((sizeof (*ptr));
you can store the n value to some temporary variables, after you get the
values.
Then use the temporary variable in your for loop condition.
scanf("%d", &n);
int temp = n ;
for (i = 1; i <= temp ; i++)
{
printf("%d", test[0][i]);
}