Data structure, pointers - c

I made a queue in C using pointers, my code works but I can not understand how the pointer variable rear1 is works, because every time function called, rear1 is initialized and same for front, front store the address of start for first time then after front reinitialize but it still keep start address, how is it possible.
#include <stdio.h>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, ("pause") or input loop */
struct node
{
int data;
struct node *next;
};
enqueue(struct node **start)
{
struct node *front,*rear;
if (*start==NULL)
{
*start=(struct node *)malloc(sizeof(struct node));
scanf("%d",&(*start)->data);
(*start)->next=NULL;
printf("%s","hello");
front=(*start);
rear=*start;
}
else
{
printf("%d",front->data);
struct node *temp,*curr;
curr=(struct node *)malloc(sizeof(struct node));
rear->next=curr;
rear=curr;
rear->next=NULL;
scanf("%d",&rear->data);
}
}
dequeue(struct node **front)
{
struct node *temp;
temp=(*front);
(*front)=(*front)->next;
printf("%d",(temp->data));
free(temp);
}
int main(int argc, char *argv[])
{
struct node *start=NULL;
enqueue(&start);
enqueue(&start);
enqueue(&start);
enqueue(&start);
enqueue(&start);
enqueue(&start);
dequeue(&start);
printf("\n");
dequeue(&start);
printf("\n");
dequeue(&start);
printf("\n");
dequeue(&start);
printf("\n");
dequeue(&start);
printf("\n");
dequeue(&start);
return 0;
}

Actually, this code shouldn't work, or has undefined behaviour.
enqueue(struct node **start)
{
struct node *front,*rear;
if (*start==NULL)
{
*start=(struct node *)malloc(sizeof(struct node));
scanf("%d",&(*start)->data);
(*start)->next=NULL;
printf("%s","hello");
front=(*start);
rear=*start;
}
else
{
printf("%d",front->data);
struct node *temp,*curr;
curr=(struct node *)malloc(sizeof(struct node));
rear->next=curr;
rear=curr;
rear->next=NULL;
scanf("%d",&rear->data);
}
}
Here, when *start is defined, you assign curr to rear->next, but rear is undefined. You have 2 solutions:
Using rear as a static variable (which is clearly not a good solution, especially if you want to use multiple queues)
Using 2 struct in your main, Start and End.
I think you use front and rear as if they were static, but by default, a variable "disappear" at the end of the function where it was declared. It's a new undefined variable at each call of the function.

Related

Linked list always show empty

REQUIREMENT / QUESTION 2
In computing, the process identifier (normally referred to as the process ID or PID), is a number used by most operating system kernels, to uniquely identify an active process. The PIDs are usually allocated on a sequential basis, beginning with 0 and rising to a maximum value that varies from system to system. Create a link list to store the PIDs. To create a new PID, createPID() function is used.
Each PID is inserted into the list at the beginning of the list, using insertPID() function. Once a process is completed, that particular PID is deleted, using the deletePID() function.
The assessment will be done based on the following criteria:
A proper writing of C codes and its structure
The ability of program to be compiled and executed
Implementation of correct programming techniques
Complete documentation and correct submission
Note: You must write C programming codes for this assignment.
I already create a code:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int info;
struct node *link;
};
void createPID ();
void insertPID (struct node *start,int x);
struct node * deletePID (struct node * start,int x);
void displayPID(struct node *start);
struct node * start;
int main()
{
createPID();
insertPID(start,0);
insertPID(start,1);
insertPID(start,2);
displayPID(start);
start=deletePID(start, 3);
displayPID(start);
}
void createPID(){
struct node *start = NULL;
}
void displayPID(struct node *start)
{
struct node *p;
if(start == NULL)
{
printf("List is empty\n");
return;
}
printf("List is :");
p=start;
while(p!=NULL)
{
printf("%d\t",p->info);
p=p->link;
}
printf("\n");
}
/*End of displayList()*/
void insertPID(struct node * start, int data)
{
struct node *temp,*p;
p=start;
while (p!=NULL)
{
if(p->link==NULL)
break;
p=p->link;
}
temp=(struct node *)malloc (sizeof (struct node));
temp->info=data;
if(p==NULL)
start=temp;
else
{
temp->link= p->link;
p->link= temp;
}
}
struct node* deletePID(struct node * start,int x){
struct node *temp, *p;
if(start == NULL)
{
printf("List is empty\n");
return start;
}
/*Deletion of first node */
if(start->info == x)
{
temp=start;
start= start->link;
free(temp);
return start;
}
/*Deletion in between or at the end */
p=start;
while (p->link != NULL)
{
if (p-> link -> info== x)
break;
p=p-> link;
}
if(p->link==NULL)
printf("Element %d not in list \n\n",x);
else
{
temp=p->link;
p->link=temp->link;
free (temp);
}
return start;
}
The result always empty list. Need help to figure out what is the problem ?
Problem is in insertPID function. start as argument of function is local variable, it hides global start and the line below
start = temp;
only modifies local start, global start is not affected and it is always NULL.
If you want to update start pointer you need to pass it by pointer-to-pointer:
void insertPID (struct node **start,int x);
//...
insertPID(&start,0);
insertPID(&start,1);
insertPID(&start,2);
//...
void insertPID(struct node ** start, int data)
{
//...
p=*start;
//...
if(p==NULL)
*start=temp;
//...
}
void createPID(){
struct node *start = NULL;
}
I assume this function wants to set start (global) to 0 ? So it should be:
void createPID(){
start = NULL;
}
Your version introduces local start variable, so global is not affected.
But the call of createPID is superfluous here because start as global variable is initialized to 0 before main starts executing.

