For Example: I have a linked list: 4->1->0->2->3 and then i want to rotate my list and get this output: 1->0->2->3->4, the first node to be a last node. But when i'm trying to make this i get out this result: 1->0->2->3->0->4. What happend i could not debug it.
#ifndef HEADER_PUSH_SWAP_H
# define HEADER_PUSH_SWAP_H
# include "../libft/libft.h"
# include "../ft_printf/include/ft_printf.h"
typedef struct s_stack
{
int n;
struct s_stack *next;
} Stack;
typedef struct s_actions
{
void (*pa)(Stack **a, Stack **b);
void (*pb)(Stack **a, Stack **b);
void (*sa)(Stack **a, Stack *x);
void (*sb)(Stack **b, Stack *x);
void (*ss)(Stack **a, Stack *x, Stack **b, Stack *y);
void (*ra)(Stack **a);
void (*rb)(Stack **b);
void (*rr)(void);
void (*rra)(void);
void (*rrb)(void);
void (*rrr)(void);
} Actions;
typedef struct s_important
{
int size;
int length;
int *collection_of_ints;
char *collection;
char **split;
int a_len;
int b_len;
} t_important;
Actions init(void);
//parser functions
void stack_nums_counter(char **av, t_important *data);
void collect(char **av, t_important *data);
void store(Stack **a, t_important *data);
//Helpers
void __collecting_ints(t_important *data);
void __sorted__indacies(t_important *data);
void ___bubble___(int *arrtmp, int length);
void __store__(t_important *data);
int is_sorted(int *ints, int len);
int __repeats__(t_important *data);
int __check__collection(t_important *data);
//Error functions
int errno(char *err);
//sorting algorithm functions
void __sort_a__(Stack **a, Stack **b, t_important *data, Actions action);
void pa(Stack **a, Stack **b);
void pb(Stack **a, Stack **b);
void sa(Stack **a, Stack *x);
void sb(Stack **b, Stack *x);
void ss(Stack **a, Stack *x, Stack **b, Stack *y);
void ra(Stack **a);
void rb(Stack **b);
void rr(void);
void rra(void);
void rrb(void);
void rrr(void);
int check_stack_length(Stack *stack);
#endif
Store Function to store data in nodes. It was called in main function before sort_a() function
void store(Stack **a, t_important *data)
{
int i;
Stack *tmp;
tmp = *a;
(*a)->next = tmp;
i = 0;
while(i < data->length)
{
tmp->n = data->collection_of_ints[i];
tmp->next = malloc(sizeof(Stack));
tmp = tmp->next;
i++;
}
tmp->next = NULL;
}
Main Function In where i call sort_a() function on the last line of code.
#include "../includes/header_push_swap.h"
int main(int ac, char **av)
{
Actions action;
Stack *a;
Stack *b;
t_important *data;
if(ac < 2)
return (-1);
data = malloc(sizeof(*data));
stack_nums_counter(av, data);
collect(av, data);
__check__collection(data);
__collecting_ints(data);
action = init();
a = malloc(sizeof(*a));
b = malloc(sizeof(*b));
store(&a, data);
__sort_a__(&a, &b, data, action);
return (0);
}
Sorting Function In where i do someting:
Input
4->1->0->2->3
#include "../includes/header_push_swap.h"
void __sort_a__(Stack **a, Stack **b, t_important *data, Actions action)
{
action.ra(a);
while((*a) != NULL)
{
ft_printf("%d ", (*a)->n);
*a = (*a)->next;
}
}
Output
1->0->2->3->0->4
Rotate Function:
void ra(Stack **a)
{
Stack *first = *a;
Stack *last = *a;
if(check_stack_length(*a) <= 1)
return ;
while(last->next != NULL)
last = last->next;
*a = first->next;
first->next = NULL;
last->next = first;
}
Your code to rotate the list seems correct. Yet the code to print the list is somewhat disturbing: why do you modify *a? You should just use a Stack pointer and follow the links.
Modify your program to print the list before and after the rotation using this modified version:
void rotate_stack(Stack **a) {
Stack *first = *a;
Stack *last = first;
if (first != NULL && first->next != NULL) {
while (last->next != NULL)
last = last->next;
*a = first->next;
first->next = NULL;
last->next = first;
}
}
void print_stack(const Stack *s) {
while (s != NULL) {
ft_printf("%d ", s->n);
s = s->next;
}
ft_printf("\n");
}
int main() {
Stack *s = NULL;
// construct the stack
[...]
print_stack(s);
rotate_stack(&s);
print_stack(s);
return 0;
}
Related
why i am getting stack is empty every time?
I am trying to make a expression tree from postfix here.
what's the logical error here?? plus we are not allowed to declare any variable globally. so, i had to pass the stackarray and node every time in each time function calling.
i am posting the full code done by me please have a look, i know its might be a simple error but as a beginner please show some kindness.
please help. TIA :)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE 10
struct ExpnTreeNode
{
struct ExpnTreeNode *lchild;
char data;
struct ExpnTreeNode *rchild;
};
struct stackarray
{
struct ExpnTreeNode *data[MAXSIZE];
int top;
};
void push(struct ExpnTreeNode *newnode, struct stackarray *s);
struct ExpnTreeNode* pop( struct stackarray *s);
int check(char c);
void operand(struct ExpnTreeNode *newnode,char m, struct stackarray *s);
void operators(struct ExpnTreeNode *newnode,char m, struct stackarray *s);
void printex(struct ExpnTreeNode *node);
int main(void)
{
struct ExpnTreeNode *p=NULL;
struct stackarray s={{NULL},-1} ;
int len;
int x;
int res;
int i;
char arr[30]={'\0'};
printf("\n\tEnter a postfix expression:");
scanf("%d",&arr);
struct ExpnTreeNode *newnode=NULL;
len=strlen(arr);
for(i=0;arr[i]!='\0';i++)
{
x=check(arr[i]);
if(x==1)
{
operand(newnode,arr[i],&s);
}
else if(x==2)
{
operators(newnode,arr[i],&s);
}
}
p=pop(&s);
printex(p);
return 0;
}
void push(struct ExpnTreeNode *newnode, struct stackarray *s)
{
if(s->top==MAXSIZE-1)
{
printf("\n\tStack is Full");//Stack is Full
}
else
{
s->top=s->top+1;
s->data[s->top]=newnode;
}
}
struct ExpnTreeNode* pop( struct stackarray *s)
{
if(s->top==-1)
{
printf("\n\tStack is Empty");
return;
}
s->top=s->top-1;
return(s->data[s->top]);
}
int check(char c)
{
if(c=='*' || c=='/' || c=='+' || c=='-')
{
return 2;
}
else
{
return 1;
}
}
void operand(struct ExpnTreeNode *newnode,char m, struct stackarray *s)
{
struct stack *fs=NULL;
fs=s;
newnode=(struct ExpnTreeNode *)calloc(1,sizeof(struct ExpnTreeNode));
newnode->data=m;
newnode->lchild=NULL;
newnode->rchild=NULL;
push(newnode,&fs);
}
void operators(struct ExpnTreeNode *newnode,char m, struct stackarray *s)
{
newnode=(struct ExpnTreeNode *)calloc(1,sizeof(struct ExpnTreeNode));
struct stack *fs=NULL;
fs=s;
newnode->data=m;
newnode->rchild=pop(&fs);
newnode->lchild=pop(&fs);
push(newnode,&fs);
}
void printex(struct ExpnTreeNode *node)
{
if(node!=NULL)
{
printf("\n\t%c",node->data);
printex(node->lchild);
printex(node->rchild);
}
}
I am trying to bubble sort linkedlist based on int value which I hold in char array.
I know that I need to do following steps;
void bubbleSort(struct Node *start)
{
int swapped, i;
struct Node *ptr1;
struct Node *lptr = NULL;
/* Checking for empty list */
if (start == NULL)
return;
do
{
swapped = 0;
ptr1 = start;
while (ptr1->next != lptr)
{
if (ptr1->data > ptr1->next->data)
{
swap(ptr1, ptr1->next);
swapped = 1;
}
ptr1 = ptr1->next;
}
lptr = ptr1;
}
while (swapped);
}
and
/* function to swap data of two nodes a and b*/
{
int temp = a->data;
a->data = b->data;
b->data = temp;
}
but as I said above I have created a struct with char value;
struct nodeForLinkedList
{
char frequency[STRING_LEN]; **// Purpose of this is to hold int value from text file.**
struct nodeForLinkedList *next;
};
void swap(struct nodeForLinkedList *a, struct nodeForLinkedList *b)
{
char temp = a->frequency;
a->frequency = b->frequency; // atoi(b->frequency) or strtol
b->frequency = temp;
}
here I could use atoi function to get int value from char array. atoi function help me to get int value from 'frequency' array
But I don't know how to change a->frequency value with b->frequency value.
Any help would be appreciated
Thanks in advance
The simplest solution is to use one of the string or memory copying functions from the library:
#include <string.h>
void swap(struct nodeForLinkedList *a, struct nodeForLinkedList *b)
{
char temp[sizeof(a->frequency)];
strcpy(temp, a->frequency);
strcpy(a->frequency, b->frequency);
strcpy(b->frequency, temp);
}
The above use of strcpy assumes that the frequency member contains a null-terminated string. You could use memcpy to copy the whole array regardless of null-termination:
#include <string.h>
void swap(struct nodeForLinkedList *a, struct nodeForLinkedList *b)
{
char temp[sizeof(a->frequency)];
memcpy(temp, a->frequency, sizeof(temp));
memcpy(a->frequency, b->frequency, sizeof(temp));
memcpy(b->frequency, temp, sizeof(temp));
}
I have generic link list in C that know how to push struct to list.
The problem is the I can't implement generic search in those link list:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
struct Node
{
void *data;
struct Node *next;
};
void push(struct Node** head_ref, void *new_data, size_t data_size)
{
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = malloc(data_size);
new_node->next = (*head_ref);
int i;
for (i=0; i<data_size; i++)
*(char *)(new_node->data + i) = *(char *)(new_data + i);
(*head_ref) = new_node;
}
struct A
{
int a1;
long a2;
};
struct B
{
long b1;
int b2;
};
void find_a1_in_a_list (int desire_a1 , struct Node *a_list)
{
struct A *a;
while(NULL != a_list)
{
a = (struct A*) a_list->data;
if(a->a1 == desire_a1)
printf("found!\n");
a_list = a_list->next;
}
}
void find_b1_in_b_list (long desire_b1 , struct Node *b_list)
{
struct B *b;
while(NULL != b_list)
{
b = (struct B*) b_list->data;
if(b->b1 == desire_b1)
printf("found!\n");
b_list = b_list->next;
}
}
void find_generic (void* desire_value,int off,struct Node *list)
{
while(NULL != list)
{
void* check_value_void = list->data + off;
int check_value_cast = *(int *) check_value_void; //How to know if cast to int or long ?????
if(check_value_cast == *(int *)desire_value) //How to know if cast to int or long ?????
printf("found generic!\n");
list = list->next;
}
}
void main()
{
struct Node *a_list = NULL;
struct A a;
a.a1=1;
a.a2=2;
push(&a_list, &a, sizeof(struct A));
find_a1_in_a_list(1,a_list);
struct Node *b_list = NULL;
struct B b;
b.b1=1;
b.b2=2;
push(&b_list, &b, sizeof(struct B));
find_b1_in_b_list(1,b_list);
//tried to make it generic
int search = 3;
find_generic(&search,offsetof(struct A, a2),a_list);
}
As you can I tried to makes generic search in function find_generic by passing the offset to the value in struct, that code works but only for int
but how can I pass to this generic function if I want to search int or long ,so I will know how to makes cast ?
Is there any way to cast void * by size so I can pass sizeof(int) or sizeof(long) and makes the casting by this value? or maybe another way?
Passing the compare function directly instead of playing with offsetof/sizeof will be more flexible:
struct Node *find_generic (struct Node *list,
int (*fn_cmp)(void const *a, void const *b),
void const *data)
{
while (list) {
if (fn_cmp(list->data, data) == 0)
break;
list = list->next;
}
return list;
}
and then create custom compare functions
static int cmp_A(void const *a_, void const *b_)
{
struct A const *a = a_;
struct A const *b = b_;
if (a->a1 == b->a1 && a->a2 == b->a2)
return 0;
return 1;
}
and call it like
struct A key = {
.a1 = 23,
.a2 = 42,
};
find_generic(a_list, cmp_A, &key);
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 tried making a Stack that contains Pointers(meaning adresses) that point to some other kind of structs(Prof or Stud). But I can't seem to manage it. The errors were infinite. Here's the code:
struct MyStack
{
int head;
void **stack;
int size;
};
struct stud
{
char flag;
char fname[50];
int semester;
};
struct prof
{
char flag;
char fname[50];
char course[30];
};
int InitStack(int size,struct MyStack *stack);
int InitStack(int size,struct MyStack *stack)
{
stack->size = size;
*stack->stack=(int *) malloc(size*sizeof(int) ); //Is this RIGHT?
stack->head=-1;
return 0;
}
int main()
{
int size,sel;
size = GiveSize();
struct MyStack NewStack;
InitStack(size,&NewStack);
do{
sel=Menu();
Select(sel,NewStack.head,&NewStack);
}while (sel!=0);
return 0;
}
How I can push pointers(that point to studs and profs) to the stack?
Heres the code:
int CreateStud(struct MyStack *stack,char *name,int sem,int *head,int n)
{
struct stud newStud;
int thead=*head;
newStud.flag='s';
strcpy(newStud.fname,name);
newStud.semester=sem;
Push(stack,&thead,&newStud,n);
*head=thead;
return 0;
}
int Push(struct MyStack *stack,int *head, void *elem,int n)
{
if(*head>=n-1)
return 0;
stack->stack[++*head]=elem;
return 1;
}
Your InitStack function should be
int InitStack(int size,struct MyStack *stack)
{
stack->size = size;
stack->stack= malloc(size * sizeof(void*));
stack->head=-1;
return 0;
}
The push function should be something like
int Push(struct MyStack *stack, void *str)
{
/* Check if stack is full */
stack->head++;
stack->stack[stack->head] = str;
return 0;
}
The you can use it as
struct stud s1;
struct prof p1;
Push(&NewStack, &s1);
Push(&NewStack, &p1);