Edit : the code works with this edit but I don't understand as to why it does.
working ideone with edit : http://ideone.com/ESfkrs
Edited code :
typedef struct _q{
int front,rear;
tree *a[MAX];
}queue;
void enqueue(queue *q, tree *x){
if(!q || q->rear==MAX-1 || !x){
return;
}
q->a[++q->rear]=x;
}
tree* dequeue(queue *q){
if(q->front>q->rear || q->front==MAX){
return NULL;
}
return q->a[q->front++];
}
I'v following code for creating a BT out of an array representation.
problem is that in multiple loops of while 1 level of BT nodes don't point to next level. i.e r->l & r->r is lost in transition of loop although the mem is heap allocated & must be retained until the program exits.
I'v spent umpteen hours digging this but to no vain. TIA.
working ideone : http://ideone.com/O4VKCH
output :
5 10 20
5 10 20
5 10 20
5 10 20
5 10 20
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
typedef struct _tree{
int data;
struct _tree *l,*r;
}tree;
typedef struct _q{
int front,rear;
tree a[MAX];
}queue;
void create_node(tree **rooty,int data){
(*rooty) = (tree*)calloc(1,sizeof(tree));
(*rooty)->data=data;
return;
}
void create_node_bst(tree **rooty,int data){
if(!(*rooty)) {
create_node(rooty,data);
}
if(data<(*rooty)->data) create_node_bst(&(*rooty)->l,data);
if(data>(*rooty)->data) create_node_bst(&(*rooty)->r,data);
}
void inorder(tree *root){
if(!root) return;
if(root->l) inorder(root->l);
printf("%d\t",root->data);
if(root->r) inorder(root->r);
}
void enqueue(queue *q, tree *x){
if(!q || q->rear==MAX-1 || !x){
return;
}
q->a[++q->rear]=*x;
}
tree* dequeue(queue *q){
if(q->front>q->rear || q->front==MAX){
return NULL;
}
return &(q->a[q->front++]);
}
void print_q(queue *q){
if(!q || q->front>q->rear){
return;
}
int front=q->front;
printf("+\n");
while(front<=q->rear){
printf("%d\t",q->a[front++].data);
}
printf("\n-");
}
void bfs_order(tree *root, queue *q){
if(!root || !q){
return;
}
printf("%d\t",root->data);
if(root->l)enqueue(q,root->l);
if(root->r)enqueue(q,root->r);
bfs_order(dequeue(q),q);
}
void initialise_q(queue **q){
if(!*q){
*q = (queue*)malloc(sizeof(queue));
(*q)->front=0;
(*q)->rear=-1;
memset((*q)->a,0,MAX*sizeof(int));
}
}
tree* create_bt(tree *r, queue *q, int *arr, int len){
if(!q || !arr) return NULL;
int i=0,first=1;
tree *root=NULL, *ret=NULL;
while(i<len){
tree *temp_l=NULL, *temp_r=NULL;
root = dequeue(q);
if(first){
ret = root;
first = 0;
}
if(!root) break;
if(i+1<len) {
create_node(&temp_l,arr[i+1]);
enqueue(q,temp_l);
}
if(i+2<len) {
create_node(&temp_r,arr[i+2]);
enqueue(q,temp_r);
}
if(temp_l) {
//root->l=temp_l;
create_node(&(root->l),temp_l->data); <-- Pls focus here
}
if(temp_r) {
//root->l=temp_r;
create_node(&(root->r),temp_r->data); <-- llly, here.
}
inorder(ret); printf("\n"); <-- to demo the output
i+=2;
}
return ret;
}
int main(void) {
tree *root = NULL, *temp_t=NULL;
int arr[]={10,5,20,2,7,8,9,0,1};
int len = sizeof(arr)/sizeof(arr[0]);
for(int k=0;k<len;k++){
//create_node_bst(&root,arr[k]);
}
queue *q = NULL, *temp_q=NULL;
initialise_q(&q);
initialise_q(&temp_q);
create_node(&temp_t,arr[0]);
enqueue(q,temp_t);
tree *bt = create_bt(root,q,arr,len);
//bfs_order(bt,temp_q);
if(root) free(root);
if(q) free(q);
return 0;
}
Related
I'm implementing a graph traversal breadth-first search that I found here. However, their implementation involves integers and without any linked list. I was playing around with it a little bit I have no luck in getting any results because it doesn't seem to work as intended.
This is the code that I currently have:
(main.c)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct s_list
{
struct s_list *next;
void *content;
} t_list;
typedef struct s_queue
{
t_list *first;
t_list *last;
} t_queue;
typedef struct s_node
{
struct s_node *next;
int vertex;
} t_node;
typedef struct s_graph
{
t_node **adj_lists;
int *visited;
int total_vertices;
} t_graph;
/*Graph functions*/
t_node *create_node(int vertex);
t_graph *create_graph(int vertices);
void add_edge(t_graph *graph, int src, int dst);
void bfs(t_graph *graph, int start_vertex);
/*Misc functions*/
void my_putstr(char *str);
void *my_memalloc(size_t size);
void *my_memset(void *ptr, int value, size_t num);
void my_bzero(void *s, size_t n);
/*Queue functions*/
t_queue *init_queue(void);
void enqueue(t_queue *queue, void *content);
void *dequeue(t_queue *queue);
void *peek_queue(t_queue *queue);
int is_empty(t_queue *queue);
void my_print_queue(t_queue *queue);
t_node *create_node(int val)
{
t_node *new_node;
new_node = (t_node*)my_memalloc(sizeof(t_node));
new_node->vertex = val;
new_node->next = NULL;
return (new_node);
}
t_graph *create_graph(int vertices)
{
int i;
t_graph *graph;
i = 0;
graph = my_memalloc(sizeof(t_graph));
graph->total_vertices = vertices;
printf("graph->total_vertices: %d\n", vertices);
graph->adj_lists = (t_node**)my_memalloc(sizeof(t_node));
graph->visited = my_memalloc(sizeof(int) * vertices);
while (i < vertices)
{
graph->adj_lists[i] = NULL;
graph->visited[i] = 0;
i++;
}
return (graph);
}
void add_edge(t_graph *graph, int src, int dst)
{
t_node *new_node;
new_node = create_node(dst);
new_node->next = graph->adj_lists[src];
graph->adj_lists[src] = new_node;
new_node = create_node(src);
new_node->next = graph->adj_lists[dst];
graph->adj_lists[dst] = new_node;
}
void bfs(t_graph *graph, int start_vertex)
{
t_queue *queue;
queue = init_queue();
graph->visited[start_vertex] = 1;
printf("start_vertex before enqueue %d\n", start_vertex);
my_print_queue(queue);
enqueue(queue, &start_vertex);
printf("start_vertex after enqueue %d\n", start_vertex);
while (!is_empty(queue))
{
my_print_queue(queue);
int current_vertex;
t_node *tmp;
current_vertex = (int)dequeue(queue);
printf("Visited %d nodes\n", current_vertex);
tmp = graph->adj_lists[current_vertex];
while (tmp)
{
int adj_vertex;
adj_vertex = tmp->vertex;
if (graph->visited[adj_vertex] == 0)
{
graph->visited[adj_vertex] = 1;
printf("%d\n", graph->visited[adj_vertex]);
enqueue(queue, &adj_vertex);
my_print_queue(queue);
}
tmp = tmp->next;
}
}
}
t_queue *init_queue(void)
{
t_queue *node;
node = (t_queue *)my_memalloc(sizeof(t_queue));
node->first = NULL;
node->last = NULL;
return (node);
}
void enqueue(t_queue *queue, void *content)
{
t_list *node;
node = (t_list *)my_memalloc(sizeof(t_list));
node->content = content;
node->next = NULL;
if (!queue->last)
{
queue->last = node;
queue->first = node;
}
else
{
queue->last->next = node;
queue->last = queue->last->next;
}
return ;
}
void *dequeue(t_queue *queue)
{
t_list *tmp;
tmp = queue->first;
if (!tmp)
return (NULL);
else
{
queue->first = tmp->next;
return (tmp->content);
}
}
void *peek_queue(t_queue *queue)
{
if (queue->first == NULL)
return (NULL);
return (queue->first->content);
}
int is_empty(t_queue *queue)
{
return (queue->first == NULL);
}
void my_print_queue(t_queue *queue)
{
if (is_empty(queue))
my_putstr("Empty queue\n");
else
{
while (!is_empty(queue))
{
int val = *(int *)queue->first->content;
printf("%d \n", val);
dequeue(queue);
}
}
}
void my_putstr(char *str)
{
int i;
i = 0;
while (str[i])
write(1, &str[i++], 1);
}
void *my_memalloc(size_t size)
{
char *str;
str = ((void*)malloc(size));
if (!str)
return (NULL);
my_bzero(str, size);
return (str);
}
void *my_memset(void *ptr, int value, size_t num)
{
unsigned char *uptr;
uptr = (unsigned char*)ptr;
while (num--)
*uptr++ = (unsigned char)value;
return (ptr);
}
void my_bzero(void *s, size_t n)
{
my_memset(s, 0, n);
}
int main(void)
{
t_graph *graph;
graph = create_graph(3);
add_edge(graph, 0, 1);
add_edge(graph, 0, 2);
add_edge(graph, 2, 4);
bfs(graph, 2);
return (0);
}
I did some research like type-casting a void pointer to make it into a char or int, or any other data type. What happens is that the create graph does it's creation after calling it; but, when it comes to the bfs, it doesn't show the correct output after. It never prints the visited vertices. I'm getting a result of
graph->total_vertices: 3
start_vertex before enqueue 2
Empty queue
start_vertex after enqueue 2
2
Visited 0 nodes
The expected output should be something like this:
Queue contains
0 Resetting queueVisited 0
Queue contains
2 1 Visited 2
Queue contains
1 4 Visited 1
Queue contains
4 Resetting queueVisited 4
I've been trying to figure out by myself to the point that I'm burning out. What am I doing wrong in here?
While posting this, I will keep debugging on my side and see what it does with a couple print statements.
I can point out the following mistakes:
my_print_queue destroys your queue. So anything after it's call works with empty queue.
You don't fill visited with to zeroes. By default their values is pretty much arbitrary. Since you compare their values with 0, it makes sense that comparison fails.
I get unexpected output in the code for the following problem:
Construct a complete (or almost complete) binary tree from given integer array.
Use a linked list representation of a queue.
Complete binary tree is full BT, and all leafs are on the same level.
Almost complete BT doesn't have to be full BT, and all leafs are on the same level.
Example 1: Almost Complete BT
arr[]={10,9,-5,1,2}
Tree:
10
/ \
9 -5
/ \
1 2
Example 2: Complete BT
arr[]={10,9,-5,1,2,7,4}
Tree:
10
/ \
9 -5
/ \ / \
1 2 7 4
Code
#include <stdio.h>
#include <stdlib.h>
typedef struct node_tree
{
int info;
struct node_tree *left,*right;
}TREE_NODE;
typedef struct node_queue
{
TREE_NODE *tn;
struct node_queue *next;
}QUEUE_NODE;
TREE_NODE *newTN(int info)
{
TREE_NODE *newN=(TREE_NODE*)malloc(sizeof(TREE_NODE));
newN->left=newN->right=0;
newN->info=info;
return newN;
}
void push_queueN(QUEUE_NODE **pf,QUEUE_NODE **pr,TREE_NODE *tn)
{
QUEUE_NODE *newQN=(QUEUE_NODE*)malloc(sizeof(QUEUE_NODE));
newQN->tn=tn;
newQN->next=0;
if(*pf==0)
*pf=*pr=newQN;
else
{
(*pr)->next=newQN;
*pr=newQN;
}
}
int pop_queueN(QUEUE_NODE **pf,QUEUE_NODE **pr,TREE_NODE **tn)
{
if(*pf==0)
return 0;
QUEUE_NODE *p=*pf;
*tn=p->tn;
if(*pf==*pr)
*pf=*pr=0;
else
*pf=p->next;
free(p);
return 1;
}
TREE_NODE *complete(int *arr,int n)
{
TREE_NODE *root;
QUEUE_NODE *pf=0,*pr=0;
int check=0,i;
int *p=arr;
if(p==NULL)
root=NULL;
root=newTN(arr[0]);
push_queueN(&pf,&pr,root);
p++;
for(i=0;i<n;i++)
{
TREE_NODE *parent=pf->tn;
if(pop_queueN(&pf,&pr,&parent))
check=1;
else
check=0;
TREE_NODE *leftChild=NULL,*rightChild=NULL;
leftChild=newTN(&p);
push_queueN(&pf,&pr,leftChild);
p++;
if(p)
{
rightChild=newTN(&p);
push_queueN(&pf,&pr,rightChild);
p++;
}
parent->left=leftChild;
parent->right=rightChild;
}
return root;
}
int height(TREE_NODE *root)
{
if(root==0)
return 0;
int hl=height(root->left);
int hr=height(root->right);
return 1+(hl>hr?hl:hr);
}
void printCurrLevel(TREE_NODE *root,int level)
{
if(root==0)
return;
if(level==1)
printf("%d",root->info);
else if(level>1)
{
printCurrLevel(root->left,level-1);
printCurrLevel(root->right,level-1);
}
}
void levelOrder(TREE_NODE *root)
{
int h=height(root),i;
for(i=1;i<=h;i++)
printCurrLevel(root,i);
}
int main()
{
int arr[]={10,9,-5,1,2};
int n=sizeof(arr)/sizeof(arr[0]);
TREE_NODE *root;
root=complete(arr,n);
levelOrder(root);
return 0;
}
There are some issues with pointers in function complete().
Could someone point out where are the possible errors?
#include<stdlib.h>
#include<stdio.h>
struct tree{char info;struct tree *left;struct tree *right;};
struct tree *root;
struct tree *stree(struct tree *root,struct tree *r,char info);
void print_tree(struct tree *root,int l);
int main(void)
{
char s[80];
root=NULL;
do {
printf("enter a letter:");
gets(s);
root=stree(root,root, *s);
}
while(*s); // <- ???
print_tree(root,0);
return 0;
}
struct tree *stree(struct tree *root,struct tree *r,char info;{ // <- ???
if(!r) {
r=(struct tree *) malloc(sizeof(struct tree));
if(!r) {
printf("out of memory \n");
exit(0);
}
r->left=NULL;
r->right=NULL;
r->info=info;
if(!root)
return r;
if(info<root->info)
root->left=r;
else
root->right=r;
return r;}if(info<r->info)stree(r,r->left,info);else
stree(r,r->right,info);return root;}
void print_tree(struct tree *r,int l);
{
int i;
if(!r) return ;
print_tree(r->right,l+1);
for(i=0;i<l;++i)
printf(" ");
printf("%c \n",r->info);
print_tree(r->left,l+1);
}
My guess is not the correct output is, because it is not been updated with the return value of stree.
E.g. if(info<r->info)stree(r,r->left,info); <-- It has been discarded return value.
Your code doesn't compile. So, I rewrite code.
#include <stdio.h>
#include <stdlib.h>
struct tree {
char info;
struct tree *left, *right;
};
struct tree *stree(struct tree *root, char info);//no need `struct tree *r`
void print_tree(struct tree *root, int level);
int main(void){
struct tree *root = NULL;//It does not need to be in a global variable
char letter;
for(;;){
printf("enter a letter:");
if(EOF == scanf("%c", &letter) || letter == '\n')//don't use `gets`
break;
scanf("%*[^\n]");//clear upto newline
scanf("%*c");
root = stree(root, letter);
}
print_tree(root, 0);
//deallocate
return 0;
}
struct tree *stree(struct tree *root, char info){
if(!root){
struct tree *r = malloc(sizeof(*r));
if(!r){
fprintf(stderr, "out of memory\n");
exit(EXIT_FAILURE);
}
r->right = r->left = NULL;
r->info = info;
return r;
}
if(info < root->info)
root->left = stree(root->left, info);
else if(info > root->info)
root->right = stree(root->right, info);
else
;//root->right = stree(root->right, info);
return root;
}
void print_tree(struct tree *r, int level){
if(!r) return ;
print_tree(r->right, level + 1);
printf("%*s%c\n", level, "", r->info);
print_tree(r->left, level + 1);
}
I've been working on some project with queue and priority queue, but I can't find a solution to a problem with priority queue. When a priority queue gets big it does not return me all the values I ask (to totalRegWait). I cut out the part where I only work with queue.
Any help regarding this question would be greatly appreciated.
Main
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "header.h"
int main()
{
ADT *attend; //Attendants
LINK *pQueue; //Priority queue
ADT *temp1; //Temporary
LINK *temp2; //Temporary
int regP; //Regular probability
int vipP; //VIP probability
int regA; //Regular attendants
int vipA; //VIP attendants
int sumA; //Combined attendants
int regT; //Regular time
int vipT; //VIP time
int bankT; //Bank working time
int i;
int attWait=0, attWait2=0; //Attendants wait time
int overtime=0, overtime2=0; //Attendants overtime
int totalRegWait=0, totalRegWait2=0; //Total regular client waiting time
int regCount=0; //Regular person count
int vipWait=0, vipWait2=0; //Maximum VIP waiting time
int vipCount=0; //Amount of VIP
getArguments(®P, &vipP, ®A, &vipA, ®T, &vipT, &bankT);
sumA=regA+vipA;
create(&attend);
for(i=0;i<sumA;i++){
enq(&attend, 0);
}
createEmpty(&pQueue);
srand(time(NULL));
for(i=0;i<bankT;i++){
if(rand()%100<regP){
regCount++;
add(&pQueue, 0, 0);
}
if(rand()%100<vipP){
vipCount++;
add(&pQueue, 1, 0);
}
//1st method
first(&attend, &pQueue, vipT, regT, &vipWait, &totalRegWait, &attWait);
}
printf("%d %d\n", regCount, vipCount);
printf("%d %d\n", totalRegWait, totalRegWait2);
//Printing results
printf("First method:\n");
printResults(attWait, overtime, totalRegWait, regCount, vipWait, vipCount);
return 0;
}
Functions
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
void createEmpty(LINK **head) {
(*head)=NULL;
}
void add(LINK **head, int p, DATA v){
LINK *curr=(*head);
LINK *beforeCurr=(*head);
LINK *newElement;
newElement=(LINK*)malloc(sizeof(LINK));
if(newElement==NULL){
printf("Error. Not enough memory to allocate.\n");
}
newElement->priority=p;
newElement->value=v;
newElement->next=NULL;
if((*head)==NULL){
(*head)=newElement;
}
else if(p<(*head)->priority){
newElement->next=curr;
(*head)=newElement;
}
else{
while(p>(curr->priority) && curr->next!=NULL){
beforeCurr=curr;
curr=curr->next;
}
if(curr->next==NULL && p>(curr->priority))
(curr->next)=newElement;
else if(curr==(*head)){
newElement->next=curr;
(*head)=newElement;
}
else{
beforeCurr->next=newElement;
newElement->next=curr;
}
}
}
void pop(LINK **head, int *p, DATA *v, int *error){
LINK *curr=(*head);
LINK *currB=(*head);
if(*head==NULL){
(*error)=1;
}
else if(curr->next==NULL){
(*p)=curr->priority;
(*v)=curr->value;
free(curr);
(*head)=NULL;
}
else{
while(curr->next!=NULL) {
currB=curr;
curr=curr->next;
}
(*p)=curr->priority;
(*v)=curr->value;
free(curr);
currB->next=NULL;
}
}
int checkIfEmpty(LINK *head){ //Working
if(head==NULL)
return 1;
else
return 0;
}
//-------------------------------
void create(ADT **front){ //Working
*front = NULL;
}
void enq(ADT **front, QDATA variable){ //Should be good
ADT *temp;
ADT *rear = (ADT *)malloc(sizeof(ADT));
if(rear==NULL){
printf("Error. Not enough memory to allocate.\n");
}
if(*front == NULL)
{
*front = (ADT *)malloc(sizeof(ADT));
if(*front==NULL){
printf("Error. Not enough memory to allocate.\n");
}
(*front)->var = variable;
(*front)->next = NULL;
}
else
{
temp = *front;
while(temp->next != NULL){
temp = temp->next;
}
rear->var = variable;
rear->next = NULL;
temp->next = rear;
}
}
//--------------------------------
void first(ADT **attend, LINK **pQueue, int vipT, int regT, int *vipWait, int *totalRegWait, int *attWait){
ADT *temp1;
LINK *temp2;
int priority;
DATA value;
int error=0;
if(checkIfEmpty(*pQueue)==1){ //If client's queue is empty, time is changed to attenders and increased att. waiting time
temp1=(*attend);
while(temp1 != NULL){
if((temp1->var)>0){
(temp1->var)--;
}
else{
(*attWait)++;
}
temp1 = temp1->next;
}
}
else{ //If there are clients, look for not occupied attenders
temp1=(*attend);
temp2=(*pQueue);
while(temp1 != NULL){ //While loop which goes through all the attenders
if((temp1->var)>0){ //If attender is busy
(temp1->var)--; //Yes, then it's value is decreased by 1
}
else{ //If attender value is not busy
if(checkIfEmpty(*pQueue)==1){ //Check if priority line is empty
(*attWait)++; //If yes, waiting time for attenders is added
}
else{ //If priority line is not empty
pop(&(*pQueue), &priority, &value, &error); //Client is removed from queue
printf("%d %d\n", priority, value);
if(error==1){ //If pop fails it shows an error and quit
printf("Error\n");
return 0;
}
else{ //If pop does not fail
if(priority==1){ //Check if client is VIP
temp1->var=vipT; //If yes, then attender is given VIP time to his value
if((*vipWait)<value){ //If VIP client's waiting time is higher than earlier value
(*vipWait)=value; //Earlier VIP waiting time is changed
}
}
if(priority==0){ //If client is regular
temp1->var=regT;
(*totalRegWait)=(*totalRegWait)+value; //Removed client's waiting value is added to a total value
(temp1->var)--;
}
(temp1->var)--; //Attender time is lowered by 1 (end of minute)
}
}
}
temp1 = temp1->next; //Going for another attender
}
if(checkIfEmpty(*pQueue)==0){ //Check if priority queue is empty
while(temp2!=NULL) {
(temp2->value)++; //Waiting time to a client is added
temp2 = temp2->next; //Next client
}
}
}
}
Header
#ifndef HEADER_H_
#define HEADER_H_
typedef int DATA;
typedef int QDATA;
typedef struct priorityQueue{
int priority;
DATA value;
struct priorityQueue *next;
}LINK;
typedef struct list
{
QDATA var;
struct list *next;
}ADT;
void enq(ADT **front, QDATA variable);
void create(ADT **front);
//PRIORITY QUEUE FUNCTIONS
void createEmpty(LINK **head);
void add(LINK **head, int p, DATA v);
void pop(LINK **head, int *p, DATA *v, int *error);
int checkIfEmpty(LINK *head);
//END OF PRIOR. QUEUE FUNCTIONS
void first(ADT **attend, LINK **pQueue, int vipT, int regT, int *vipWait, int *totalRegWait, int *attWait);
#endif
I apologise if this concept has been explained on SOF before! I believe my case is slightly different and couldn't find a similar question in the website.
Here's the problem:
I'm trying to store char arrays (strings) in a Queue structure that I'm trying to implement.
The structure and its functions seem to work fine when I hardcode the data myself like this:
#include "Time.h"
#include <unistd.h>
int main(void){
struct Queue* q = CreateQueue();
Enqueue(q, "element1");
Enqueue(q, "element2");
Enqueue(q, "element3");
Enqueue(q, "element4");
PrintAll(q->first); // this outputs all elements and the time they've been in the queue.
return 0;
}
The output is as expected, a list of all 4 elements.
However, as soon as I put a simple menu together, to capture the data from the user instead of it being hardcoded as above, the PrintAll() function outputs a duplicate of the very last element enqueued. You also notice that I am timing each node to keep a track on when it was added to the queue and that seem to work fine. Although the ouput shows the last element entered duplicated N times (N being the size of the queue) the timer seems to show correctly for each node!
I am suspecting it's to do with the stdin stream that is not being cleaned but I thought I handled that with a block of code that is shown in main() function.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void){
char name[31];
char c;
int option;
int ch;
struct Queue* q = CreateQueue();
do
{
printf("\n 1. Add a an element to the queue");
printf("\n 2. Print all elements");
printf("\n 0. Exit");
printf("\n Please select an option");
while(scanf("%d", &option)!=1){
puts("Value non good");
ch=getchar();
while(ch!=EOF && ch!='\n'){
ch=getchar();
}
}
switch(option)
{
case 1:
{
ch=getchar();
while(ch!=EOF && ch!='\n')
{
ch=getchar();
}
printf("Please enter the name of the element.\n ");
fgets(name,30,stdin);
Enqueue(q, name);
PrintAll(q->first);
break;
}
case 2:
{
PrintAll(q->last);
break;
}
default:
return 0;
}
}while(option != 0);
return 0;
}
Can anybody please shed light on the problem ? I would appreciate it.
here's the rest of the code:
Time.c:
#include "Time.h"
struct Queue* CreateQueue()
{
struct Queue* q = malloc(sizeof(struct Queue));
q->first = NULL;
q->last = NULL;
q->size = 0;
return q;
}
void Enqueue(struct Queue* queue, char* string)
{
struct Node* newNode = malloc(sizeof(struct Node));
newNode->next = NULL;
newNode->student = string;
newNode->start_time = time(0);
if(queue->size == 0)
{
queue->first = newNode;
}
else
{
queue->last->next = newNode;
}
queue->last = newNode;
queue->size = queue->size + 1;
}
char* Dequeue(struct Queue* queue)
{
if (queue->size < 0)
{
exit(0);
}
char* toBeRemoved = queue->first->student;
struct Node* oldNode = queue->first;
queue->first = oldNode->next;
queue->size = queue->size - 1;
if(queue->size == 0)
{
queue->last = NULL;
}
free(oldNode);
return toBeRemoved;
}
int IsEmpty(struct Queue *q)
{
return q->size == 0;
}
char* Peek(struct Queue *q)
{
return q->first->student;
}
void PrintOne(struct Node *node)
{
if(node !=NULL)
{
int elapsed = ElapsedTime(node);
printTime(elapsed, node->student);
//printf("%s\n", node->student);
}
}
void PrintAll(struct Node* node)
{
if (node !=NULL)
{
PrintAll(node->next);
PrintOne(node);
}
}
// returns the waiting time for a student node.
int ElapsedTime(struct Node* node)
{
int elapsed;
time_t stop_time;
stop_time = time(NULL);
elapsed = difftime( stop_time , node->start_time );
return elapsed;
}
void printTime(int elapsed, char* student_name)
{
printf("%s : waiting for ", student_name);
int minutes_or_hours = 0; //Stores a zero to indicate that it is not neccesary to print minutes or hours.
//Stores a one to indicate that hours and/or minutes have been printed.
if( (elapsed / 3600) >= 1)
{
int hours = elapsed/3600;
if(hours == 1)
{
printf("1 hour, ");
}
else
{
printf("%d hours, ", hours);
}
elapsed = elapsed - (hours*3600);
minutes_or_hours = 1;
}
if( (elapsed / 60) >= 1)
{
int minutes = elapsed/60;
if(minutes == 1)
{
printf("1 minute, ");
}
else
{
printf("%d minutes, ", minutes);
}
minutes_or_hours = 1;
elapsed = elapsed - (minutes*60);
}
if(minutes_or_hours == 1)
{
printf("and ");
}
printf("%d seconds\n", elapsed);
}
Time.h:
#ifndef TIME_H_
#define TIME_H_
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Node
{
time_t start_time;
struct Node* next;
char* student;
};
struct Queue
{
int size;
struct Node* first;
struct Node* last;
};
struct Queue* CreateQueue();
void Enqueue(struct Queue* , char* );
char* Dequeue(struct Queue* );
int IsEmpty(struct Queue *);
char* Peek(struct Queue *);
void PrintOne(struct Node *);
void PrintAll(struct Node *);
int ElapsedTime(struct Node* );
void printTime(int , char* );
#endif /* TIME_H_ */
In the function Enqueue() you have only copied the string pointer to your structure. In your first case that works, because all the four strings have different pointers to string literals. But in your second example, you are storing the pointer of your data entry name, and the contents of this string change with each entry. Each structure store the same pointer, so all point to the most recent string you typed in. If your struct stored the actual string, it would work (but you need to be careful with string lengths).
struct Node
{
time_t start_time;
struct Node* next;
char student[31];
};
void Enqueue(struct Queue* queue, char* string)
{
...
strncpy (newNode->student, 30, string);
...
}