BINARY SEARCH TREE creation

i have written a simple code to create and insert elements into a binary search tree, when i write the code in the following manner, the chaining doesn't seem to happen, can anybody help me understand what exactly is happening in the insert function ? I know the code to insert elements into a binary search tree, just curious to know why this one doesn't work.
#include <stdio.h>
#include<stdlib.h>
struct node {
struct node *left;
struct node* right;
int element;
};
void insert(struct node *node,int x) {
if(node==NULL) {
node=(struct node *)malloc(sizeof(struct node));
node->element=x;
node->left=NULL;
node->right=NULL;
} else {
if(x<node->element) {
insert(node->left,x);}
else {
insert(node->right,x);
}
}
}
void inorder(struct node *base) {
if(base!=NULL) {
inorder(base->left);
printf("%d ",base->element);
inorder(base->right);
}
}
int main(int argc, char *argv[]) {
struct node *base;
base=(struct node *)malloc(sizeof(struct node));
base->element=1;
base->left=NULL;
base->right=NULL;
insert(base,25);
insert(base,30);
inorder(base);
return 0;
}
if the insert function is written this way, it works but still doesn't work for creation of the first node of the binary search tree, confused :/
void insert2(struct node *node,int x) {
if(node==NULL) {
node=(struct node *)malloc(sizeof(struct node));
node->element=x;
node->left=NULL;
node->right=NULL;
} else {
if(x<node->element) {
if(node->left==NULL) {
node->left=(struct node *)malloc(sizeof(struct node));
node->left->element=x;
node->left->left=NULL;
node->left->right=NULL;
} else {
insert2(node->left,x);
}
} else {
if(node->right==NULL) {
node->right=(struct node *)malloc(sizeof(struct node));
node->right->element=x;
node->right->left=NULL;
node->right->right=NULL;
} else {
insert2(node->right,x);
}
}
}
}
When you pass a value to a function in C, you're using pass-by-value. What that means is the value gets copied into another variable which becomes local to the function.
void change(struct node *n) {
n = 42;
}
int main(void) {
change(NULL); // change can't change the value of NULL, can it?
}
Now take a look at your insert function... Suppose I call insert(NULL,42);, do you think insert is trying to change NULL? Or is it trying to change some local variable, which your main function can't see?
You know what needs to be done already... Either make your insert function use an extra level of pointer indirection as you've suggested in your comments, or return the root node from insert so that you can propagate the changes made by insert into the data structure stored in main (using the assignment = operator).
C is pass-by-value. When you pass something into a function's parameter, the function makes a copy of it. So when you pass a struct node pointer into the insert function, C makes a copy of that pointer.
What you did in main is first you made a struct node* base:
base --> struct node.
When you call insert(base, 25), C makes a copy of base. So now in your memory you have something like this:
basecpy ---> [struct node] <--- base
So in your insert, you are essentially doing
if(basecpy==NULL)
{basecpy=(struct node *)malloc(sizeof(struct node));
basecpy->element=x;
basecpy->left=NULL;
basecpy->right=NULL;}
Which does not change base in anyway at all - it just changes basecpy.
This can be solved by using double pointers:
void insert(struct node **node, int x) {
if (*node == NULL) {
*node = malloc(sizeof(*node));
(*node)->element=x;
(*node)->left=NULL;
(*node)->right=NULL;
} else {
if (x < (*node)->element) {
insert(&((*node)->left), x);
} else {
insert(&((*node)->right), x);
}
}
}
And then to use it, pass in the address of base.
insert(&base, 25);
Pointers can be tricky :)
ideone

Passing an uninitialized struct to a function, why is it not null?

