Creating binary tree and passing node as pass by reference - c

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.

Related

solving balancing parantheses problem in C misunderstanding

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", &paras[j]); // &paras[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;
}

Linked list: remove all nodes whose next element has a larger value

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.

Having a trouble with linked lists (adding and printing)

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");
}

Linked list- find_node_data

I have previously posted about this same topic. I am self-learning data structures using MIT Open Courseware. I'm doing the 6.S096-Introduction to C/C++ course and attempting the fourth assignment.
It is based on binary search trees and I gave it a try. I wanted to print the values for debugging but kept getting different executions each time.
One time, the cycle doesn't complete and the other time, it goes on to infinity. The debugging block also relates to the other function(find_node_data) I have to complete. So if I can figure what's wrong here, I can easily finish the find_node_data. I have commented a few things to see if it affects anything. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int node_id;
int data;
struct node* left;
struct node* right;
}node;
///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***///
// Declare the tree modification functions below...
node* newNode(int data,int node_id){
node* new_node = (node*) malloc(sizeof(node));
new_node->data = data;
new_node->node_id= node_id;
new_node->right= new_node->left=NULL;
return new_node;
}
node* insert_node(node* root, int node_id, int data) {
if(root==NULL)
return newNode(data,node_id);
else{
node* cur;
if(node_id<root->node_id){
cur=insert_node(root->left,data,node_id);
root->left=cur;
}
else if(node_id>root->node_id){
cur=insert_node(root->right,data,node_id);
root->right=cur;
}
}
return root;
}
// Find the node with node_id, and return its data
/*int find_node_data(node* root, int node_id) {
node* current;
for( current = root->; current->next!=NULL;
current= current->next){
if(current->data == data) return current;
}
return NULL;
}
*/
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T,data,node_id;
printf("Print yo cases");
scanf("%d", &T);
node* root = NULL;
while(T-->0){
printf("Type yo numnums no. %d:",T);
scanf("%d %d",&data,&node_id);
root=insert_node(root,data,node_id);
}
node *lol;
node *king;
for(lol=root;lol->left!=NULL;lol=lol->left){
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ",lol->node_id);//,king->node_id);
//}
}
return 0;
}
To find the node_data you can use recursion to find the node.
node* find_node_data(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else {
node *left = find_node_data(root->left, node_id);
return left? left: find_node_data(root->right, node_id);
}
}
And then get the data for the node e.g. get the data for node with node_id 42:
printf("node data %d", find_node_data(root, 42)->data);
Full program below (I can't guarantee its correctness but maybe you can?)
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int node_id;
int data;
struct node *left;
struct node *right;
} node;
///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***///
// Declare the tree modification functions below...
node *newNode(int data, int node_id) {
node *new_node = (node *) malloc(sizeof(node));
new_node->data = data;
new_node->node_id = node_id;
new_node->right = new_node->left = NULL;
return new_node;
}
node *insert_node(node *root, int data, int node_id) {
if (root == NULL)
return newNode(data, node_id);
else {
node *cur;
if (node_id < root->node_id) {
cur = insert_node(root->left, data, node_id);
root->left = cur;
}
else if (node_id > root->node_id) {
cur = insert_node(root->right, data, node_id);
root->right = cur;
}
}
return root;
}
// Find the node with node_id, and return its data
/*
int find_node_data_old(node *root, int node_id) {
node *current;
for (current = root->; current->next != NULL;
current = current->next) {
if (current->data == data) return current;
}
return NULL;
}*/
node* find_node_data(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else {
node *left = find_node_data(root->left, node_id);
return left? left: find_node_data(root->right, node_id);
}
}
void print(node *np) {
if (np) {
print(np->left);
printf("(%d, %d)", np->node_id, np->data);
print(np->right);
}
}
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T, data, node_id;
printf("Print yo cases");
scanf("%d", &T);
node *root = NULL;
while (T-- > 0) {
printf("Type yo numnums no. %d:", T);
scanf("%d %d", &data, &node_id);
root = insert_node(root, data, node_id);
}
node *lol;
node *king;
for (lol = root; lol->left != NULL; lol = lol->left) {
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ", lol->node_id);//,king->node_id);
//}
}
print(root);
printf("\n");
printf("node data %d", find_node_data(root, 42)->data);
return 0;
}
Test
Print yo cases3
Type yo numnums no. 2:22 42
Type yo numnums no. 1:21 41
Type yo numnums no. 0:20 40
executed!
42 executed!
41 (40, 20)(41, 21)(42, 22)
node data 22
You may also use Jonathan Leffler's improved recursion to find the node:
node *find_node_data2(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else if (root->node_id > node_id)
return find_node_data(root->left, node_id);
else
return find_node_data(root->right, node_id);
}
Both functions return the correct values as seen in the second test.
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T, data, node_id;
printf("Print yo cases");
scanf("%d", &T);
node *root = NULL;
while (T-- > 0) {
printf("Type yo numnums no. %d:", T);
scanf("%d %d", &data, &node_id);
root = insert_node(root, data, node_id);
}
node *lol;
node *king;
for (lol = root; lol->left != NULL; lol = lol->left) {
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ", lol->node_id);//,king->node_id);
//}
}
print(root);
printf("\n");
printf("node data %d\n", find_node_data(root, 42)->data);
printf("node data find_node_data2 %d", find_node_data2(root, 42)->data);
return 0;
}
Test 2
Print yo cases3
Type yo numnums no. 2:11 12
Type yo numnums no. 1:13 14
Type yo numnums no. 0:20 42
(12, 11)(14, 13)(42, 20)
node data 20
node data find_node_data2 20

