Write a function AlternatingSplit() that takes one list and divides up its nodes to make two smaller lists ‘a’ and ‘b’. The sublists should be made from alternating elements in the original list. So if the original list is 0->1->0->1->0->1 then one sublist should be 0->0->0 and the other should be 1->1->1.
More details about the problem - http://www.geeksforgeeks.org/alternating-split-of-a-given-singly-linked-list/
Now i made this code and it's running successfully
#include<stdio.h>
#include<stdlib.h>
struct node
{
int num;
node *next;
};
node *start1 = NULL, *start2 = NULL, *start3 = NULL;
void push()
{
node *temp = (node *)malloc(sizeof(node));
printf("Enter number = ");
scanf("%d", &temp->num);
temp -> next = start1;
start1 = temp;
}
void split()
{
while(start1 != NULL)
{
node *temp1 = (node *)malloc(sizeof(node));
temp1 ->num = start1 ->num;
temp1->next = start2;
start2 = temp1;
start1 = start1 -> next;
if(start1 != NULL)
{
node *temp2 = (node *)malloc(sizeof(node));
temp2 ->num = start1 ->num;
temp2->next = start3;
start3 = temp2;
start1 = start1 -> next;
}
}
}
int main()
{
int n;
scanf("%d", &n);
while(n--)
push();
split();
node *temp = start2;
while(temp != NULL)
{
printf("%d ", temp ->num);
temp = temp ->next;
}
printf("\n");
temp = start3;
while(temp != NULL)
{
printf("%d ", temp ->num);
temp = temp ->next;
}
return 0;
}
And the code provided with the question is -
/*Program to alternatively split a linked list into two halves */
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
/* Link list node */
struct node
{
int data;
struct node* next;
};
/* pull off the front node of the source and put it in dest */
void MoveNode(struct node** destRef, struct node** sourceRef) ;
/* Given the source list, split its nodes into two shorter lists.
If we number the elements 0, 1, 2, ... then all the even elements
should go in the first list, and all the odd elements in the second.
The elements in the new lists may be in any order. */
void AlternatingSplit(struct node* source, struct node** aRef, struct node** bRef)
{
/* split the nodes of source to these 'a' and 'b' lists */
struct node* a = NULL;
struct node* b = NULL;
struct node* current = source;
while (current != NULL)
{
MoveNode(&a, ¤t); /* Move a node to list 'a' */
if (current != NULL)
{
MoveNode(&b, ¤t); /* Move a node to list 'b' */
}
}
*aRef = a;
*bRef = b;
}
/* Take the node from the front of the source, and move it to the front of the dest.
It is an error to call this with the source list empty.
Before calling MoveNode():
source == {1, 2, 3}
dest == {1, 2, 3}
Affter calling MoveNode():
source == {2, 3}
dest == {1, 1, 2, 3}
*/
void MoveNode(struct node** destRef, struct node** sourceRef)
{
/* the front source node */
struct node* newNode = *sourceRef;
assert(newNode != NULL);
/* Advance the source pointer */
*sourceRef = newNode->next;
/* Link the old dest off the new node */
newNode->next = *destRef;
/* Move dest to point to the new node */
*destRef = newNode;
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at the beginging of the linked list */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in a given linked list */
void printList(struct node *node)
{
while(node!=NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
/* Drier program to test above functions*/
int main()
{
/* Start with the empty list */
struct node* head = NULL;
struct node* a = NULL;
struct node* b = NULL;
/* Let us create a sorted linked list to test the functions
Created linked list will be 0->1->2->3->4->5 */
push(&head, 5);
push(&head, 4);
push(&head, 3);
push(&head, 2);
push(&head, 1);
push(&head, 0);
printf("\n Original linked List: ");
printList(head);
/* Remove duplicates from linked list */
AlternatingSplit(head, &a, &b);
printf("\n Resultant Linked List 'a' ");
printList(a);
printf("\n Resultant Linked List 'b' ");
printList(b);
getchar();
return 0;
}
My query here is, which of these two codes are more efficient and more correct for this question, considering the time complexity, space complexity and every other factor?
And why?
A detailed explanation will be more helpful.
When you just split a linked list, you don't need any memory allocations, it's enough to just shuffle around pointers.
Your code does memory allocations when splitting, so it is rather inefficient that way, the model answer code is much better.
But worse, your code leaks memory. It loses the pointers to original list elements without freeing them. So your code is actually buggy, in a bad way.
To fix just the memory leak, which is an actual bug, you would need to change the two start1 = start1 -> next; lines to this:
node *tmp_next = start1->next;
free(start1);
start1 = tmp_next;
For other changes, the model answer is a good example, but most important things would be: Get rid of the extra malloc calls, and do the split by moving nodes, instead of allocating new node and copying data (and, after above bugfix, freeing the old node). And then get rid of the global variables, instead add parameters to the functions, like in the model answer.
Just another quick split, no new allocations, and keeping the original list reduced to odd elements, while forming the new lists for even ones, along with comment on each critical step
void split_in_evenodd(node *orig)
{
if(!orig)
return;
node *e, *cur, *e_hd;
e = orig->next; // point first even member
e_hd = e; // keep a head pointer to even list
if(!e) // covers the case of list with single element
return;
orig->next = e->next; // make orig skip the even node
cur = orig->next; // cur moves to next odd node
while(cur && cur->next) {
e->next = cur->next; // even pointing to next even node
e = e->next; // move even list forward
cur->next = e->next; // update odds next
cur = e->next;// move current forward (to next odd)
}
}
While solving this problem, I came up with this approach where I have created separate head nodes for both the splits and then with the help of count variable, all odd count linked list nodes are sent to split linked list 1 and all even count linked list nodes are sent to split linked list 2.
Hope it helps! This code is in C language.
#include <stdio.h>
#include <stdlib.h>
struct node *add_at_end(struct node *ptr,int item);
struct node{
int data;
struct node *next;
};
void main(){
struct node *head=malloc(sizeof(struct node));
head->data=1;
head->next=NULL;
// first node gets created
struct node *ptr=head;
//now we will add other nodes at the end
ptr=add_at_end(ptr,2);
ptr=add_at_end(ptr,3);
ptr=add_at_end(ptr,4);
ptr=add_at_end(ptr,5);
//the nodes get added to the linked list.Now let's print the data of all these nodes
ptr=head;
while(ptr!=NULL){
printf("%d ",ptr->data);
ptr=ptr->next;
}
printf("\n");
int count;
struct node *splitNode=malloc(sizeof(struct node));
struct node *forward=malloc(sizeof(struct node));
forward=head;
//now we will create the 1st split linked list
struct node *headll1=malloc(sizeof(struct node));
splitNode=forward;
forward=forward->next;
headll1->data=splitNode->data;
headll1->next=NULL;
struct node *ptr1=headll1;
count=1;
//now we will create the 2nd split linked list
struct node *headll2=malloc(sizeof(struct node));
splitNode=forward;
forward=forward->next;
headll2->data=splitNode->data;
headll2->next=NULL;
struct node *ptr2=headll2;
count++;
//head nodes of both the split linked lists is ready
while(forward!=NULL){
splitNode=forward;
forward=forward->next;
count+=1;
if(count%2==1){
ptr1->next=splitNode;
splitNode->next=NULL;
ptr1=ptr1->next;
}else{
ptr2->next=splitNode;
splitNode->next=NULL;
ptr2=ptr2->next;
}
}
//we have finished adding the nodes to linked list 1 and 2 alternatively based on count.
//now let's print both the linked lists.
ptr1=headll1;
while(ptr1!=NULL){
printf("%d ",ptr1->data);
ptr1=ptr1->next;
}
printf("\n");
ptr2=headll2;
while(ptr2!=NULL){
printf("%d ",ptr2->data);
ptr2=ptr2->next;
}
}
struct node *add_at_end(struct node *ptr,int item){
struct node *temp=malloc(sizeof(struct node));
temp->data=item;
ptr->next=temp;
temp->next=NULL;
return temp;
}
Related
This question already has answers here:
Using pointers to remove item from singly-linked list
(8 answers)
Closed 2 years ago.
I am checking the parity of the length of a singly linked list:
if it's odd, I have to delete the first node;
if it's even, I have to delete the last node.
I am able to figure out the parity but can't delete the relevant nodes.
Given that I also have to use the signature void sil(struct node **head), what should I change and add to my code?
// C program to check length
// of a given linklist
#include<stdio.h>
#include<stdlib.h>
// Defining structure
struct Node
{
int data;
struct Node* next;
};
// Function to check the length of linklist
int LinkedListLength(struct Node* head)
{
while (head && head->next)
{
head = head->next->next;
}
if (!head)
return 0;
return 1;
}
// Push function
void push(struct Node** head, int info)
{
// Allocating node
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
// Info into node
node->data = info;
// Next of new node to head
node->next = (*head);
// head points to new node
(*head) = node;
}
// Driver function
int main(void)
{
struct Node* head = NULL;
// Adding elements to Linked List
push(&head, 4);
push(&head, 5);
push(&head, 7);
push(&head, 2);
push(&head, 9);
push(&head, 6);
push(&head, 1);
push(&head, 2);
push(&head, 0);
push(&head, 5);
push(&head, 5);
int check = LinkedListLength(head);
// Checking for length of
// linklist
if(check == 0)
{
printf("Even\n");
}
else
{
printf("Odd\n");
}
return 0;
}
typedef struct Node Node;
You can do that relatively easily with a simple function that takes the address of your list and the parity value as parameters, e.g.
/** delete 1st or last node from list given parity,
* parity odd, delete 1st node, otherwise delete last
*/
void del_first_last_node (Node **head, int parity)
{
Node **ppn = head; /* pointer to pointer */
Node *pn = *head; /* pointer to node */
if (parity & 1) { /* is parity odd delete first node */
*ppn = pn->next; /* set node at current address to next */
free (pn);
return;
}
for (; pn; ppn = &pn->next, pn = pn->next) { /* loop to end */
if (pn->next == NULL) { /* if next pointer NULL */
*ppn = pn->next; /* set node at current address to next */
free (pn);
break;
}
}
}
Above, parity is checked for odd, and if so, the first node is deleted (and properly freed). If the parity is even, you loop to the end of the list and delete the last node (again freeing the deleted node)
Iterating with both the address of the node and a pointer to node means there is no need to keep track of the prior node or any special cases. You are simply replacing the node at the current address with the next in the list. In the case of the first node, you just replace the node at the current head address with the next node (and since you also maintain a pointer to the node which is unchanged, you use that to free the original node) For the last node, you are just replacing its contents with NULL. See Linus on Understanding Pointers
the idea behind deleting a node is in general the same:
Create temp node that points to the node you want to delete in your structure.
If you want to delete the head, you can first point to the head with your temp node and then set your head to point to the item next to it. It should look something like this: node->head = node->head->next; and then of course free your temp pointer.
If you want to delete the tail, there are several cases to be covered. If you don't use a sentinel node , you have to traverse your list in a way that it will not destroy or corrupt the original one. The code for that should look like this:
int deleteTail(list_t* list){
int toReturn;
//declare a temp pointer to the head of your list
node_t* temp = list->head;
//here you found the last node and have it in a temp pointer.
while(temp->next != NULL) temp=temp->next;
//get the value you want to return
toReturn = temp->data;
//free the last element
free(temp);
return toReturn;
}
"I am checking if the singly linked list is odd or even. If it's odd I have to delete first node and if it's even I have to delete last node.
I did the part where I found it's odd or even. But I can't delete nodes. I'll be really happy if you can help.
Also I have to use this parameter " void sil(struct node **head) " What should I change and add to my code?"
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
void push(struct node** head, int info) {
struct node *newN = (struct node *) malloc(sizeof(struct node));
newN->data = info;
newN->next = *head;
*head= newN;
}
void sil(struct node **head){
if (*head==NULL) return;
struct node *ptail=NULL;
struct node *tail=*head;
int i;
for (i=1; tail->next!=NULL; ptail=tail, i++, tail=tail->next);
if (i%2){
tail=*head;
*head=(*head)->next;
}else{
ptail->next=NULL;
}
free(tail);
}
int main(void){
struct node *head = NULL;
push(&head, 4);
push(&head, 5);
push(&head, 7);
push(&head, 2);
push(&head, 9);
push(&head, 6);
push(&head, 1);
push(&head, 2);
push(&head, 0);
push(&head, 5);
push(&head, 5);
sil(&head);
return 0;
}
Try it.
I must write a code for a lab and i don't understand how i can insert the nodes with which function.
struct list
{int value;
struct list * next;};
int main()........
the code says that we ask the user how many integers (N) he wants to insert to the list.. so easy printf, scanf
AND THEN ..It will ask for the numbers and list them in the order they are given.
I think that i need a for loop
but i know many function for inserting for example insertAfter, push etc, etc
I need you help! Thank you
The structure you have given represents a node. You first create a head of the list, then you need to read numbers one by one, create a node for each number and append it at the end of the list using append() function defined in the code given below.
Here is the full program you require (function codes taken from geeksforgeeks.org):
#include <stdio.h>
#include <stdlib.h>
// A linked list node
struct Node
{
int data;
struct Node *next;
};
/* Given a reference (pointer to pointer) to the head
of a list and an int, appends a new node at the end */
void append(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
struct Node *last = *head_ref; /* used in step 5*/
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be the last node, so make next of
it as NULL*/
new_node->next = NULL;
/* 4. If the Linked List is empty, then make the new node as head */
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
return;
}
// This function prints contents of linked list starting from head
void printList(struct Node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
int main()
{
/* Start with the empty list */
struct Node* head = NULL;
int n;
scanf("%d", &n);
for(int i=0; i<n; i++) {
int e;
scanf("%d", &e);
append(&head, e);
}
printList(head);
}
Problem was to find the intersection of 2 sorted linked lists and store the common elements in the third list.
My approach was to make temporary pointers temp1 and temp2 initializing both to head1 (head of list 1) and head2 (head of list 2) respectively.And then traversing both lists and comparing elements and shifting temp1 and temp2 accordingly.The code works fine.
Test case:
First linked list=> 1->2->3->4->6
Second linked list be 2->4->6->8, then function should create and return a third list as 2->4->6.
But I am confused about what is the time complexity: O(m+n) or O(min(m,n))? (m,n are number of elements in list 1 and list 2).
My Code:
#include<stdio.h>
#include<stdlib.h>
/* Link list node */
struct Node
{
int data;
struct Node* next;
};
void append(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
struct Node *last = *head_ref; /* used in step 5*/
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be the last node, so make next
of it as NULL*/
new_node->next = NULL;
/* 4. If the Linked List is empty, then make the new node as head */
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
return;
}
struct Node* sortedIntersect(struct Node* head1,struct Node*head2)
{
struct Node*head3=NULL;
struct Node*temp1=head1;
struct Node*temp2=head2;
while(temp1!=NULL&&temp2!=NULL)
{
if(temp1->data<temp2->data)
{if(temp1->next!=NULL)
temp1=temp1->next;
else
break;
}
else if(temp1->data>temp2->data)
{
if(temp2->next!=NULL)
temp2=temp2->next;
else{
break;
}
}
else
{
append(&head3,temp1->data);
temp1=temp1->next;
temp2=temp2->next;
}
}
return head3;
}
/* Function to insert a node at the beginging of the linked list */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in a given linked list */
void printList(struct Node *node)
{
while (node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
int main()
{
/* Start with the empty lists */
struct Node* a = NULL;
struct Node* b = NULL;
struct Node *intersect = NULL;
/* Let us create the first sorted linked list to test the functions
Created linked list will be 1->2->3->4->5->6 */
push(&a, 6);
push(&a, 5);
push(&a, 4);
push(&a, 3);
push(&a, 2);
push(&a, 1);
/* Let us create the second sorted linked list
Created linked list will be 2->4->6->8 */
push(&b, 8);
push(&b, 6);
push(&b, 4);
push(&b, 2);
/* Find the intersection two linked lists */
intersect = sortedIntersect(a, b);
printf("\n Linked list containing common items of a & b \n ");
printList(intersect);
return 0;
}
This is a problem that can be solved in O(m+n).
However, this solution is not O(m+n). Each element you add in the method intersectSorted is added with the method append, which traverses the whole current output list.
So the time complexity is O((m+n)log(min(m,n))
As in each iteration of while, at least one of the pointers go to the next, and the condition of while termination is none of the pointers reach to the end, the time complexity would be O(min(m,n)).
In worst case it will be O(m+n)
example: {1,3,5,7} {2,4,6,8}
in this case you traverse both the
list.
In average case it will be
O(min(m,n) + number of times you don't increment the smaller list)
example : {1,2,3,4,6} {2,4,6,8,9,10}
in this case you terminate
the loop once you reach the end of first lined list but in between you
increment the second list without increment the first list.
In best case it will be O(min(m,n))
example: {1,2,3} {1,2,3,4,}
in this case you will terminate
the loop after reaching end of the first list.
while debugging i found that replacing **s by *s makes the program work correctly, but i dont understand why **s causes eroor in SortedMerge() function, please help
#include<stdio.h>
#include<stdlib.h>
/* Link list node */
struct node
{
int data;
struct node* next;
};
/* function prototypes */
struct node* SortedMerge(struct node* a, struct node* b);
void FrontBackSplit(struct node* source,
struct node** frontRef, struct node** backRef);
/* sorts the linked list by changing next pointers (not data) */
void MergeSort(struct node **head)
{
/*if list empty or contains one element, return head*/
if((*head==NULL)||((*head)->next)==NULL)
return *head;
/*if control here, implies, atleast 2 nodes present in ll*/
struct node* a=NULL;
struct node* b=NULL;
FrontBackSplit(*head,&a,&b);
MergeSort(&a);
MergeSort(&b);
*head=SortedMerge(a,b);
}
/* See http://geeksforgeeks.org/?p=3622 for details of this
function */
struct node* SortedMerge(struct node* first,struct node* second)
{
if((first==NULL)&&(second==NULL))
return NULL;
if(first==NULL)
return (second);
if(second==NULL)
{
return (first);
}
/*first and second list both have elements*/
struct node **s=NULL;
struct node *z=NULL;
while((first!=NULL)&&(second!=NULL))
{
if(*s==NULL)
{
*s = malloc(sizeof(struct node));
z = *s;
}
else
{
z->next = malloc(sizeof(struct node));
z = z->next;
}
if(first->data<=second->data)
{
z->data = first->data;
first = first->next;
}
else
{
z->data = second ->data;
second = second ->next;
}
}
while(first!=NULL)
{
z->next = malloc(sizeof(struct node));
z = z->next;
z->data = first->data;
first = first->next;
}
while(second!=NULL)
{
z->next = malloc(sizeof(struct node));
z = z->next;
z->data = second->data;
second = second->next;
}
z->next=NULL;
return *s;
}
/* UTILITY FUNCTIONS */
/* Split the nodes of the given list into front and back halves,
and return the two lists using the reference parameters.
If the length is odd, the extra node should go in the front list.
Uses the fast/slow pointer strategy. */
void FrontBackSplit(struct node* head,struct node **first,struct node **last)
{
struct node *slow_ptr=head;
struct node *fast_ptr=head->next;
if((head==NULL)||(head->next==NULL))
{
*first=head;
*last=NULL;
return;
}
while((fast_ptr!=NULL)&&(fast_ptr->next!=NULL))
{
fast_ptr=fast_ptr->next->next;
slow_ptr=slow_ptr->next;
}
*last=slow_ptr->next;
slow_ptr->next=NULL;
*first=head;
return;
}
/* UTILITY FUNCTIONS */
/* Split the nodes of the given list into front and back halves,
and return the two lists using the reference parameters.
If the length is odd, the extra node should go in the front list.
Uses the fast/slow pointer strategy. */
/* Function to print nodes in a given linked list */
void printList(struct node *node)
{
while(node!=NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
/* Function to insert a node at the beginging of the linked list */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node =
(struct node*) malloc(sizeof(struct node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Drier program to test above functions*/
int main()
{
/* Start with the empty list */
struct node* res = NULL;
struct node* a = NULL;
/* Let us create a unsorted linked lists to test the functions
Created lists shall be a: 2->3->20->5->10->15 */
push(&a, 15);
push(&a, 10);
push(&a, 5);
push(&a, 20);
push(&a, 3);
push(&a, 2);
/* Sort the above created Linked List */
MergeSort(&a);
printf("\n Sorted Linked List is: \n");
printList(a);
getchar();
return 0;
}
here is the working SortedMerge() function, that i replaced..
struct node* SortedMerge(struct node* a, struct node* b)
{
struct node* result = NULL;
/* Base cases */
if (a == NULL)
return(b);
else if (b==NULL)
return(a);
/* Pick either a or b, and recur */
if (a->data <= b->data)
{
result = a;
result->next = SortedMerge(a->next, b);
}
else
{
result = b;
result->next = SortedMerge(a, b->next);
}
return(result);
}
The split function divides the list into two pieces; no memory is allocated or freed. (Actually *head == *a after that, but that doesn't matter).
The merge function ought to be the inverse of split: combine two pieces into one list, without allocating or freeing. However it contains malloc statements. This must be an error; you should be merging the two lists by adjusting which element points to which next element.
It might be simpler to change your interface: just have split(struct node **a, struct node **b) that has pre-req *b = NULL and it moves half of a's nodes to b; and then merge(struct node **a, struct node **b); that moves all of b's nodes to a.
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);