I'm too new on data structures, actually i began yesterday. Here is the code:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int x;
node *next;
};
void addToList(node *r, int a);
void printList(node *r);
int main()
{
node *root;
root = NULL;
for (int i = 0; i < 5; i++)
{
int a;
scanf("%d", &a);
addToList(root, a);
}
printList(root);
return 0;
}
void addToList(node *r, int a)
{
while (r != NULL)
r = r -> next;
r = (node *)malloc(sizeof(node));
r -> x = a;
r -> next = NULL;
}
void printList(node *r)
{
while (r != NULL)
{
printf("%d ", r -> x);
r = r -> next;
}
printf("\n");
}
I expect the program gets new 5 elements into the list and then prints them. But end of the program nothing is happening. What is my fault?
The problem is in the addToList() function. If you want to update the root node of the list you have to define your function like that:
void addToList(node **r, int a)
Otherwise, you're sending the pointer to root and doing whatever you doing inside the function. But it doesn't affect root's value on main() and it remains NULL.
If you want to change the value of the pointer, you have to send from main() the address of the pointer to the function ==> addToList(&root, a);.
So now we can update where root points to. But it's not enough because you want root to always point to the beginning of the list ==> you want to update it only in the first call to addToList().
Last problem is to add the new created node as the last node in the list. You can do that by saving a temporary pointer to the last node. See my comments in the code (marked my changes with <<<):
void addToList(node **root, int a) <<<
{
node *r = *root; <<<
node *last = NULL; <<<
while (r != NULL) {
last = r; <<<
r = r -> next;
}
r = (node *)malloc(sizeof(node));
r -> x = a;
r -> next = NULL;
if (last == NULL) { <<<
// this is true only on the first call to
// addToList, so we update root only once
*root = r;
} else {
// all other times we add the new node to be the last one
last->next = r;
}
}
You have root = NULL but your addtoList function checks if root !=NULL. So the test fails there and nothing gets added.
You should have something like this instead:
void addToList(node *r, int a) {
struct node *temp;
temp=(struct node *)malloc(sizeof(struct node));
temp->data = a;
if (r== NULL) {
r = temp;
r->next = NULL;
}
else {
temp->next = r;
r = temp;
}
}
Here, the first mistake is that you have not taken the *root pointer variable as global, so it will not update the value of the *root whenever a new node is inserted. It will keep the value of *root as NULL.
The below code has comments in it, which will explain the various mistakes done by you very easily.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int x;
node *next;
};
node *root; //Declaring the *root as global
void addToList(int a);
void printList();
//removing the *root as parameter from both the functions
int main()
{
root = NULL;
for (int i = 0; i < 5; i++)
{
int a;
scanf("%d", &a);
addToList(a);
}
printList();
return 0;
}
void addToList(int a)
{
//Declaring a temporary pointer(*temp) to avoid the value loss of the *root pointer
node *temp=root;
//Declaring a new node to save the data taken from the user
node *nn = (node *)malloc(sizeof(node));
//Assigning the values to the new node(*nn)
nn->x=a;
nn->next=NULL;
//Checking that the root node is NULL or not
//If root is empty, then new node is assigned to *root
if(root == NULL)
{
root=nn;
}
//Else, we will first find the last node of the linklist using the *temp pointer
else
{
while (temp->next != NULL)
temp = temp -> next;
//Assigning the new node after the last node of the linklist
temp->next=nn;
}
}
void printList()
{
node *r=root;
while (r != NULL)
{
printf("%d ", r -> x);
r = r -> next;
}
printf("\n");
}
Related
I am trying to create a program to solve the classic problem of brackets balancing.
The program needs to tell the user if an the parantheses appearing in an expression are balanced.
I am very new to C/C++, coming from Python, so please excuse my ignorance and please point me towards the right direction!
What I have up until now is below. When compiled with gcc -o exec program.c then ./exec it outputs: List is: ) ( ] [ } { , rather than what I would expect: List is: { } [ ] ( )
I do not understand why, is there an obvious mistake?
I keep searching for it...
Also, I would be very grateful if you could comment if my logic on how I am designing those functions makes sense and is correct: I feel I actually need to put those pointer variables as arguments to the functions?
Thank you!
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Parantheses check:
struct Node {
char data;
struct Node* next;
};
struct Node* head_of_listofparans = NULL;
struct Node* head_of_listofparans_open = NULL;
struct Node* head_of_listofparans_close = NULL;
struct Node* insert_at_beginning(char c, struct Node* head) {
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = c;
temp->next = head;
head = temp;
return head;
}
void Delete(int n, struct Node* head) { // removes the n-th node (n=1 represents the head node, n=2 represents the second node)
struct Node* temp1 = head;
if (n==1) {
head = temp1->next;
free(temp1);
return;
}
int i;
for (i=0; i<n-2; i++) { // if n=2 (want to delete the 2nd node), this for-loop doesn't get executed.
temp1 = temp1->next;
} // temp1 now points to the n-1 th node. if n=2, temp1 still (correctly) points towards the head (first node)
struct Node* temp2 = temp1->next; // temp2 points towards the n-th node
temp1->next = temp2->next; // n-1 th node now points to the n+1 th node
free(temp2); // delete the n-th node
}
struct Node* createListOfParantheses(char* parants, struct Node* initial_head) {
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = parants[0];
temp->next = initial_head;
initial_head = temp; // 1st node created. the link of this node points to NULL now. head of the list points to this newly created 1st node.
int i;
for (i=1; i<=(int)strlen(parants); i++) {
initial_head = insert_at_beginning(parants[i], initial_head);
}
return initial_head;
}
// int ParanthesisCheck(char* parantheses_open, char* parantheses_close, char* expr) {
// int n = int(strlen(expr));
// int i;
// for (i=0; i<=n-1; i++) {
// if (strchr(parantheses_open, expr[i])!=NULL) { // if expr[i] can be found in "{[("
// insert_at_beginning(expr[i]) // ppush(expr[i]);
// }
// else if (strchr(parantheses_close, expr[i])!=NULL) { // if expr[i] can be found in "}])"
// if ((check_emptiness_of_stack()==1) || (get_top_of_stack() != expr[i])) { // || signifies the logical OR
// return 0;
// }
// else {
// Delete(1, head_of_stack); // ppop(), delete the very first node (head node), i.e. the most-recently-introduced node
// }
// }
// }
// return check_emptiness_of_stack()==1 ? 1:0;
// }
void Print_List_Of_Parans(struct Node* head) {
struct Node* temp = head;
printf("List is: ");
while (temp != NULL) {
printf(" %c", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
char paras[7] = "{}[]()";
char paras_open[4] = "{[(";
char paras_close[4] = "}])";
char input_expr[20] = "(a+b)";
// int j;
// for (j=0; j<7; j++) {
// scanf("%c", ¶s[j]); // ¶s[j] is equivalent to: paras + j if paras is an array
// printf("%s %d\n", "Iteration number: ", j);
// } // doesn't work because scanf reads 1 character, alright, but adds a \n at its end, so consumes 2 memory locations from the array char paras[7], not 1 as expected.
head_of_listofparans = createListOfParantheses(paras, head_of_listofparans);
head_of_listofparans_open = createListOfParantheses(paras_open, head_of_listofparans_open);
head_of_listofparans_close = createListOfParantheses(paras_close, head_of_listofparans_close);
Print_List_Of_Parans(head_of_listofparans);
// int result = ParanthesisCheck(head_of_listofparans_open, head_of_listofparans_close, input_expr);
// printf("%d\n", result);
return 0;
}
I'd like to remove in a linked list all the nodes that have a greater value to their right.
Input: 10 -> 12 -> 15 -> 20 -> 5 -> 16 -> 25 -> 8 -> NULL
Expected output: 20 -> 25 -> 8 -> NULL
Actual Output: 20 -> 25 ->
Kindly help me resolve the bug.
#include <stdlib.h>
#include <stdio.h>
struct node{
int data;
struct node *ptr;
}*start=NULL, *t, *last=NULL;
int i=0;
int main() {
//creation
int size;
printf("Enter size:");
scanf("%d", &size);
while (size--) {
t = (struct node *) malloc(sizeof(struct node));
printf("Enter list:");
scanf("%d", &(t->data));
t->ptr = NULL;
if (start == NULL) {
start = t;
} else
last->ptr = t;
last = t;
}
//display
printf("\n");
t = start;
do {
printf("%d->", t->data);
t = t->ptr;
} while (t != NULL);
printf("NULL\n");
//main objective
struct node *t1,*t2;
t1=start;
t2=t1->ptr;
t=start;
for(t=start;t!=NULL;t=t->ptr){
if(t1->data>t2->data||t->ptr==NULL){
printf("%d->", t->data);
}
t1=t1->ptr;
t2=t2->ptr;
}
printf("NULL\n");
return 0;
}
You can fix the segmentation fault due to illegal memory access by verifying that t2 is not null before attempting to dereference the pointer. This version runs clean after adding guards to t2:
for (t = start; t; t = t->ptr) {
if (!t2 || (t1 && t1->data > t2->data)) {
printf("%d->", t->data);
}
t1 = t1->ptr;
if (t2) {
t2 = t2->ptr;
}
}
Although this shows the correct output, the list isn't actually modified, so we're simply producing a side effect, rendering the routine useless for manipulating the data in memory for other purposes.
A few additional suggestions:
There's no need for global variables in this program.
Avoid unnecessary variables (t and t1 are basically the same, so it's easy to remove one of these. We can also remove t2 and use t->ptr instead).
Give variables descriptive names.
Use spacing around operators.
Separate logical chunks of code into separate functions rather than adding comments in main to delimit them.
Free allocated memory when finished with it.
No need to cast the result of malloc.
Here's a version that modifies the list in-place and implements the above points:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *ptr;
};
void remove_right_larger(struct node **head) {
for (struct node *curr = *head, *prev = NULL;
curr; curr = curr->ptr) {
if (curr->ptr && curr->data < curr->ptr->data) {
if (prev) {
prev->ptr = curr->ptr;
}
else {
*head = curr->ptr;
}
free(curr);
}
else {
prev = curr;
}
}
}
void print_list(struct node *head) {
for (; head; head = head->ptr) {
printf("%d->", head->data);
}
puts("NULL");
}
void free_list(struct node *head) {
while (head) {
struct node *tmp = head;
head = head->ptr;
free(tmp);
}
}
struct node *input_list() {
struct node *start = NULL;
struct node *last = NULL;
int size;
printf("Enter size: ");
scanf("%d", &size);
while (size--) {
struct node *tmp = malloc(sizeof(*tmp));
tmp->ptr = NULL;
printf("Enter list: ");
scanf("%d", &(tmp->data));
if (start) {
last->ptr = tmp;
}
else {
start = tmp;
}
last = tmp;
}
return start;
}
int main() {
struct node *head = input_list();
print_list(head);
remove_right_larger(&head);
print_list(head);
free_list(head);
return 0;
}
You are facing Core Dump/Segmentation fault which is a specific kind of error caused by accessing memory that “does not belong to you.”
The iteration before the last one, you're setting t1 <- 8 & t2 <- NULL. So when you enter the last iteration, you check t1->data with t2->data with in if(), which resutls in accessing NULL->data (you're not allowed).
To fix this, you need to add some extra condition to handle this case.
can any one tell me where is the error in this program please it will be really helpful , i did my best to solve this problem ,this code is passing only two test cases
Given an undirected graph and a starting node, determine the lengths of the shortest paths from the starting node to all other nodes in the graph. If a node is unreachable, its distance is -1. Nodes will be numbered consecutively from to , and edges will have varying distances or lengths.
Here is the question https://www.hackerrank.com/challenges/dijkstrashortreach/problem
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
// Node
typedef struct node {
int data;
// Lower values indicate higher priority
int priority;
struct node* next;
} Node;
// Function to Create A New Node
Node* newNode(int d, int p)
{
Node* temp = (Node*)malloc(sizeof(Node));
temp->data = d;
temp->priority = p;
temp->next = NULL;
return temp;
}
// Return the value at head
int peek(Node** head)
{
return (*head)->data;
}
// Removes the element with the
// highest priority form the list
void pop(Node** head)
{
Node* temp = *head;
(*head) = (*head)->next;
free(temp);
}
void updateprt(Node** head, int data) {
if ((*head)->data == data)
{
Node* temp = *head;
*head = (*head)->next;
free(temp);
return;
}
Node* prev = *head;
while ((prev->next)->data != data) {
prev = prev->next;
}
Node* start = prev->next;
prev->next = start->next;
free(start);
}
// Function to push according to priority
void push(Node** head, int d, int p)
{
Node* start = (*head);
// Create new Node
Node* temp = newNode(d, p);
if (*head == NULL) {
*head = temp;
return;
}
// Special Case: The head of list has lesser
// priority than new node. So insert new
// node before head node and change head node.
if ((*head)->priority > p) {
// Insert New Node before head
temp->next = *head;
(*head) = temp;
}
else {
// Traverse the list and find a
// position to insert new node
while (start->next != NULL &&
start->next->priority < p) {
start = start->next;
}
// Either at the ends of the list
// or at required position
temp->next = start->next;
start->next = temp;
}
}
// Function to check is list is empty
int isEmpty(Node** head)
{
return (*head) == NULL;
}
struct adjlistnode {
int data;
struct adjlistnode* next;
};
struct adjlist {
struct adjlistnode* head;
};
struct graph {
int v;
struct adjlist* array;
};
struct graph* creategraph(int v) {
struct graph* G = (struct graph*) malloc(sizeof(struct graph));
G->v = v;
int i;
G->array = (struct adjlist*)malloc(sizeof(struct adjlist)*v);
for (i = 0; i < v; i++) {
G->array[i].head = NULL;
}
return G;
}
int Distance[100000], path[50];
struct adjlistnode* getnewnode(int ver) {
struct adjlistnode* newnode = (struct adjlistnode*)malloc(sizeof(struct adjlistnode));
newnode->data = ver;
newnode->next = NULL;
return newnode;
}
void addedge(struct graph* G, int src, int dest, long int w, long int** weight) {
struct adjlistnode* temp;
temp = getnewnode(dest);
temp->next = G->array[src].head;
G->array[src].head = temp;
temp = getnewnode(src);
temp->next = G->array[dest].head;
G->array[dest].head = temp;
if (weight[src][dest] != 0 || weight[dest][src] != 0 && w < weight[src][dest]) {
weight[src][dest] = w;
weight[dest][src] = w;
}
if (weight[src][dest] == 0) {
weight[src][dest] = w;
weight[dest][src] = w;
}
}
void printgraph(struct graph* G) {
for (int i = 0; i < G->v; i++) {
struct adjlistnode* temp = G->array[i].head;
printf("%d-> ", i);
while (temp) {
printf(" %d", temp->data);
temp = temp->next;
}
printf("\n");
}
}
void Dijkstra(Node** queue, struct graph* G, int s, long int** weight) {
int v, w, d;
push(queue, s, 0);
for (int i = 0; i < 100000; i++) {
Distance[i] = -1;
}
Distance[s] = 0;
while (!isEmpty(queue)) {
v = peek(queue);
pop(queue);
struct adjlistnode* temp = G->array[v].head;
while (temp) {
w = temp->data;
d = Distance[v] + weight[v][w];
//To update the distance of w check the below two conditions
if (Distance[w] == -1) {
Distance[w] = d;
push(queue, w, d);
path[w] = v;
}
if (Distance[w] > d)
{
Distance[w] = d;
path[w] = v;
updateprt(queue, w);
push(queue, w, d);
}
temp = temp->next;
}
}
}
int main()
{
int t;
scanf("%d", &t);
while (t) {
Node* pq = NULL;
int v;
int e;
scanf("%d %d", &v, &e);
long int** weight = (long int**)malloc(sizeof(long int*)*v);
for (int i = 0; i < v; i++)
weight[i] = (long int*)malloc(sizeof(long int)*v);
struct graph* G = creategraph(v);
int u, w;
long int l;
for (int i = 0; i < e; i++) {
scanf("%d %d %ld", &u, &w, &l);
addedge(G, u - 1, w - 1, l, weight);
}
int s;
scanf("%d", &s);
// printgraph(G);
//printf("\n");
Dijkstra(&pq, G, s - 1, weight);
for (int i = 0; i < G->v; i++) {
if (i == s - 1)
continue;
printf("%d ", Distance[i]);
}
/* while (!isEmpty(&pq)) {
printf("%d ", peek(&pq));
pop(&pq);
}*/
return 0;
}
system("pause");
}
Your biggest issue is with your priority queue, which you implement as simple linked list. You seem to be confused about when and how to use a pointer to node pointer.
For example, this function:
int isEmpty(Node **head) ...
only inspects the list. It doesn't modify it, so it is enough to pass a node pointer:
int isEmpty(Node *head) ...
This function doesn't modify the contents of the nodes, either, so this could be made explicit:
int isEmpty(const Node *head) ...
On the other hand, the push, pop and updateprt functions must be able to change the head via a pointer, so they require a pointer to a node pointer. Your pop function, which always changes the head, does this. The other functions look like this:
void push(Node** head, int d, int p)
{
Node* start = (*head);
// ... do stuff with start, leave head alone ...
}
Here, you have just used the pointer to node pointer as an overly obscure way to pass in information about the head, but you never modify it (except in the special case of inserting into an ampty list).
Here's how that push function should look like:
void push(Node **head, int d, int p)
{
Node *temp = newNode(d, p);
while (*head && (*head)->priority < p) {
head = &(*head)->next;
}
temp->next = *head;
*head = temp;
}
Note how there aren't any special cases. When you call push(&queue, ...), you pass the address of the head pointer and you can modify the local variable queue in the calling function by assigning to *head. When you walk through the list with head = &(*head)->next, head holds the address of the next field of the previous node, which you can also modify via *head. The pointer to a pointer adds one level of indirection and tells you where you have come from and lets you modify that value.
In the same vein, you can change (and simplify) your updateptr function:
void updateprt(Node** head, int data)
{
while (*head && (*head)->data != data) {
head = &(*head)->next;
}
if (*head) pop(head);
}
With these changes, your program should work, but there are other things to note:
if (weight[src][dest] != 0 || weight[dest][src] != 0 && w < weight[src][dest]) ...
The condition (w1 == 0 || w2 == 0 && w < w1) is parsed as (w1 == 0 || (w2 == 0 && w < w1)), which probably isn't what you want. The check for zero is ot done correctly, because you never initialize weight. (You could use calloc instead of malloc to create a zero-initialized array.)`
But why have a separate array of weights at all? You could store the weight with each edge:
struct adjlistnode {
int data; // destination vertex
int weight;
struct adjlistnode* next;
};
The same goes for the arrays:
int Distance[100000], path[50];
Both arrays provide one entry for each vertex. The first one is too generous ("I'll allocate a bit more, just in case ..."), the second could be too small. (You don't need the path for the task, but it's always nice to be able to verify it. The variable isn't a path, however, it holds the next step towards the starting point for each vertex.)
The competition rules say that there are at most 3,000 nodes, so you could just dimension your arrays with [3000], but you cold also make them part of the graph structure and allocate according to the number of vertices.
Good luck!
I am trying to create a binary tree and i am new to data structure.
What i have to do is:
(1) Take the size of tree (total number of nodes) at terminal.
(2) Then up to size read nodes from the user at terminal
(3) Then create Binary search tree.
Note: I have to pass the node by reference only` in the function call(No other options).
It compiles without error but i guess there is any logical problem.It gives segmentation fault when i try to insert second node in for loop (for first it works fine) but compile without errors .I am not able to predict it's due to which line of code?
When I do:
How many nodes are to be inserted ?
5
enter the nodes
1 //I am not able to add more nodes
Segmentation fault (core dumped)
Answer in any language c/c++ or even algorithm are welcome.
My code to do so is :
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * left, * right;
};
typedef struct node node;
/////////////////////////////////////////////////////////////Function definitions //////////////////////////////////////////////////
insert_first_node(int data, node * * Node)
{
node * temp1 ;
temp1 = Node;
temp1= (node * ) malloc(sizeof(node));
temp1 -> freq = data;
temp1 -> left = NULL;
temp1 -> right = NULL;
}
////////////////////////////////////////////////////////////////////
insert_beginning(int data, node * * Node)
{
root = * Node;
root = (node * ) malloc(sizeof(node));;
if (root ==NULL)
{
insert_first_node(data, & root);
}
if (data <= root -> freq)
{
insert_beginning(data, & root -> left);
} else
{
insert_beginning(data, & root -> right);
}
*Node = root;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
main()
{
int i, size, data;
node * head;
head = NULL;
printf("How many nodes are to be inserted ?\n");
scanf("%d", & size);
for (i = 1; i <= size; i++)
{
printf("enter the nodes \n");
scanf("%d", & data);
insert_beginning(data, & head);
}
}
I would write it like this (although I wouldn't necessarily use recursion, but maybe you are supposed to...):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
int freq;
struct Node *left;
struct Node *right;
} Node;
///////////////////////////////////////////////////////////
// Function definitions //
///////////////////////////////////////////////////////////
int insert_leaf_node(int freq, Node **parent_ptr)
{
Node *node;
if ((node = malloc(sizeof *node)) == NULL)
return -1;
node->freq = freq;
node->left = NULL;
node->right = NULL;
*parent_ptr = node;
return 0;
}
///////////////////////////////////////////////////////////
int insert_node(int freq, Node **parent_ptr)
{
Node *node = *parent_ptr;
if (node == NULL) {
return insert_leaf_node(freq, parent_ptr);
}
else if (freq <= node->freq) {
return insert_node(freq, &node->left);
}
else {
return insert_node(freq, &node->right);
}
}
///////////////////////////////////////////////////////////
int main()
{
int i, size, freq;
Node *root = NULL;
printf("How many nodes are to be inserted ?\n");
scanf("%d", &size);
for (i = 0; i < size; i++) {
printf("enter the freq of node %d\n", i+1);
scanf("%d", &freq);
insert_node(freq, &root);
}
return 0;
}
And here's how I would write insert_node without recursion:
int insert_node(int freq, Node **parent_ptr)
{
Node *node;
while ((node = *parent_ptr) != NULL) {
parent_ptr = (freq <= node->freq) ? &node->left : &node->right;
}
return insert_leaf_node(freq, parent_ptr);
}
You are getting segmentation fault starting from first input only. Let me clear the reason for that.
In insert_beginning function, first line is root = * Node;. Here *Node is NULL already. So root would have NULL value also. You expected that root also points to same address as *Node but this is not the case as *Node is pointing to nothing, so root and *Node are still unrelated. Now you have allocated the memory to root in previous line, but now you have assigned NULL to root. So previous assigned address to root is lost. So that is the leak memory, Dalibor is talking about.
Lets go ahead.
Now root==NULL is checked, which is true, so insert_first_node is called. There is temp1=Node, which is syntactically wrong. I think you intended temp1 = *Node. But still that is wrong as *Node is NULL, so would be temp1. Now you are assigning value to NULL object. So next line gives segmentation fault.
The working code can be
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * left, * right;
};
typedef struct node node;
/////////////////////////////////////////////////////////////Function definitions //////////////////////////////////////////////////
void insert_first_node(int data, node * * Node,int direction)
{
node * temp1 = (node * ) malloc(sizeof(node));
temp1 -> freq = data;
temp1 -> left = NULL;
temp1 -> right = NULL;
if(*Node == NULL)
*Node = temp1;
else if(direction == 1)
(*Node)->right = temp1;
else
(*Node)->left = temp1;
}
////////////////////////////////////////////////////////////////////
void insert_beginning(int data, node * * Node)
{
node *root;
root = * Node;
if (root == NULL)
{
insert_first_node(data,Node,0);
return;
}
if (data <= root -> freq)
{
if(root->left == NULL)
insert_first_node(data,&root,0);
else
insert_beginning(data,&root->left);
} else
{
if(root->right == NULL)
insert_first_node(data,&root,1);
else
insert_beginning(data,&root->right);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
main()
{
int i, size, data;
node * head;
head = NULL;
printf("How many nodes are to be inserted ?\n");
scanf("%d", & size);
for (i = 1; i <= size; i++)
{
printf("enter the nodes \n");
scanf("%d", & data);
insert_beginning(data, & head);
}
}
It seg-faults during the insertion of your first node. If it was during the second insert, you would see the message "enter the nodes" twice.
Now to the reason. In the function insert_beginning, the first if statement does not compare root to NULL, but sets it to NULL. Since NULL is treated as false, the code inside the if is not evaluated and the execution moves to the second if statement. In it, you're trying to access freq field of root, which is set to NULL from the first if statement. So you are trying to dereference NULL pointer, which leads to the seg-fault.
i have written a code to append nodes if empty or not.
I think my code and logic is correct but still i am not able to get any answer . its compiling but after running not showing any result . please tell me why
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *nxt;
};
void append(struct node *,int);
void display(struct node*);
void append( struct node *q, int num )
{
struct node *temp,*r;
if(q == NULL)
{
temp = (struct node*)malloc(sizeof(struct node));
temp -> data = num;
temp -> nxt = NULL;
q = temp;
}
else
{
temp = q;
while(temp->nxt != NULL)
{
temp = temp->nxt;
}
r = (struct node*)malloc(sizeof(struct node));
r -> data = num;
r -> nxt = NULL;
temp->nxt = r;
}
}
void display(struct node *q)
{
while(q != NULL)
{
printf("%d",q->data);
q = q->nxt;
}
}
int main()
{
struct node *a;
a= NULL;
append(a,10);
append(a,11);
append(a,12);
display(a);
return 0;
}
You need to pass the address of the first parameter (the list head) to the append method by address. As written, it is passing NULL in the first call (and each subsequent call) because it is passing by value.
The prototype should look something like this:
void append( struct node **q, int num )
And then make calls like this:
append(&a,10);
Note that the function append needs to be updated accordingly to treat the parameter change correctly.
The prototype of append needs to be changed as
void append( struct node **q, int num );
and pass the address of the a as &a to this function. This is because C only supports pass by value. Learn more on this here.
Please find the modified append function as below:
void append( struct node **q, int num )
{
struct node *temp,*r;
if(*q == NULL)
{
temp = (struct node*)malloc(sizeof(struct node));
temp -> data = num;
temp -> nxt = NULL;
*q = temp;
}
else
{
temp = *q;
while(temp->nxt != NULL)
{
temp = temp->nxt;
}
r = (struct node*)malloc(sizeof(struct node));
r -> data = num;
r -> nxt = NULL;
temp->nxt = r;
}
}
In addition:
Chane the below line:
printf("%d",q->data);
as
printf("%d\n",q->data);
printf might not flush data unless there is a newline in some terminals.