Linked list shows only first node element on printing

I am trying to create a linked list in order to enhance my concepts of pointers and address. I have to create linked list in following way:
(1) Read all the nodes together at once at terminal.
(2) Then show the final linked list so formed at last.
How i try to do so ?
I am reading first the size of linked list (total number of nodes to be entered). Then i read all the nodes 1 by one in do-while loop. After reading all the nodes i try to create linked list. I differentiate the case when the node is first node to be created by a count variable which will have count=0 when the node is first node after that it will be in another loop.
The output i get is as follows:
enter the size of node
4
start entering the number of elements until your size
2
3
4
5
Printing linked list
2-> //It don't print the other nodes, Just first one
hp#ubuntu:~/Desktop/pointer$
My full code to do so is :
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * next;
};
typedef struct node node;
node * tree;
void main()
{
int size, data;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
tree = NULL;
printf("enter the size of node\n");
scanf("%d", & size);
printf("start entering the number of elements until your size\n");
node * temp3 = tree;
node * prev;
//Problem creating area is below
do
{
scanf("%d", & data);
if (count == 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev = temp;
}
else if (count != 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
}
size--;
++count;
}
while (size > 0);
printf("Printing linked list\n");
node * temp1;
temp1 = prev;
//there may be problem here
while (temp1-> next != NULL)
{
printf("%d-> ", temp1-> freq);
temp1 = temp1-> next;
}
printf("\n");
}
Couldanyone please help me in printing the full linked list by pointing me the error with it's solution ?
Okay there is some unnecessary pointers and a few pointer mistakes being made, for ease of answering I've rewritten your code, I'll try to explain what I did here:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * next;
};
typedef struct node node;
//only need two pointers when building a linked list, one for the top and one for the
//current node
node *tree = NULL, *curr = NULL; //init both pointers to NULL initially
int main()
{
int size, data; //dont need count, you'll see in a minute why
printf("enter the size of node\n");
scanf("%d", & size);
printf("start entering the number of elements until your size\n");
//Problem creating area is below
do
{
scanf("%d", &data);
if (tree == NULL) //just test for top node being NULL instead of using count
{
node *temp;
temp = malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
//stylistically i like using curr rather than prev, just a style choice
tree = temp; //set tree to first node
curr = tree; //make the top node the current node
}
else //don't need else if, there are only two conditions
{
node *temp = malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
curr->next = temp; //set the next node in list to the new one
curr = curr->next; //here's where you had pointer issues, move the current
//to the newly created node
}
size--;
}
while (size > 0);
printf("Printing linked list\n");
curr = tree; //reuse curr, no need to make a new pointer
//test for the current node being NULL, takes care of special case of empty list
//causing a segfault when you attempt to access a member of an invalid pointer
while (curr != NULL)
{
printf("%d->", curr->freq);
curr = curr->next; //move to next item in list
}
printf("\n");
return 0;
}
I ran a sample run with size of 3 and inputs of 1, 2, and 3, and I get as output: 1->2->3->
You got two problems.
else if (count != 0)
{
node * temp = prev;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
}
You aren't changing prev to point to your new node. It still points to '2' in your scenario, and you'll never have more than two nodes in the list.
Try something like
else if (count != 0)
{
/* node * temp = prev; */ //This code is not doing anything useful
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
prev = temp;
}
Next, your printing loop should probably be
node* temp1 = start; //You need a variable that points to the first node in the list
do
{
printf("%d-> ", temp1-> freq);
temp1 = temp1-> next;
}
//The last item will always have next == NULL, and must be included
while (temp1-> next != NULL);

Resources