I have been trying to do pairwise swap of linkedlist elements. In place of swapping the elements by data, I am swapping them by swapping the links:
input 1: 1->2->3->4->5
output 1: 2->1->4->3->5
input 2: 1->2->3->4->5->6
output 2: 2->1->4->3->6->5
#include <iostream>
using namespace std;
struct node{
int data;
struct node *next;
};
struct node* func(struct node *f, struct node *s){
if(s==NULL){
return f;
}
struct node *rest1;
rest1 = s->next;
s->next = f;
if(rest1){
f->next = func(rest1,rest1->next);
}
return s;
}
void show(struct node *head){
while(head!=NULL){
cout<<" "<<head->data;
head = head->next;
}
}
int main() {
//code
struct node *head =(struct node*)malloc(sizeof(struct node));
head->data=1;
head->next = (struct node*)malloc(sizeof(struct node));
head->next->data = 2;
head->next->next = (struct node*)malloc(sizeof(struct node));
head->next->next->data = 3;
head->next->next->next = (struct node*)malloc(sizeof(struct node));
head->next->next->next->data = 4;
//head->next->next->next->next=(struct node*)malloc(sizeof(struct node));
//head->next->next->next->next->data=5;
head = func(head,head->next);
show(head);
return 0;
}
This code works fine for odd length list but does not work for even length.
I think the problem is in:
if(s==NULL){
return f;
}
statement which I am using to make previous f->next=NULL (in case of even length).
Since you tagged this as C++, I'd recommend STL's <list>. You can accomplish what you want with its splice method which allows you to manipulate the list. One possible implementation would look something like:
void alternate(list<int>& l)
{
if (l.empty())
return;
auto from_itr = cbegin(l);
auto to_itr = from_itr;
for (; ++to_itr != cend(l) && ++to_itr != cend(l);) {
l.splice(to_itr, l, from_itr);
++from_itr;
}
}
NOTE: The from_itr in the loop is incremented only once because it has been moved in the list to precede the next node of interest.
Consider the case of Even length list say 1->2->3->4->5->6 when f points to 5, s points to 6 & rest1 points to null.
s->next = f makes node 6->5 but still node 5 will point to 6. Thus a loop will be formed where 6->5->6->5..............so on.
Thus to make this code work add an else statement here
if(rest1){
f->next = func(rest1,rest1->next);
}
else f->next = NULL;
This will make 5->NULL preventing an infinite loop.Thus your function will look like this
struct node* func(struct node *f, struct node *s){
if(s==NULL){
return f;
}
struct node *rest1;
rest1 = s->next;
s->next = f;
if(rest1){
f->next = func(rest1,rest1->next);
}
else f->next = NULL;
return s;
}
Related
I am not getting the else part in create_node() function..
As you can see in the else part ,memory block is allocated for r and coeff and power are assigned...but when did they assign r node to the last of linkedlist.. when did they traverse to end of linked list
I mean how is it getting assigned at the last of linked list.
#include <bits/stdc++.h>
using namespace std;
struct Node {
int coeff;
int pow;
struct Node* next;
};
// Function to create new node
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
*temp = r;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
else {
r->coeff = x;
r->pow = y;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
}
// Display Linked list
void show(struct Node* node)
{
while (node->next != NULL) {
printf("%dx^%d", node->coeff, node->pow);
node = node->next;
if (node->coeff >= 0) {
if (node->next != NULL)
printf("+");
}
}
}
// Driver code
int main()
{
struct Node *poly1 = NULL, *poly2 = NULL, *poly = NULL;
// Create first list of 5x^2 + 4x^1 + 2x^0
create_node(5, 2, &poly1);
create_node(4, 1, &poly1);
create_node(2, 0, &poly1);
// Create second list of -5x^1 - 5x^0
create_node(-5, 2, &poly2);
create_node(-5, 0, &poly2);
printf("1st Number: ");
show(poly1);
printf("\n2nd Number: ");
show(poly2);
return 0;
}
Am I the only one who thinks that create_node() function should be more like this than the above code?
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
r->next=NULL;
*temp = r;
}
else {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
r->next=NULL;
while(z->next!=NULL)
{
z=z->next;
}
z->next=r;
}
}
I really want to know how is it producing the right output, even without assigning newnode to last of linked list
If you are going to write a C++ program then use the operator new to allocate memory instead of calling the C function malloc.
If you want to append a node to the list to its tail then it is better to use a two-sided singly-linked list.
The first function create_node does not make a sense due to appending a dummy node with uninitialized data members except the data member next.
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
The function show can invoke undefined behavior because it does not check whether the passed pointer is equal to nullptr.
// Display Linked list
void show(struct Node* node)
{
while (node->next != NULL) {
//...
The functions as C++ functions can be declared and defined the following way without using a duplicated code.
void create_node( Node **head, int x, int y )
{
Node *new_node = new Node { x, y, nullptr };
while ( *head ) head = &( *head )->next;
*head = new_node;
}
std::ostream & show( const Node *head, std::ostream &os = std::cout )
{
for ( ; head != nullptr; head = head->next )
{
os << head->coeff << '^' << head->pow;
if ( head->next != nullptr ) os << " + ";
}
return os;
}
I am not getting the else part in create_node() function.. As you can
see in the else part ,memory block is allocated for r and coeff and
power are assigned...but when did they assign r node to the last of
linkedlist.. when did they traverse to end of linked list I mean
how is it getting assigned at the last of linked list.
It is not. When you pass a null Node*, z will be null, and your else code is dereferencing r which hasn't even been initialized.
// Function to create new node
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
*temp = r;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
else {
r->coeff = x;
r->pow = y;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
}
Am I the only one who thinks that create_node() function should be
more like this than the above code?
This seems to solve above's code issues. Here you are creating a Node and assigning it to r, then appending it at the end of z (input Node*). Notice though that you are duplicating the code for creating r in both blocks of code. You could take at least that part out of the if-else.
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
r->next=NULL;
*temp = r;
}
else {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
r->next=NULL;
while(z->next!=NULL)
{
z=z->next;
}
z->next=r;
}
}
Hi all I'm having an issues in a linked list problem. Given two piece of code I've to find why one of them is not working
Code 1 is
struct node {
int data;
struct node *link;
};
void insert(struct node *head) {
struct node *last, *temp;
head = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &head->data);
head->link = NULL;
last = head;
{
int n = 3;
while(n>0){
temp = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &temp->data);
temp->link = NULL;
last->link = temp;
last = temp;
n--;
}
}
return;
}
void display(struct node *p) {
while(p) {
printf("%d ",p->data);
p = p->link;
}
return;
}
int main() {
struct node *head;
insert(head);
display(head);
return 0;
}
and second code is
struct node {
int data;
struct node *link;
}*head;
void insert() {
struct node *last, *temp;
head = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &head->data);
head->link = NULL;
last = head;
{
int n = 3;
while(n>0){
temp = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &temp->data);
temp->link = NULL;
last->link = temp;
last = temp;
n--;
}
}
return;
}
void display(struct node *p) {
while(p) {
printf("%d ",p->data);
p = p->link;
}
return;
}
int main() {
insert();
display(head);
return 0;
}
Now my question is why declaring head in main in the first is not giving o/p for display function wheres declaring it globally in second code is working? Asking this as I'm wondering that in first case head is declared in main and passed as an address so after coming back from insert function it should get the effect of that insert function operation but it's not working like the way and not giving ant o/p for display function
The issue is that, in the first code, insert receives a copy of the main's head pointer and modifies that copy by making it point to some newly allocated memory. That modification never propagates back to main.
To make it propagate, use a pointer to pointer:
void insert(struct node **head) {
struct node *last, *temp;
*head = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &(*head)->data);
(*head)->link = NULL;
last = *head;
{
int n = 3;
while(n>0){
temp = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &temp->data);
temp->link = NULL;
last->link = temp;
last = temp;
n--;
}
}
return;
}
and then, in main, call it like so:
insert(&head);
Alternatively, you could make insert take a pointer but also return a pointer (i.e. the new head):
struct node* insert(struct node *head) { ... }
One issue what that API is that it's rather error-prone: it's very easy to call insert() and forget to deal with its return value.
In the following code i am trying to merge 2 list alternatively and than printing them in reverse order. But my code is not giving correct output it is just merging the last element of the second list.
input:
1
3
1 3 5
3
2 4 6
Actual Output:
5 6 3 1
Expected Output:
5 6 3 4 1 2
Can someone please tell me whats the problem in my code....
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node *next;
};
void push(struct Node ** head_ref, int new_data)
{
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(struct Node *head)
{
struct Node *temp = head;
while (temp != NULL)
{
cout<<temp->data<<' ';
temp = temp->next;
}
cout<<' ';
}
void mergeList(struct Node **head1, struct Node **head2);
int main()
{
int T;
cin>>T;
while(T--){
int n1, n2, tmp;
struct Node *a = NULL;
struct Node *b = NULL;
cin>>n1;
while(n1--){
cin>>tmp;
push(&a, tmp);
}
cin>>n2;
while(n2--){
cin>>tmp;
push(&b, tmp);
}
mergeList(&a, &b);
printList(a);
printList(b);
}
return 0;
}
void mergeList(struct Node **p, struct Node **q)
{
struct Node*temp1=*p,*temp2=*q,*t1,*t2;
while(temp1!=NULL)
{
if(temp2==NULL)
break;
t1=temp1->next;
t2=temp2;
temp1->next=t2;
t2->next=t1;
temp1=t1;
*q=temp2->next;
temp2=*q;
}
}
To be honest, I'm really not sure what exactly you are doing in the mergeList function. The code is pretty cancerous so I did not take the liberty of verifying the correctness. I have renamed a few variables and re-written the code, so you can take this as a reference point and see what's wrong with your code.
void mergeList(struct Node **p, struct Node **q)
{
struct Node *a = *p, *b = *q, *next_a, *next_b;
while(a != NULL)
{
if(b == NULL)
break;
next_a = a->next;
a->next = b;
next_b = b->next;
b->next = next_a;
a = next_a;
b = next_b;
}
}
Hope this helps. Cheers.
I am trying to insert element at the end of linked list but the while loop doesn't terminate. I am not able to understand why is this happening. Here is my code.
I am calling this function inside my main() function.
struct node{
int data;
struct node* link;
};
struct node * head;
void insert_last(int element){
struct node * temp = (node*)malloc(sizeof(struct node));
temp->data = element;
temp->link = NULL;
if(head==NULL){
head = temp;
}
struct node * temp1 = head;
while(temp1->link!=NULL){
temp1 = temp1->link;
}
temp1->link = temp;
}
Here is the main method:
int main()
{
head = NULL;
printf("Enter the no. of nodes or elements you want to make linked list of. ");
int n;
scanf("%d",&n);
int element = 0;
for(int i = 0; i<n; i++){
printf("Enter the element\n");
scanf("%d",&element);
insert_last(element);
std::cout<<"Element inserted\n\n";
}
//print_recursive(head);
print();
}
That's easy.
if(head==NULL){
head = temp;
}
In that case, you are already done with what are you doing. If you continue, temp1 becomes the temp. Then temp1->link = temp; makes this node point to itself. Second insertion will never find end because your list is circular now and while(temp1->link!=NULL) will never end.
What you should do is simply put return;.
if(head==NULL){
head = temp;
return;
}
I'm trying to make linked list similar too the one here:
linked list in C
That is to have the "head", I called it first, inside another struct. However I found doing that change. Makes it hard to add values to the list_item struct. I have tried some few things to see if it works. It compiles, however when I run the code it will crash. Any help would be helpful here. I know the cause of the crash is when I want to point the new_node to the linked_list.
#include <iostream>
using namespace std;
struct list_item
{
int key;
int value;
list_item *next;
};
struct list
{
struct list_item *first;
};
int main()
{
list *head;
list *new_node;
head = NULL;
head->first = NULL;
for(int i = 0; i < 10; i++)
{
//allocate memory for new_node
new_node = (list*)malloc(sizeof(list));
new_node->first = (list_item*)malloc(sizeof(list_item));
//adding the values
new_node->first->key = i;
new_node->first->value = 10 + i;
//point new_node to first;
new_node->first->next = head->first;
//point first to new_node;
head->first = new_node->first;
}
//print
list *travel;
travel->first = head->first;
int i = 0;
while(travel != NULL)
{
cout << travel->first->value << endl;
travel->first = travel->first->next;
}
return 0;
}
You are creating 10 lists, I think you might try to do something like this:
#include <iostream>
using namespace std;
struct list_item
{
int key;
int value;
list_item *next;
};
struct list
{
struct list_item *first;
};
int main()
{
//Just one head is needed, you can also create this
// on the stack just write:
//list head;
//head.first = NULL;
list *head = (list*)malloc(sizeof(list));
list_item *new_node = NULL;
head->first = NULL;
for(int i = 0; i < 10; i++)
{
//allocate memory for new_node
new_node = (list_item*)malloc(sizeof(list_item));
//adding the values
new_node->key = i;
new_node->value = 10 + i;
//if the list is empty, the element you are inserting
//doesn't have a next element
new_node->next = head->first;
//point first to new_node. This will result in a LIFO
//(Last in First out) behaviour. You can see that when you
//compile
head->first = new_node;
}
//print the list
list_item *travel;
travel = head->first;
while(travel != NULL)
{
cout << travel->value << endl;
travel = travel->next;
}
//here it doesn't matter, but in general you should also make
//sure to free the elements
return 0;
}
This is what is going on. At first you only have one head and no elements.
head
|
|
V
NULL
Then you add your first element. Make sure that the "new_node->next==NULL":
head
|
|
V
node: ------------------> NULL
key = 0
value = 10
Then you add another node in front but append your first node to its next node. you move the pointer from the head to the new node
head:
first
|
|
V
node: ---------> node: -------------> NULL
key: 1 key: 0
value: 11 value: 10
etc.
Since you are using c++, you might consider using "new" and "delete". Just replace
new_node = (list_item*)malloc(sizeof(list_item));
with
list *head = new list
The next line only allocates memory for your list struct. The list contains only a pointer, you must also allocate memory for new_node->first before assigning to any of its members.
//allocate memory for new_node
new_node = (list*)malloc(sizeof(list));
I think you want something more like this:
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct tag_list_item
{
int key;
int value;
struct tag_list_item *next;
} list_item;
typedef struct
{
list_item *head;
} list;
int main()
{
list my_list;
list_item *new_node;
list_item *previous_node = NULL;
my_list.head = NULL;
for(int i = 0; i < 10; i++)
{
//allocate memory for new_node
new_node = (list_item*)malloc(sizeof(list_item));
//adding the values
new_node->key = i;
new_node->value = 10 + i;
if(previous_node == NULL)
{
my_list.head = new_node;
}
else
{
previous_node->next = new_node;
}
previous_node = new_node;
}
//print
list_item *iter = my_list.head;
while(iter != NULL)
{
cout << iter->value << endl;
iter = iter->next;
}
return 0;
}
Changes of note:
For malloc, I added:
#include <cstdlib>
I changed your list structures to typedefs, had to declare "next" using the tag since the typedef isn't complete at that point
typedef struct tag_list_item
{
int key;
int value;
struct tag_list_item *next;
} list_item;
I changed your list name to "my_list" and declared it directly (without the pointer). In this case you can just have the compiler allocate it automatically on the stack.
list my_list;
I keep a pointer for "previous_node" so that you can assign the "next" pointer much more easily. Notice that the first node allocated is pointed to by the "head" pointer in the list structure. I believe that is the traditional name for the pointer to the first element in a list.
if(previous_node == NULL)
{
my_list.head = new_node;
}
else
{
previous_node->next = new_node;
}
previous_node = new_node;
head = NULL;
head->first = NULL;
There's the issue. You can't follow a pointer and set it to NULL if you've set the pointer itself to NULL.
That should be
head = malloc(sizeof(list));
head->first = NULL;
That should fix your code.
Hope that helps,
Billy3
EDIT: There's also an issue with your FOR loop. When you allocate the list, you should only allocate the list itself once. When you insert an item, you only allocate a list_item. You're assigning a list pointer to a member which accepts only a list_item pointer ;)
See Gabe's post for a demonstration of correct behavior :)
Look at your struct declaration
struct list_item
{
int key;
int value;
list_item *next;
};
That should be
struct list_item
{
int key;
int value;
struct list_item *next;
};
Hope this helps,
Best regards,
Tom