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);
Related
I am trying to reverse a linked by iterative method. Magically, after watching tutorial and trying to recode myself, the program works successfully. However, when I review the code, I hit a question: in line 23, why we must use temp1->next instead of temp1? When traversing to the end of the linked list, which case we use the condition (the node != NULL)? In which case we use (the link of the node ! = NULL)? I fully appreciate it if anyone can enlighten me.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node* Insert(struct Node* head, int data)
{
struct Node* temp = (struct Node*) malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
//If the list is empty
if (head == NULL)
{
head = temp;
}
else //The list is not empty
{
struct Node* temp1 = head;
while (temp1->next != NULL)
{
temp1 = temp1->next;
}
temp1->next = temp;
}
return head;
}
void Print(struct Node* head)
{
struct Node* temp = head;
while (temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
struct Node* Reverse(struct Node* head)
{
struct Node* *prev, *current, *next;
current = head;
prev = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
head = prev;
return head;
}
int main()
{
struct Node* head = NULL;
printf("Enter the length of the linked list you want to create: ");
int length;
scanf("%d", &length);
printf("Enter the value you want to input: ");
int i;
for (i = 0; i < length; i++)
{
int x;
scanf("%d", &x);
head = Insert(head, x);
}
printf("Given linked list\n");
Print(head);
head = Reverse(head);
printf("\nReversed linked list \n");
Print(head);
return 0;
}
In that case, inside the while condition, on line 23, you can notice that the program is using temp1 = temp1->next, if you change the condition to temp1 != NULL when it reaches the last element of linked list it'll collect trash from memory or even result in an error, because NULL don't have a next position.
So, you use temp1 != NULL if you are accessing the data inside the list and temp1->next != NULL if you are manipulating the next positions of the linked list.
Because temp1->next at the end of the linked list is NULL, however, the last node has data, if you use temp1 == NULL you would say that the last node is NULL, which is not the case. So you want to end the loop when the "pointer to the next node" is NULL, not when the next node is NULL.
i write function whom Traverse linked list using two pointers. Move one pointer by one and other pointer by two. When the fast pointer reaches end slow pointer will reach middle of the linked list.
but my code crash when i try to move temp pointer by two
#include <stdio.h>
#include <stdlib.h>
#define MEM (struct node*) malloc(sizeof(struct node))
void addl(); //add elements at last
void print(); //print linked list
void addf(); //add element at first
void addm(); //add element at middel
struct node {
int data;
struct node* next;
};
struct node* head;
void addl()
{
struct node* new, *temp;
temp = head;
new = MEM;
printf("\n\t\tenter any number : ");
scanf("%d", &new->data);
new->next = 0;
if (temp == 0)
head = new;
else {
while ((temp->next != 0))
temp = temp->next;
temp->next = new;
}
}
void print()
{
struct node* temp = head; //
printf(" \n Elements are : ");
while (temp != 0) {
printf(" %d ", temp->data);
temp = temp->next;
}
}
void addf()
{
struct node* new;
new = MEM;
printf("\n\t\tenter any number : ");
scanf("%d", &new->data);
new->next = head;
head = new;
}
void addm()
{
struct node* new, *temp, *med;
temp = head;
med = head;
new = MEM; //MEM #define for dynamic memory allocation
printf("\n\t\tenter m any number : ");
scanf("%d", &new->data);
if (temp == 0)
head = new;
else {
while ((temp = temp->next != 0)) {
med = med->next;
temp = temp->next; //fist move
temp = temp->next; //2nd move when i add program crash
}
// new->next=med;
//med->next=new;
printf("\n\t\tDATA : %d\n", med->data);
}
}
int main()
{
head = 0;
int i = 5; //create linked list
while (i) {
system("cls");
addf();
addl();
i--;
}
addm();
print();
return 0;
}
as of now addm not add anything in linked list because code crash while i try to found mid of linked list
The crash is due to these two line -
temp=temp->next;//for one move
temp=temp->next;//for second move when i add this program crash
Let's think of two situations -
1) List has one element. Then after the while check condition, dur to temp=temp->next line temp will point to NULL. In next temp=temp->next line you are trying to de-reference that NULL. That will crash
2) List have 2 elements. After while condition check temp will point to last element. And after next temp=temp->next line temp will point to NULL. Now in very next line you are trying to de-reference that NULL. Which is another point of crash
You need to remove one temp=temp->next from inside loop as it advances temp by 3 position in each loop iteration which is clearly a logical bug. Node that after that removing one of them will not eliminate the chance of crash.
Another thing is that the commented code is also wrong.
// new->next=med;
//med->next=new;
You may have wanted to do -
new->next = med->next;
med->next = new;
I'm trying to build a singly-linked list using a struct with 2 data types: char* and int, as well as next to point to other nodes of course.
I have two functions: addToList, and printList as well as the main method to run everything.
What my code is supposed to do is add a node after the head, and check to see if another node with the same data has already been added. If so, it does not add the new node, while incrementing the count data of the already-linked node.
Then, printList() prints the count data and the char* data of each node.
The first issue is that my char comparison doesn't seem to be working, since duplicate nodes are still added. Then, my printList function does not print the char* data correctly. Here's my code (I made sure to comment it so it's easy to follow along):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Struct for node. Has an extra data variable to keep track of which node is next
// in a singly-linked list.
typedef struct node {
char *str;
unsigned int count;
struct node *next;
} node;
// Creates a HEAD node with NULL data.
node *head = NULL;
// Adds a new node and populates the data.
struct node* addToList(struct node* Listptr, char* word){
struct node* new = malloc(sizeof(struct node));
new->str = malloc(sizeof(char) * 34);
strcpy(new->str, word);
new->count = 1;
new->next = Listptr;
// If the head is NULL, sets the new node as the head.
if(head == NULL){
head = new;
return new;
}
// Sets a node iterator "cur" to the first position.
node *cur = head;
// Sets a node iterator to be one place behind cur.
node *prev;
// Loops through the linked list, in order to count the previous words and determine
// if it is necessary to add another node.
// Otherwise, it sets cur to the next node, and prev to the node cur was just at.
while(cur != NULL){
if(cur->str == new->str){
cur->count++;
new = NULL;
return new;
} else{
prev = cur;
cur = cur->next;
}
}
// Checks to see if cur is NULL, if so, sets the previous node.next to the one we're adding.
if(cur == NULL){
prev->next = new;
return new;
}
}
// Prints out the count and word values of each node.
void printList(){
node* cur = head;
while(cur != NULL){
printf("%d %c\n", cur->count, cur->str);
cur = cur->next;
}
}
int main() {
node* Z = NULL;
char *a = "hello";
char *b = "world.";
char *c = "hello";
addToList(Z, a);
addToList(Z, b);
addToList(Z, c);
printList(Z);
return 0;
}
I expect to get:
2 hello
1 world
But in the console, I get:
1 l
1 (weird symbol)
1
Don't use == to compare strings rather use strcmp().
Change if (cur->str == new->str) to this:
if (strcmp(cur->str, new->str) == 0)
Read this to know more on string compare: How do I properly compare strings?
I am trying to create a doubly linked list, I have successfully done insertion at begining but not at end.
When tried to add node at end , It just prints the first and last node only not the nodes between them.
My code to do so as follows:
insert_at_end(int data, node ** head) { //Where data is the data to be kept it in it's Info part.
node *temp, *temp2 = *head;
if (temp2 == NULL) {
temp2 = (node * ) malloc(sizeof(node));
temp2->freq = data;
temp2->next = NULL;
temp2->prev = *head;
*head = temp2;
} else {
temp = (node * ) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
temp->prev = temp2;
temp2->next = temp;
}
}
code for printing is:
main() {
int size, data, i, pos, var, pos2;
node *head = NULL;
printf("enter the size of node\n");
scanf("%d", &size);
printf("start entering the number of elements until your size\n");
for (i = 1; i <= size; i++) {
scanf("%d", & data);
insert_at_end(data, & head);
}
node * temp1;
temp1 = head;
while (temp1 != NULL) {
printf("%d-> ", temp1->freq);
temp1 = temp1 -> next;
}
}
The output is as follows:
enter the size of node
5
start entering the number of elements until your size
1
2
3
4
5
1-> 5-> //It don't print "2->3->4->"
I think there is some logical problem, What that i couldn't find. Could any one correct me please in my logic?
You are not adding new node at the end.
To add at the end you should first reach to the last node by iterating over all other nodes in between.
Or,
you can keep track of the pointer to last node and then add new node after that.
Also, specify the return type of your insert function:
"void" insert_at_end(int data, node ** head)
C treats unspecified return types as int and hence your compiler might complain: "Control reached at the end of a non-void function"
there is mistake in you insert at end function.
you should travese a non-empty list first to reach the end of the list and then insert the new node there. then the node will be added at the last position. now what you wrote makes the new node to be added to the 2nd position. and its next pointer is NULL so the resulting list will always contain only 2 nodes.
1st_node followed by the node containing last node(node with last entered value)
insert_at_end(int data, node * * head) //Where data is the data to be kept it in it's Info part.
{
node * temp,*temp2= *head;
if(temp2==NULL)
{
temp2 = (node * ) malloc(sizeof(node));
temp2 -> freq = data;
temp2 -> next = NULL;
temp2 -> prev = *head;
* head = temp2;
}
else
{
temp = (node * ) malloc(sizeof(node));
temp -> freq = data;
temp -> next = NULL;
while((temp2)->next!=NULL) //for moving to the end point
temp2=(temp2)->next;
temp -> prev = temp2;
temp2->next=temp;
}
}
I'm very new to coding in C (and therefore the silly exercise I am working on). I tried looking at this other solution to a similar question, but it seems like my coding strategy is different, and ultimately I would like to understand what is the problem with my code. I would greatly appreciate your input.
I have a linked list, a function that inserts a new node at the beginning of my list, a function that prints my linked list, and main function.
Unfortunately my knowledge of C is not good enough to understand why my function is not inserting at the beginning of the list. What is even more unfortunate is that this code does not crash.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} *Node_t;
void print_list(Node_t root) {
while (root) {
printf("%d ", root->data);
root = root->next;
}
printf("\n");
}
void add_to_list(Node_t *list, Node_t temp){
// check if list is empty
if ((*list)->next == NULL) {
// insert first element
(*list) = temp;
}
else {
temp->next = (*list);
(*list) = temp;
}
}
int main () {
int val1 = 4;
int val2 = 8;
int val3 = 15;
Node_t list = malloc(sizeof(struct Node));
Node_t temp1 = malloc(sizeof(struct Node));
Node_t temp2 = malloc(sizeof(struct Node));
Node_t temp3 = malloc(sizeof(struct Node));
temp1->data = val1;
temp1->next = NULL;
temp2->data = val2;
temp2->next = NULL;
temp3->data = val3;
temp3->next = NULL;
//Initialize list with some values
list->data = 0;
list->next = NULL;
/* add values to list */
add_to_list(&list,temp1);
add_to_list(&list,temp2);
add_to_list(&list,temp3);
print_list(list);
}
This code will only ever print the last node I have attempted to add to the list, therefore overwriting the previous nodes.
For example:
Running…
15
Debugger stopped.
Program exited with status value:0.
A single mistake in add_to_list() function:
if ((*list)->next == NULL) { // checks next of first is NULL not list is NULL
// to insert at first
should be just:
if ((*list) == NULL){ // You need to check list is NULL
Check working code
Why you were getting only 15 the last node (temp3) value?
Because in main you creates three temp nodes and initialized next of every node to NULL, including list node so in add_to_list() function if condition ((*list)->next == NULL) always evaluates true and list always initialized with temp node.