Insert in Linked List C - 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.

Related

Data structure, pointers

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.

Creating two link list using one function

This is a program to print two link lists using one function.
I have used two functions i.e create and display.Create() is to create the linklist and display() to display the result of linklist.
But this code is printing NULL. I'm not not getting where is the error???
`#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node* next;
}
*start=NULL,*start1=NULL;
//to create the linklist
struct node* create(struct node* ptr)
{ int ch;
do
{
struct node* new_node=(struct node*)malloc(sizeof(struct node));
struct node* current;
printf("enter the data\n");
scanf("%d",&new_node->data);
new_node->next=NULL;
if(ptr==NULL)
{
ptr=new_node;
current=new_node;
}
else
{
current->next=new_node;
current=new_node;
}
printf("Do u want to add more ");
scanf("%d",&ch);
}while(ch!=0);
return ptr;
}
//to display the linklist
void display(struct node* temp)
{
while(temp!=NULL)
{
printf("%d--->",temp->data);
temp=temp->next;
}
printf("NULL\n");
}
int main()
{
clrscr();
create(start);
display(start);
printf("\n 2nd linklist\n");
create(start1);
display(start1);
getch();
return 0;
}
First problem
current must be declared outside the do/while loop, otherwise you will get undefined behaviour because there is no guarantee that current will keep it'svalue from one iteration to the next. However with certain compilers you may get away with it.
Second problem
Calling create(start); will not modify start because variables in C are passed by value. You need to write start = create(start);. See also this SO question. In your program start is still NULL after the call to the create function. You could have found out that easily by yourself.

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

linked list implementation using pointer to pointer in C

I am unable to append a new node in the linked list. I have already identified the problem area but after much research and trying many things I am still unable to resolve the issue.
The problem is with the for loop in insert_node(char,struct **) function and traverse(struct *) function both of which never seem to terminate:
// program that stores name of the user using linkedlist
#include<stdio.h>
#include<stdlib.h>
typedef struct LIST{
int flag;
char name;
struct LIST *next;
} LISTNODE;
LISTNODE *head=NULL,*newnode=NULL;// global pointers
LISTNODE* initialize(); //initializes struct node with default values and returns a node
void insertNode(char c,LISTNODE** temp);
void traverselist(LISTNODE *temp);
int main(){
char ans,ch;
printf("\n\nEnter your name and hit enter-\n\n");
do{
printf("your name:");
fflush(stdin);
scanf("%c",&ch);
insertNode(ch,&head);
printf("\n\ninsertnode-back to main()");
printf("Want to continue?(Y?N):");
fflush(stdin);
scanf("%c",&ans);
}while(ans=='y'||ans=='Y');
printf("\n\ntraverselist-leaving main()");
traverselist(head);
printf("\n\ntraverselist-back to main()");
return 0;
}
void insertNode(char c, LISTNODE **temp){
printf("\n\ninto insertnode: before initialize");
LISTNODE* temp2;
newnode=initialize();
printf("\n\nback to insertnode:after initialize");
//printf("\nnewnode->name=%c",newnode->name);
//printf("\nnewnode->flag=%d",newnode->flag);
newnode->name=c;
//printf("\nnewnode->name=%c",newnode->name);
//printf("\nnewnode->flag=%d",newnode->flag);
//for(;(*temp)!=NULL;temp=&(*temp)->next);
/*while((*temp)->next!=NULL){
temp=&(*temp)->next;
printf("\n\nIn while!");
}
*/
for(;*temp!=NULL;temp=&((*temp)->next))
printf("\n\nIn for!") ;
//printf("\n\nout of while!");
(*temp)=newnode;
}
LISTNODE* initialize(){
static int count=0;
LISTNODE *tempnewnode;
printf("\n\nINto inintialize!");
tempnewnode=(LISTNODE*)malloc(sizeof(LISTNODE));
if(tempnewnode==NULL){
printf("No memory available. Aborting!");
exit(0);
}
else{
tempnewnode->flag=0;
tempnewnode->name='*';
tempnewnode->next=NULL;
if(count==0){
head=tempnewnode;
count++;
}
}
return tempnewnode;
}
void traverselist(LISTNODE *temp){
printf("\n");
for(;temp!=NULL;temp=temp->next){
printf("%c",temp->name);
}
}
Please help!
The problem is inside the insert_node function, specifically with the loop:
for(;*temp!=NULL;temp=&((*temp)->next))
printf("\n\nIn for!");
You'd be better advised not to use the reference temp in your loop, as it overwrites the head->next back to itself. Create another temporary pointer.
I changed the insertNode(char, LISTNODE**) to the following:
void insertNode(char c, LISTNODE *temp){
LISTNODE** temp2=&temp;
newnode=initialize();
printf("\n\nback to insertnode:after initialize");
newnode->name=c;
for(;(*temp2)!=NULL;temp2=&(*temp2)->next)
printf("\n\nIn for!") ;
(*temp2)=newnode;
}
and function is called like this:
insertNode(ch,head);
It works just fine!
The problem is this portion of your insertNode function
for(;*temp!=NULL;temp=&((*temp)->next))
printf("\n\nIn for!") ;
//printf("\n\nout of while!");
(*temp)=newnode;
Here you should first check if the link list is empty or not if it is empty then you can create the new node and assign the address of it to temp.
If not then depending upon whether you want to insert the new element in the end, beginning or middle of the list you should traverse the list then perform the insertion.
For example if you want to perform insertion at the beginning then after creating the new node you should assign the address of the start pointer of the list to the next of newly created node and move the start to the new node as you have to keep track of the start pointer.

Pop() function that crashes

I am trying to implement a stack with linked lists. I am having problems with the pop() function. It compiles OK, but when I try to run the code it crashes on tmp=tmp->head; and I have no idea why. I tried google but didn't find the answer. Here is the full code:
struct node{ //kreiram stog
struct node* head;
struct node* next;
int broj;
}node;
void push_onto(int broj){ // dodajem na glavu
struct node* novi;
novi=(struct node*)malloc(sizeof(struct node));
//novi=novi->head;
if (novi== NULL)
printf("Smth is wrong,Jose!\n");
else
novi->broj=broj;
novi->next=novi->head;
novi->head=novi;
}
int pop()// skidam sa stoga
{
struct node* temp;
temp=temp->head;
int br;
if (temp->next==NULL)
return -1;
else
br=temp->head;
temp=temp->next;
free(temp);
return br;
}
void top(){ //koji je element na stogu
struct node* tmp;
printf("Trenutni element na stogu je %d",tmp->broj);
}
void is_empty(){
struct node* tmp;
tmp=tmp->head;
if (tmp->head ==NULL)
printf("List is empty!\n");
}
void print_elem(){
struct node* tmp;
tmp=tmp->head;
if (tmp->head==NULL)
printf("Smth gone wrong!\n");
while (tmp!=NULL)
{
printf("Number is: %d",tmp->broj);
tmp=tmp->next;
}
printf("\n");
}
int main(void){
push_onto(15);
push_onto(10);
push_onto(20);
push_onto(12);
//print_elem();
printf("The element removed is : %d",pop());
//print_elem();
return 0;
}
This is not my homework, although it looks as such. This is just my attempt at trying to figure out some basic algorithms.
Thanks in advance! :)
struct node* temp;
temp=temp->head;
You never allocated anything for temp. It's just an uninitialized pointer.
It's not clear what you are trying to pop. Your pop() function takes no parameters and it accesses no globals. Likewise, I see the same problem with most of your functions there. They are supposed to operate on some sort of stack object, but none of them actually take such an object as a parameter.
I think you're close to "getting it". I remember it was a bit hard for me to understand structs and pointers at the beginning. But once you "get it" you'll be fine.
It seems you're trying to construct a stack using a simply-linked list. I'll try to offer some suggestions.
The very first thing that I would modify is your node struct. It is true, you need to keep
track of the head node, but usually you don't need to do it on every node. So we will remove it from your node definition.
struct node{ //kreiram stog
struct node* next;
int broj;
};
Now, you need to keep track of the head node of your list. This can be done with a global variable, that I'm going to call head:
struct node* head = NULL;
I'm initializing it to null because it is empty. A null head pointer will always mean
your stack is empty. All the code that tries to manipulate the list WILL need to start
with this head node. It is your anchor point.
Then to the push_onto() function
void push_onto(int broj){ // dodajem na glavu
// this bit is fine
struct node* novi;
novi=(struct node*)malloc(sizeof(struct node));
if (novi== NULL)
printf("Smth is wrong,Jose!\n");
else { //I'm adding the bracket, you require it to enclose more than one statement
//in the else section
novi->broj = broj; // store the number to be pushed on the stack
novi->next = head; // link the list, remember head will
// be NULL if the stack was empty
head = novi; // make the new node the current head node
}
}
Let's modify the pop() function
int pop()// skidam sa stoga
{
struct node* temp;
int result;
// first we will check if the head node is NULL (stack is empty)
if( head == NULL ) {
printf("Stack is empty\n");
return -1;
} else {
// hold a temporary value to current head pointer, so we can modify the head node
// and still refer to it
temp = head;
// Head node should now point to the next node on the list (will become NULL when
// popping the last value. This is what actually "pops" the value from our list
head = head->next;
// place in temporary variable the result we are popping. This is so because
// it's not a good idea to reference the node after we free the memory it is using
result = temp->broj;
// release the memory occupied by the node we're popping
free(temp);
return result;
}
}
Finally I'm going to show you how to fix some of the functions that are using your stack
void top(){ //koji je element na stogu
if( head == NULL ) {
printf("Stack is empty\n");
} else {
printf("Trenutni element na stogu je %d",head->broj);
}
}
void print_elem(){
struct node* tmp;
// As you can see, we're initializing tmp to head, since head will always point
// to the top element of your stack.
tmp = head;
if (tmp==NULL) {
printf("Stack is empty!\n");
return;
}
while (tmp!=NULL)
{
printf("Number is: %d",tmp->broj);
tmp=tmp->next;
}
printf("\n");
}
Hope things are clearer now. The head node is kept apart as a global variable and as I said before, it is the anchor point to begin manipulating the list. Feel free to ask me if you're still confused.
=)

Resources