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);
Related
I am trying to find the shortest distance between two nodes using adjacent matrix and recursive call, but for some reason it always returns 0, i cant find where things are going wrong.
The function 'shortestDist' is a recursive function which returns the shortest cost. If src node contains a direct path to destination than the cost is directly added to array. but if it doesnt the possible nodes replace the source node and a recursive function is called. for a node to replace a source node it must meet the following requirements : 1- it shouldn't be visited, 2- the distance between this.node and destination should be less than prevsrc and dst, 3- the node should not be the destination itself.
`
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define X 99
int **graph;
int numNodes;
char nodes[10][10];
void createGraph(int);
void printGraph();
void addPath(char[],char[],int);
void deleteGraph();
int shortestDist(int,int);
int visited[10];
int min(int[]);
void main()
{
int i,j;
createGraph(5);
addPath("a","b",3);
addPath("b","c",5);
addPath("a","c",9);
printf ("\n%d\n",shortestDist(0,2));
printGraph();
}
void createGraph(int no){
int i,j;
numNodes=no;
graph = malloc(sizeof(int*)*no);
for(i=0;i<no;i++){
graph[i] = malloc(sizeof(int)*no);
visited[i] = 0;
}
for(i=0;i<no;i++){
printf("Enter %d node: ",i+1);
scanf("%s",&nodes[i]);
for(j=0;j<no;j++){
graph[i][j] = X;
}
}
}
void addPath(char from[],char to[],int dist){
int i,j;
for(i=0;i<numNodes;i++){
for(j=0;j<numNodes;j++){
if(strcmp(from,nodes[i])==0 && strcmp(to,nodes[j])==0){
graph[i][j]=dist;
}
}
}
}
void printGraph(){
int i,j;
for(i=0;i<numNodes;i++){
for(j=0;j<numNodes;j++){
printf("%d ",graph[i][j]);
}
printf("\n");
}
for(i=0;i<numNodes;i++){
printf("%d ",visited[i]);
}
}
void deleteGraph(){
free(graph);
}
int shortestDist(int src,int dst){
int possPaths=0,i;
int count=0;
visited[src] = 1;
for(i=0;i<numNodes;i++){
if(graph[src][i]!=X){
possPaths++;
}
}
int possNodes[possPaths];
for(i=0;i<possPaths;i++){
possNodes[i] = X;
}
if(graph[src][dst]!=X){
possNodes[count] = graph[src][dst];
count++;
}
for(i=0;i<numNodes;i++){
if(graph[src][i]!=X && visited[i]==0 && i!=dst){
printf("?");
possNodes[count] = graph[src][i] + shortestDist(i,dst);
count++;
}
}
for(i=0;i<possPaths;i++){
printf("->%d\n",possNodes[i]);
}
return min(possNodes);
}
int min(int arr[]){
int minimum=arr[0],i;
for(i=0 ; i<numNodes ; i++){
if(arr[i]<minimum){
minimum = arr[i];
}
}
return minimum;
}
`
Output is always returing 0.
The min function processes numNodes array elements, but it is passed the array possNodes with only possPaths elements, hence it fails to return a correct minimum.
I suggest to change it to
int min(int possPaths, int arr[possPaths])
{
int minimum = X;
for (int i = 0; i < possPaths; ++i)
if (arr[i] < minimum) minimum = arr[i];
return minimum;
}
and invoke it so:
return min(possPaths, possNodes);
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));
}
whenever i try to use the following code in c the for loop breaks after one iteration and i cannot figure out why exactly.If not using for loop then it works fine which i did tested.Please help.
#include<stdio.h>
#include<stdlib.h>
struct stack
{
int top;
int n;
char *arr;
};
void push(struct stack *ptr,char x);
int main(){
struct stack chs;
struct stack *ptr;
ptr = &chs;
ptr->top=-1;
printf("enter the size of stack: ");
scanf("%d",&ptr->n);
int size = ptr->n;
for(int i=0 ; i < size ; i++){
printf("test iteration ");
push(ptr,'a');
}
return 0;
}
void push(struct stack *ptr,char x){
if(ptr->top >= (ptr->n-1)){
printf("\nstack overflow\n");
return;
}
else{
ptr->top = (ptr->top) + 1;
ptr->arr[(ptr->top)] = x;
}
}
As noted in the comment, member arr is never initialized to point to anything. You can correct the problem by modifying your code to the following:
#include<stdio.h>
#include<stdlib.h>
struct stack
{
int top;
int n;
char *arr;
};
void push(struct stack *ptr,char x);
int main(){
struct stack chs;
struct stack *ptr;
ptr = &chs;
ptr->top=-1;
printf("enter the size of stack: ");
scanf("%d",&ptr->n);
int size = ptr->n;
char chs_arr[size]; // Variable-sized array based on input
ptr->arr = chs_arr; // Set pointer member arr to point to array created.
for(int i=0 ; i < size ; i++){
printf("test iteration ");
push(ptr,'a');
}
return 0;
}
void push(struct stack *ptr,char x){
if(ptr->top >= (ptr->n-1)){
printf("\nstack overflow\n");
return;
}
else{
ptr->top = (ptr->top) + 1;
ptr->arr[(ptr->top)] = x;
}
}
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.
Hi this code is just an example of what im working on. I've got the solution by copying everything from my search function and dump it into my edit function. Is there any better solution rather than just copy pasting?
struct inventory
{
float a,b,c,d;
char something[MAXSIZE];
};
typedef struct inventory Inventory;
struct will contain some float integer and some characters.
void search(const Inventory inv[], int np); // declare search function
void edit(struct inventory inventoryRegister[],int np);
int main(void)
{
int np=0;
struct inventory inventoryRegister[MAXSIZE];
// calling the functions search and edit
search(inventoryRegister, np);
edit(inventoryRegister, np);
return 0;
}
void search(const Inventory inv[], int np)
{
int i,
float min, max;
printf("Enter min max");
scanf("%f %f", &min, &max);
for (i = 0; i < np; i++)
if (inv[i].a >= low && inv[i].a <= high)
{
print..
}
//repeat for b,c,d and something
}
void edit(struct inventory inventoryRegister[],int np)
{
int a;
print("Enter new a");
scanf("%f", &a);
// Here i can copy and paste my entire search function and do a loop to replace the min & max with my new input a.
But is there any easier way to do it? say i call the search(); and somehow extract the elements between min & max and do a loop replacement with a?
Any suggestion?
}
Disclaimer : Its a kind of a psuedo code
struct MinMaxLocation
{
int minloc;
int maxloc;
};
struct MinMaxLocation getMinMaxLocation(struct inventory inventoryRegister[],float min,float max)
{
// your logic to find min and max locations here
struct MinMaxLocation loc;
loc.minloc = // min element location
loc.maxloc = // max element location
return loc;
}
void search(....)
{
struct MinMaxLocation loc_here_search = getMinMaxLocation(inventoryRegister,min,max);
for (i = loc_search_here.min; i < loc_search_here.max; i++)
{
print ...
}
}
void edit(....)
{
struct MinMaxLocation loc_here_search = getMinMaxLocation(inventoryRegister,min,max);
for (i = loc_search_here.min; i < loc_search_here.max; i++)
{
edit the values here ...
}
}