I've been scratching my head quite a while at this one. I'm creating my node without any values (and even tried initializing it and a pointer and set it = NULL), but when I get inside the insert function head_ does not evaluate to NULL. I can check for head_->id = NULL but I don't think I should have to do that. Any ideas on what I'm doing wrong? I'm trying to build and traverse a linked list and am certainly not off to a good start! The output is:
head_ =
not null!?
#include <stdio.h>
#include <stdlib.h>
struct node{
int id;
struct node *next;
};
int main(void){
struct node head;
int entered_id;
insert(&head, 1);
}
void insert(struct node* head_, int new_id){
printf("\nhead_ = %s", head_);
if(!head_){
printf("\nnull");
}
else
printf("\nnot null!?");
fflush(stdout);
}
#include <stdio.h>
#include <stdlib.h>
struct node{
int id;
struct node *next;
};
int main(void){
struct node * head = NULL; // create a pointer instead of declaring structure variable
int entered_id;
insert(head, 1);
}
void insert(struct node* head_, int new_id){
// printf("\nhead_ = %s", head_); can you print structure as string?
if(!head_){
printf("\nnull");
}
else
printf("\nnot null!?");
fflush(stdout);
}
If you use struct node head, it will create an object which occupies space and so is not NULL. What you want is a pointer to an object which initially points to nothing and so is null.
The struct is not a pointer to null because it was allocated. If it were declared as:
struct node *head;
then, it would possibly point to NULL, but its not defined.
struct node *head = NULL;
would guarantee its pointing to NULL. Even in that case, you can't allocate it in another function that way. If you in insert did
head = malloc(sizeof(struct node));
then, when main came back, head would still be NULL, and you would have a memory leak.
The way it is defined,
struct node head; //allocates sizeof(struct node) bytes on the stack of main, which is destroyed after main exits.
Make sense?

Insert in Linked List C

I am working on a simple text editor in C. I am having troubles with inserting an element in a linked list.
Here is my structure:
struct node {
struct node *previous;
int c;
int x;
int y;
struct node *next;
}*head;
Here is my insertion code:
void checker(int ch, int xpos, int ypos)
{
int flag=0;
struct node *temp,*temp1,*insert_node=NULL;
temp=(struct node *)malloc(sizeof(struct node));
temp=head;
while(temp!=NULL)
{
if(temp->x==xpos && temp->y==ypos)
{
insert_node->c=ch;
insert_node->x=xpos;
insert_node->y=ypos;
if(temp->previous==NULL) //this is for inserting at the first
{
insert_node->next=temp;
head=insert_node;
}
else //this is for inserting in the middle.
{
temp1=temp;
temp=insert_node;
insert_node->next=temp1;
}
flag=1;
break;
}
temp=temp->next;
}
//this one's for the normal insertion and the end of the linked list.
if(flag==0)
characters(ch,xpos,ypos);
}
None of the inserting in the first and middle works. I do not know where it went wrong. Please help me.
temp=(struct node *)malloc(sizeof(struct node));
temp=head;
You are allocating space for a new node, but then you loose the address of this new node assigning temp=head.
The problem is that insert_node is a local variable in your function checker() which is also initialized as NULL. Doing insert_node->c means NULL->c which i'm sure you'll agree with me that is wrong.
Try to dynamically allocate memory for your variables before using them and you should be fine.
insert_node will always be NULL in the code you posted.
Also, you may want to split your code more; start by isolating part of it in a find() function.

Simple linked list with random values

Okay so here's the task: Implement a list with 25 ordered random integers between 0 and 100.
My approach: get 25 numbers in an array, order the array and create the list with the array elements.
#include <conio.h>
#include <malloc.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
struct Node{
int data;
struct Node *next;
};
int main()
{
struct Node *p=NULL;
struct Node *q=NULL;
int j,i,aux,n,v[25];
for (i=0;i<25;i++)
{
v[i]=rand()%100;
}
for (i=0;i<25;i++)
{
for (j=1;j<25;j++)
{
if (v[i]>v[j])
{
aux=v[i];
v[i]=v[j];
v[j]=v[i];
}
}
}
q=(Node *)malloc(sizeof(struct Node));
q->data=v[0];
q->next=NULL;
for (i=1;i<25;i++)
{
p=(Node *)malloc(sizeof(struct Node));
q->next=p;
p->data=v[i];
p->next=NULL;
q=p;
}
while (p)
{
printf("%d ",p->data);
p=p->next;
}
}
Output: 0.
Can you guys figure out what I did wrong ?
There's a number of things wrong... but the primary one (that's causing all 0's) is here:
if (v[i]>v[j])
{
aux=v[i];
v[i]=v[j];
v[j]=v[i];
}
Your swap is incorrect, you store v[i]'s data in aux, but you never set it to v[j], so you're just overwriting everything with the smallest value (0)
You wanted:
v[j] = aux;
The other major issue is you're not keeping track of the "head" of your list:
p=(struct Node *)malloc(sizeof(struct Node));
q->next=p;
p->data=v[i];
p->next=NULL;
q=p;
You keep assigning a new value to p, then overwritting q with p... so there's no way to find your way back. You'll only have the last value in your linked list
Something like:
struct Node* head = NULL;
...
head = q=(Node *)malloc(sizeof(struct Node)); // head points to the first node now
Then later:
p = head; // reset p to the start of the list.
while (p)
{
...
You don't need to set up all this array stuff; the fragment below returns a linked list of N=cnt Nodes with random payload:
struct Node *getnrandom(unsigned cnt) {
struct Node *p=NULL, **pp;
for (pp=&p; cnt--; pp = &(*pp)->next) {
*pp = malloc (sizeof **pp);
if (!*pp) break;
(*pp)->data = rand();
}
if (*pp) (*pp)->next = NULL;
return p;
}
UPDATE: since the OP appears to need the values to be ordered, he could either perform insertion (at the right position) into the llist (N*N) , or sort it post hoc. (NlogN)

Resources