K-ary tree with array implementation in C - c

Hi everyone so i got this task to make an adt of non-binary tree which can do traversals. I messed up the structure from the very beginning but I still can do the post-order and pre-order traversal (i don't know if i did it wrong too, but it works). Now i confused how to do the in-order traversal. My code just doesn't work.
This is my data structure
typedef char infotype;
typedef int letak;
typedef struct {
infotype info;
letak parent, firstson, nextsibling;
} node;
typedef node tree;
These are how I initialize each node
void initNode(tree T[], int k, int i)
{
char info;
printf("Input the node name : ");
scanf(" %c", &info);
createNode(T, k, i, info);
}
void createNode(tree T[], int k, int i, char value)
{
int j;
if(i == 0)
{
T[i].info = value;
T[i].firstson = i+1;
}
else
{
T[i].info = value;
T[i].parent = (i-1) / k;
T[i].firstson = (i * k) + 1;
if (i % k != 0)
{
T[i].nextsibling = i+1;
}
else
{
T[i].nextsibling = 0;
}
}
}
and this is how I try to do the in-order traversal
void InOrder(tree T[], int maksimum_array, int maksimum_anak)
{
bool Resmi = true;
int i = 0;
while(i >= 0)
{
if(T[i].firstson < maksimum_array - 1 && Resmi == true)
{
i = T[i].firstson;
}
else
{
if(Resmi == true)
{
printf("%c ", T[i].info);
}
if(i = T[T[i].parent].firstson)
{
printf("%c ", T[T[i].parent].info);
}
if(T[i].nextsibling < maksimum_array - 1 && T[i].nextsibling != 0)
{
i = T[i].nextsibling;
Resmi = true;
}
else
{
i = T[i].parent;
Resmi = false;
}
}
}
}
And this is my main driver :
int main()
{
tree pohon[1000];
int maksimum;
int maksimum_anak;
int level;
int i = 0;
int count = 0;
char cari;
printf("Enter array maximum amount : ");
scanf("%d", &maksimum);
printf("\nEnter maximum child of each node : ");
scanf("%d", &maksimum_anak);
createTree(pohon);
for (i = 0; i < maksimum ; i++)
{
initNode(pohon, maksimum_anak, i);
}
for (i = 0; i < maksimum; i++)
{
printTree(pohon, i, maksimum, maksimum_anak);
}
printf("In Order Traversal : ");
InOrder(pohon, maksimum, maksimum_anak);
}
I've tried another algorithms for the in-order traversal like using recursive. But since i messed up the struct those algorithms just did not work. Thank you before.

if(i = T[T[i].parent].firstson)
Should be
if(i == T[T[i].parent].firstson)
The former assigns to i, the latter compares it.

Related

Why is my Hash Map insert function not working?

I am making a Hash Map with people's names as its key using C language. I am using separate chaining to resolve the collision.
This is my code:
#include<stdio.h>
#include<stdlib.h>
#define MinTableSize 1
#include <stdbool.h>
//Colission resolution Using linked list
struct ListNode;
typedef struct ListNode *Position;
struct HashTbl;
typedef struct HashTbl *HashTable;
typedef unsigned int Index;
Index Hash(const char *Key, int Tablesize)
{
unsigned int HashVal = 0;
while(*Key != '\0')
{
HashVal += *Key++;
}
return HashVal % Tablesize;
}
struct ListNode
{
int Element;
Position Next;
};
typedef Position List;
struct HashTbl
{
int TableSize;
List *TheLists;
};
//Function to find next prime number for the size
bool isPrime(int n)
{
if(n <= 1)
{
return false;
}
if(n <= 3)
{
return true;
}
if(n%2 == 0 || n%3 == 0)
{
return false;
}
for(int i = 5; i*i <= n; i = i + 6)
{
if(n%i == 0 || n%(i + 2) == 0)
{
return false;
}
}
return true;
}
int NextPrime(int N)
{
if(N <= 1)
{
return 2;
}
int prime = N;
bool found = false;
while(!found)
{
prime++;
if(isPrime(prime))
{
found = true;
}
}
return prime;
}
HashTable InitializeTable(int TableSize)
{
HashTable H;
int i;
if(TableSize < MinTableSize)
{
printf("Table size is too small\n");
return NULL;
}
H = malloc(sizeof(struct HashTbl));
if(H == NULL)
{
printf("Out of space\n");
return NULL;
}
H->TableSize = NextPrime(TableSize);
H->TheLists = malloc(sizeof(List) * H->TableSize);
if(H->TheLists == NULL)
{
printf("Out of space\n");
return NULL;
}
for(i = 0; i < H->TableSize; i++)
{
H->TheLists[i] = malloc(sizeof(struct ListNode));
if(H->TheLists[i] == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
H->TheLists[i]->Next = NULL;
}
}
return H;
}
//funtion to find the value
Position Find(const char *Key, HashTable H)
{
Position P;
List L;
L = H->TheLists[Hash(Key, H->TableSize)];
P = L->Next;
while(P != NULL && P->Element != Key)
{
P = P->Next;
}
return P;
}
void Insert(const char *Key, HashTable H)
{
Position Pos;
Position NewCell;
List L;
Pos = Find(Key, H);
if(Pos == NULL)
{
NewCell = malloc(sizeof(struct ListNode));
if(NewCell == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
L = H->TheLists[Hash(Key, H->TableSize)];
NewCell->Next;
NewCell->Element = Key;
L->Next = NewCell;
printf("Key inserted\n");
}
}
else
{
printf("Key already exist\n");
}
}
int main()
{
char Name[6][20] = {"Joshua", "Erica", "Elizabeth", "Monica", "Jefferson", "Andrian"};
int Size = sizeof(Name[0])/sizeof(Name[0][0]);
HashTable H = InitializeTable(Size);
Insert(Name[0], H);
Insert(Name[1], H);
Insert(Name[2], H);
Insert(Name[3], H);
}
The putout of this code is:
Key inserted
Key inserted
This means, it only successfully inserted two keys, while the other name has not been inserted. I think there's some error in my Insert() function, but I got no clue. I tried using an online compiler and it compile properly.

Array of structures lose data while passing it in C

I don't understand why printq() function prints 0, but when I access it back in main() it prints. I don't understand what I am doing wrong, I tried using pointers, but I get some different error in the priority queue. I want to print elements in array pq[10].
EDIT: I realized that the elements are stored but when I use pq[R].data it prints
but when I use pq[i].data in printq() and put it inside for loop, it prints zero.
#include <stdio.h>
int F = -1, R = -1;
int item, max = 10;
struct prioq {
int data;
int prio;
};
struct prioq pq[10] = { 0 };
void printq()
{
int i = 0;
printf("%d,", pq[i].data);
printf("QUEUE :");
for (i = 0; i < max; i++) {
printf("%d,", pq[i].data);
}
printf("\n");
printf("PRIO :");
for (i = 0; i < max; i++) {
printf("%d,", pq[i].prio);
}
}
void enqueue(int item, int p, struct prioq pq[])
{
if (F == -1 && R == -1 || F > R) {
F == 0;
R == 0;
pq[R].data = item;
pq[R].prio = p;
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
printq();
} else if (R == max-1 || R > max) {
printf("overflow\n");
} else if (R < max) {
R++;
pq[R].data = item;
pq[R].prio = p;
printq();
}
}
void dequeue(struct prioq pq[])
{
int large = 0;
if (F == -1) {
printf("underflow\n");
} else {
int i;
for (i = 0; i < max; i++) {
if (pq[i].prio > large) {
large = i;
}
}
}
item = pq[large].data;
pq[large].prio = 0;
pq[large].data = 0;
printf("item deleted: %d\n", item);
printq();
}
void main()
{
int item = 0;
int c = 0, p = 0;
do {
printf("choose your option\n");
printf("1.Insert, 2.Delete, 3.Exit\n" );
scanf("%d", &c);
switch (c) {
case 1:
printf("Enter the priority and element to insert\n");
scanf("%d %d", &item, &p);
enqueue(item,p,pq);
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
break;
case 2:
dequeue(pq);
break;
default:
c = 3;
break;
}
} while (c != 3);
printf("exited\n");
}
In your enqueue function, change the == in the F and R assignments to =.
void enqueue(int item, int p, struct prioq pq[])
{
if (F == -1 && R == -1 || F > R) {
F = 0; // Here
R = 0; // And here
pq[R].data = item;
pq[R].prio = p;
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
printq();
} else if (R == max-1 || R > max) {
printf("overflow\n");
} else if (R < max) {
R++;
pq[R].data = item;
pq[R].prio = p;
printq();
}
}

My BFS code is only showing the direct paths from source to destination, but not all possible paths

I want to print all possible paths from a given source and destination. But in my BFS code, it only shows the two paths, not the multiple path. For a directed graph where n = 4, edge = 6, given,
1-2
1-3
1-5
5-3
5-4
3-4
3-2
It should've printed 3 paths:
1-5-4
1-3-4
1-5-3-4
But it only shows this two paths
1-3-4
1-5-4
This is my sample code for finding the src to destination path
#include <stdio.h>
int queue1[100], state[100], parent[100];
int front = 0, rear = -1, maxSize = 100;
int count = 0;
int initial = 1, waiting = 2, visited = 3;
int n, e;
int adj[100][100];
bool isEmpty()
{
return count == 0;
}
bool isFull()
{
return count == maxSize;
}
void enqueue(int val)
{
if (!isFull())
{
if (rear == maxSize - 1)
{
rear = -1;
}
rear++;
queue1[rear] = val;
count++;
}
}
int dequeue()
{
int val = queue1[front];
front++;
if (front == maxSize)
{
front = 0;
}
count--;
return val;
}
void BFS_Traversal(int src, int des)
{
int done = 0;
enqueue(src);
state[src] = waiting;
parent[src] = -1;
printf("path ");
while (!isEmpty() && done == 0)
{
src = dequeue();
// printf("%d ",src);
state[src] = visited;
for (int i = 1; i <= n; i++)
{
if (adj[src][i] == 1 && state[i] == initial)
{
enqueue(i);
state[i] = waiting;
parent[i] = src;
if (i == des)
{
state[i] = initial;
int k = des;
do
{
printf("%d ", k);
k = parent[k];
} while (k != -1);
printf("\n");
}
}
}
}
}
int main()
{
int src, start, end, des;
scanf("%d%d", &n, &e);
for (int i = 1; i <= e; i++)
{
scanf("%d%d", &start, &end);
adj[start][end] = 1;
}
for (int i = 1; i <= n; i++)
{
state[i] = initial;
}
for (int k = 1; k <= n; k++)
{
parent[k] = -1;
}
scanf("%d%d", &src, &des);
BFS_Traversal(src, des);
}
As, you can see 1-5-3-4 path is not showing because they are already visited. How should I modify this code to print all possible paths?

Unreachable Node in Dijkstra's Algorithm

So I'm having trouble with Dijkstra's algorithm (src to dest). I looked at other answers and could not find the solution to my problem. I have used an adjacency list, thus I have a list for vertices, and each vertex has it's own edge list. My problem arises when I have a node that is unreachable. Specifically, it never gets visited thus I'm stuck in my allNotComp while loop. Can anyone help me with a solution? Code is below.
#include <stdlib.h>
#include <stdio.h>
int INFINITY = 9999;
struct edge
{
int vertexIndex;
int vertexWeight;
struct edge *edgePtr;
} edge;
struct vertex
{
int vertexKey;
struct edge *edgePtr;
struct vertex *vertexPtr;
}vertex;
struct vertex *Start = NULL;
void insertEdge(int vertex, int vertex2, int vertexWeight);
void insertVertex(int vertexKey);
int allNotComp(int comp[], int size);
void printPath(int prev[], int src, int dest, int size);
void dijkstra(int src, int size, int dest);
int cost(int curr, int i);
int main(int argc, char * argv[]) {
int k = 1;
int numVertices = atoi(argv[2]);
char* source = argv[3];
char* destination = argv[4];
int src = atoi(argv[3]);
int dest = atoi(argv[4]);
Start = &vertex;
Start->vertexKey = 0;
Start->vertexPtr = NULL;
Start->edgePtr = NULL;
int m = 0;
int flag = 0;
int flag2 = 0;
for(m = 0; m < numVertices; m++){
if(src == m) {
flag = 1;
}
if(dest == m) {
flag2 = 1;
}
}
if(!(flag && flag2)) {
printf("%s ", "ERROR: Src and/or Dest not valid.\n");
exit(0);
}
while(k < numVertices) {
insertVertex(k);
k++;
}
FILE *f = fopen(argv[1], "r");
int numbers[numVertices][numVertices];
char ch;
int i = 0;
int j = 0;
for(m = 0; m < numVertices*numVertices; m++) {
fscanf(f, "%d", &(numbers[i][j]));
j=j+1;
if(j == numVertices) {
i=i+1;
j=0;
}
}
for(i=0;i<numVertices;i++) {
for(j=0;j<numVertices;j++) {
if(i == j && numbers[i][j] != 0) {
printf("%s", "ERROR: All diagonals must be zero.\n");
exit(0);
}
if(i != j) {
insertEdge(i, j, numbers[i][j]);
}
}
}
dijkstra(src, numVertices, dest);
}
void insertEdge(int vertex, int vertex2, int vertexWeight)
{
if(vertexWeight == -1) return;
struct vertex *traverse;
if(vertex == Start->vertexKey) {
traverse = Start;
}
else {
while(traverse->vertexKey != vertex) {
traverse = traverse->vertexPtr;
}
}
struct edge *e,*e1,*e2;
e=traverse->edgePtr;
while(e&& e->edgePtr)
{
e=e->edgePtr;
}
e1=(struct edge *)malloc(sizeof(*e1));
e1->vertexIndex=vertex2;
e1->vertexWeight = vertexWeight;
e1->edgePtr=NULL;
if(e)
e->edgePtr=e1;
else
traverse->edgePtr=e1;
}
void insertVertex(int vertexKey) {
struct vertex *v, *v1, *v2;
v = Start->vertexPtr;
while(v && v->vertexPtr) {
v=v->vertexPtr;
}
v1=(struct vertex *)malloc(sizeof(*v1));
v1->vertexKey = vertexKey;
v1->vertexPtr = NULL;
v1->edgePtr = NULL;
if(v) {
v->vertexPtr = v1;
}
else {
Start->vertexPtr = v1;
}
}
void dijkstra(int src, int size, int dest) {
int comp[size];
int dist[size];
int prev[size];
int i;
for(i = 0; i<size; i++) {
comp[i] = 0;
dist[i] = INFINITY;
prev[i] = -1;
}
comp[src] = 1;
dist[src] = 0;
prev[src] = src;
int curr = src;
int k;
int minDist;
int newDist;
while(allNotComp(comp, size)) {
minDist = INFINITY;
for(i = 0; i<size;i++) {
if(comp[i] == 0) {
newDist = dist[curr] + cost(curr, i);
if(newDist < dist[i]) {
dist[i] = newDist;
prev[i] = curr; }
if(dist[i] < minDist) {
minDist = dist[i];
k=i; }
}
}
curr = k;
comp[curr] = 1;
}
if(dist[dest] < INFINITY) {
printPath(prev, src, dest, size);
printf(":%d\n", dist[dest]);
} else {
printf("%s\n", "NO PATH EXISTS BETWEEN THE TWO VERTICES!");
}
}
int allNotComp(int comp[], int size) {
int i;
for(i = 0; i < size; i++) {
if(comp[i] == 0) {
return 1;
}
}
return 0;
}
int cost(int curr, int i) {
struct vertex *travel;
struct edge *traverse;
travel = Start;
while(travel->vertexPtr != NULL) {
if(travel->vertexKey != curr) {
travel = travel->vertexPtr;
}
else{
break;
}
}
traverse = travel->edgePtr;
while(traverse->edgePtr != NULL) {
if(traverse->vertexIndex != i) {
traverse = traverse->edgePtr;
}
else{
break;
}
}
if(traverse->vertexIndex != i) {
return INFINITY;
}
return traverse->vertexWeight;
}
void printPath(int prev[], int src, int dest, int size) {
if(src == dest) {
printf("%d", src);
}
else {
printPath(prev, src, prev[dest], size);
printf("-%d", dest);
}
}
Although an unreachable node never gets visited, this situation can be detected. If the dists of all unvisited nodes are INFINITY, this means all remaining nodes are unreachable, and you should end the loop.

top-bottom binary tree display

The following code displays my created binary tree from left to right on the console window. How do I print it from the top to the bottom, as you would on paper?
// Binary Trees Implementation
#include<stdio.h>
#include<stdlib.h>
typedef struct BTNode
{
int key;
struct BTNode *left, *right;
};
void displayBT(BTNode *p, int level);
BTNode *buildBT();
void RSD(BTNode *p);
void SRD(BTNode *p);
void SDR(BTNode *p);
int main()
{
int op;
BTNode *root;
do
{
printf("\n 1. Build Binary Tree");
printf("\n 2. Display Binary Tree");
printf("\n 3. Display Traversals");
printf("\n 0. Exit");
printf("\n........................\n");
scanf("\n %d", &op);
switch(op)
{
case 1:
root=buildBT();
break;
case 2:
displayBT(root,0);
break;
case 3:
printf("\n Pre-Order:");
RSD(root);
printf("\n In-Order:");
SRD(root);
printf("\n Post-Order:");
SDR(root);
printf("\n.....................\n");
break;
}
} while(op);
}
BTNode *buildBT()
{
int value;
BTNode *p;
printf("\n k=");
scanf("%d",&value);
if(value!=0)
{
p=(BTNode *)malloc(sizeof(BTNode));
p->key = value;
p->left = buildBT();
p->right = buildBT();
} else p=NULL;
return p;
}
void displayBT(BTNode *p, int level)
{
if(p!=NULL)
{
displayBT(p->right, level+1);
for(int j=0; j<=level;j++)
printf(" ");
printf("%d \n", p->key);
displayBT(p->left, level+1);
}
}
void RSD(BTNode *p)
{
if(p!=NULL)
{
printf("%d ", p->key);
RSD(p->left);
RSD(p->right);
}
}
void SRD(BTNode *p)
{
if(p!=NULL)
{
SRD(p->left);
printf("%d ", p->key);
SRD(p->right);
}
}
void SDR(BTNode *p)
{
if(p!=NULL)
{
SDR(p->left);
SDR(p->right);
printf("%d ", p->key);
}
}
Ok so I uploaded the full code because I was having trouble with the suggestions and maybe I should have done this from the beginning.
gave it another go, actually tried it now. works for me
void print_box(FILE* out, int i)
{
static char buff[16] = {0};
sprintf(buff,"%d",i);
int n = strlen(buff);
static char buf2[16] = {0};
strcpy(buf2,"[ ]");
int nn = 2 - (n-1)/2 ;
for(i=0;i<n;++i)
buf2[nn+i] = buff[i];
fprintf(out,"%s",buf2);
}
void print_empty_box(FILE* out) { fprintf(out,"%s","[ - ]"); }
typedef struct NodeRowTag
{
struct NodeRowTag* nxt;
BTNode* node;
} NodeRow;
NodeRow* make_head()
{
NodeRow* nr;
nr = (NodeRow*) malloc(sizeof(NodeRow));
nr->node = 0;
nr->nxt = 0;
return nr;
}
void push_back( NodeRow* nr, BTNode* n )
{
while( nr->nxt )
{
nr = nr->nxt;
}
nr->nxt = (NodeRow*) malloc(sizeof(NodeRow));
nr->nxt->node = n;
nr->nxt->nxt = 0;
}
void del_all( NodeRow* nr )
{
if( nr->nxt )
del_all(nr->nxt);
free( nr );
}
NodeRow* print_and_next( FILE* out, NodeRow* nr, int rownum, int maxnum )
{
// init spacing
int spacing = 0;
int stride = 3;
for(int i=rownum; i<maxnum; ++i)
{
spacing += stride;
stride *= 2;
}
for(int i=0;i<spacing;++i)
fprintf(out, " " );
// inbetween spacing
spacing = 1;
stride = 6;
for(int i=rownum; i<maxnum; ++i)
{
spacing += stride;
stride *= 2;
}
//
NodeRow* nxt = make_head();
NodeRow* n = nr->nxt;
while(n)
{
BTNode* p = n->node;
if(p) {
print_box(out,p->key);
push_back(nxt,p->left);
push_back(nxt,p->right);
} else {
print_empty_box(out);
push_back(nxt,0);
push_back(nxt,0);
}
for(int i=0;i<spacing;++i)
fprintf(out, " " );
n=n->nxt;
}
fprintf(out, "\n" );
del_all(nr);
return nxt;
}
int max(int a,int b) { return (a>b)?a:b; }
int max_depth( BTNode* p )
{
if(!p) return 0;
return 1 + max( max_depth(p->left), max_depth(p->right) );
}
void PrittyPrint( FILE* out )
{
int n = max_depth(root);
NodeRow* nr = make_head();
push_back(nr,root);
for(int i=1; i<=n; ++i)
{
nr = print_and_next( out, nr, i, n );
}
del_all(nr);
}
By printing the value of the current node BEFORE recursing right/left!

Resources