I am new at linked List. Recently I have tried to create a program which takes an array and its size as input. then it converts the array into a linked list and print elements. But the program is not working and I guess it is because the head pointer get changed. So, what I can do to keep the head node unchanged?
#include<bits/stdc++.h>
using namespace std ;
struct node
{
int data ;
node* link ;
};
node* create_linkedlist (int ara[] , int siz )
{
node* head = NULL ;
node* temp = new node() ;
temp->data = ara[0] ;
temp->link = NULL ;
head = temp ;
node* tmhead = head->link ;
node* temp2 ;
for(int i = 1 ; i < siz ; i++)
{
temp2 = new node() ;
temp2->data = ara[i] ;
temp2->link = NULL ;
while ( tmhead->link!= NULL)
{
tmhead = tmhead->link ;
}
tmhead->link = temp2 ;
}
return head ;
}
void printlist( node* h_ref )
{
while (h_ref != NULL)
{
printf("%d " , h_ref->data) ;
h_ref = h_ref->link ;
}
}
int main()
{
int siz ;
cin>> siz ;
int ara[siz + 2];
for(int i = 0 ; i < siz ; i++)
{
cin >> ara[i] ;
}
node* hd = create_linkedlist(ara , siz) ;
node* temp = hd ;
printlist(temp) ;
return 0 ;
}
For the second element (first iteration of loop) in create_linkedlist() function, tmhead is NULL and you are trying to de-reference it which will lead to a crash.
Change the line node* tmhead = head->link ; to node* tmhead = head; and it should work fine.
Also try to use specific header instead of bits/stdc++.h and use nullptr instead of NULL. You don't need the while loop inside the for loop as well. Get rid of it and just change the for loop like below -
for(int i = 1 ; i < siz ; i++)
{
temp2 = new node() ;
temp2->data = ara[i] ;
temp2->link = NULL ;
tmhead->link = temp2 ;
tmhead = tmhead->link ;
}
Notice that in case of user provided size 0, your code acts wrongly. Better to include header node creation, population inside the loop as well.
With all the mentioned changes the function may look like this -
node* create_linkedlist (int ara[] , int siz )
{
node* head = nullptr;
node* temp = nullptr;
node* last = nullptr; // Keeps track of last inserted node
for(int i = 0; i < siz; i++)
{
temp = new node();
temp->data = ara[i];
temp->link = nullptr;
if (!head) {
head = temp;
}
if (last) {
last->link = temp;
}
last = temp;
}
return head ;
}
Related
I'm trying to implement a recursive reversal of a linked list. Along with providing a node* pointer as an argument, what should I give as an argument?
This function is when the head is declared locally in main. I successfully implemented this function when the head is declared globally since we do not need to pass the address of head explicitly(as it is accessible inside the function).
#include<bits/stdc++.h>
using namespace std ;
struct node{
int data ;
node* link ;
};
void insert(int n, node** head)
{
node* temp = new node() ;
temp->link = NULL ;
temp->data = n ;
if(*head == NULL)
{
*head = temp ;
}
else
{
node* ptr = *head ;
while(ptr->link != NULL)
{
ptr = ptr->link ;
}
ptr->link = temp ;
}
}
void print(node* ptr)
{
while(ptr != NULL)
{
cout<<ptr->data<<" " ;
ptr = ptr->link ;
}
}
void reverse(node* ptr, node** hptr)
{
node* temp = *hptr ;
if(ptr->link == NULL)
{
*hptr = ptr ;
return ;
}
ptr = ptr->link ;
reverse(ptr, &temp) ; //Line 10: Here is the main doubt. I want to write an equivalent of &head instead of &temp to pass the original address of head.
node* q = ptr->link ;
q->link = ptr ;
ptr->link = NULL ;
}
int main()
{
node* head = NULL ; //local head declaration
insert(5,&head) ;
insert(6,&head) ;
insert(7,&head) ;
insert(8,&head) ;
reverse(head,&head) ;
cout<<endl ;
print(head) ;
}
When the linked list is 5->6->7->8, there is no error and nothing is printed when I print this linked list.
The expected answer is 8->7->6->5 .
How do I rectify line 10, or any other error in my code?
Code with global head:
#include<iostream>
using namespace std ;
struct node{
int data ;
node* link ;
};
node* head ;
void reverse(node* ptr) //pointer to node
{
if((ptr->link) == NULL) //exit condition
{
head = ptr ;
return;
}
else
{
reverse(ptr->link) ;
node* q = ptr->link ; //temp variable that points to the adjacent(right) node of ptr
q->link = ptr ;
ptr->link = NULL ;
}
}
void print(node* ptr)
{
if (ptr == NULL)
{
return ;
}
else
{
cout<<ptr->data<<" " ;
ptr = ptr->link ;
print(ptr) ;
}
}
int main()
{
head = NULL ;
for(int i=0;i<4;i++)
{
node* temp = new node() ;
temp->link = NULL ;
temp->data = i ;
if(head == NULL)
{
head = temp ;
}
else
{
node* p = head ;
while(p->link != NULL)
{
p = p->link ;
}
p->link = temp ;
}
}
reverse(head) ;
print(head) ;
return 0 ;
}
This version works for me
void reverse(node* ptr, node** hptr)
{
if (ptr->link == NULL)
{
*hptr = ptr;
return;
}
reverse(ptr->link, hptr);
node* q = ptr->link;
q->link = ptr;
ptr->link = NULL;
}
The problem with the version above was the assignment ptr = ptr->link; immediately before the recursive call. Plus the incorrect treatment of the head pointer.
The code that I have made is this:
struct node
{
int value;
node *prev;
node *next;
};
void play()
{
node *head = NULL, *temp = NULL, *run = NULL;
for (int x = 1; x > 10; x++)
{
temp = new node(); //Make a new node
temp -> value = x; //Assign value of new node
temp -> prev = NULL; //Previous node (node before current node)
temp -> next = NULL; //Next node (node after current node)
}
if (head == NULL)
{
head = temp; //Head -> Temp
}
else
{
run = head; //Run -> Head
while (run -> next != NULL)
{
run = run -> next; //Go from node to node
}
run -> next = temp; //If next node is null, next node makes a new temp
temp -> prev = run;
}
run = head; //Play from start again
while (run != NULL) //Printing
{
printf("%d\n", run -> value);
run = run -> next;
}
}
int main()
{
play();
system ("pause");
return 0;
}
However, it is not working. There is no output (completely blank). How can I get this linked list to print properly? I want it to output:
1 2 3 4 5 6 7 8 9 10
Other options that I have is to make another separate function for the printing or move the whole thing to int main but I have already tried that and it still does not output anything.
For starters there is a typo in the condition of the first for-loop in the function
for (int x = 1; x > 10; x++)
^^^^^^
There must be
for (int x = 1; x <= 10; x++)
^^^^^^
Secondly the code that tries to add a new node to the list is outside the for-loop. So only the last allocated node will be added to the list. You have to place the code inside the loop.
Also if here is a double-linked list then it is desirable to have a tail node to which a new node will be appended.
And you should free all allocated memory before exiting the function.
The function can look the following way as it is shown in the demonstrative program.
#include <iostream>
#include <cstdlib>
struct node
{
int value;
node *prev;
node *next;
};
void play()
{
const int N = 10;
node *head = nullptr, *tail = nullptr;
for (int i = 0; i < N; i++)
{
node *temp = new node{ i + 1, tail, nullptr };
if (tail == nullptr)
{
head = tail = temp;
}
else
{
tail = tail->next = temp;
}
}
for (node *current = head; current != nullptr; current = current->next)
{
std::cout << current->value << ' ';
}
std::cout << std::endl;
while (head != nullptr)
{
node *temp = head;
head = head->next;
delete temp;
}
tail = head;
}
int main()
{
play();
// system("pause");
return 0;
}
The program output is
1 2 3 4 5 6 7 8 9 10
You could make the function more flexible by adding one parameter that specifies the number of nodes in the created list instead of using the magic number 10.
For example
void play( int n )
{
node *head = nullptr, *tail = nullptr;
for (int i = 0; i < n; i++)
{
node *temp = new node{ i + 1, tail, nullptr };
if (tail == nullptr)
{
head = tail = temp;
}
else
{
tail = tail->next = temp;
}
}
for (node *current = head; current != nullptr; current = current->next)
{
std::cout << current->value << ' ';
}
std::cout << std::endl;
while (head != nullptr)
{
node *temp = head;
head = head->next;
delete temp;
}
tail = head;
}
In this case the function can be called for example like
play( 10 );
or
play( 20 );
and so on.
When you run play(), you create 10 new nodes, but you store them nowhere before creating a new one. Thus, you "lose" all the nodes - except the last one, which is still in temp.
Instead, you should do something like:
for (int x = 1; x < 10; x++)
{
if (temp == nullptr) {
temp = new node();
temp -> value = x;
temp -> prev = nullptr;
temp -> next = nullptr;
head = temp;
} else {
temp -> next = new node();
temp -> next -> value = x;
temp -> next -> prev = temp;
temp -> next -> next = nullptr;
temp = temp -> next
}
}
Then, you can print your linked list as you already do:
run = head; //Play from start again
while (run != nullptr) //Printing
{
printf("%d\n", run -> value);
run = run -> next;
}
As noticed by #Vlad from Moscow, don't forget to free allocated memory before exiting the function.
Note that I use nullptr instead of NULL. It's a C++11 keyword that replaces NULL. Explications are here.
First your program never enters the for loop. Your loop is equivalent to:
int x=1;
while(x>10) { // always false
// do stuff
x++;
}
Therefore, temp is NULL, head is initialize to NULL and nothing happens.
Second, the initialization of your list is not in the loop, so at most only the head would be initialized. Move the closing bracket of the for loop at the end of your function (and adjust indentations etc).
In a second time, and if your compiler allows it, you might consider using more C++ idioms instead of C idioms (if your goal is to learn C++), using nullptr, cout, smart pointers... but it's an other story!
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct node{
int size;
char* name;
node* next;
}node;
void insertnodes( node** arrayhead , int index , node* ptr){
index = index - 1 ;
while ( index--){
*arrayhead = (*arrayhead)->next;
}
(*arrayhead)->next = new node;
(*arrayhead)->next = ptr;
}
int main(){
int n = 4;
node *A[n] ;
for ( int i = 0 ; i < n ; i++){
A[i] = NULL ;
}
A[0] = new node;
A[0]->size = 10;
A[0]->name = new char;
A[0]->name = "gunna";
A[0]->next = NULL;
//cout << A[0]->name << endl;
node* ptr = new node ;
ptr->size = 10;
ptr->name = new char;
ptr->name = "param";
ptr->next = NULL;
insertnodes(&A[0] , 1 , ptr);
node* ptrr = new node ;
ptrr->size = 10;
ptrr->name = new char;
ptrr->name = "sidd";
ptrr->next = NULL;
insertnodes(&A[0] , 2 , ptrr);
cout << A[0]->name << endl;
cout << A[0]->next->name;
}
It should have to print "gunna" and "param" .
but it is giving "param" and "sidd" as output.
I don'nt know where i am going wrong . I have tried a lot of things but i am still confused
Pls help ...
I am using code blocks to compile this program ..
In your insertnodes() you are passing a double pointer node** arrayhead, thus, by dereferncing it later, you are overwriting the current value of next pointer, which will later cause memory leak in your program.
What you should do instead is create a temporary variable node* tmp which you will change when the index decreases. Then, you don't need to allocate a new node to the next pointer, because you already have a pointer you want to attach as next.
The fixed code would look like this:
void insertnodes(node** arrayhead, int index, node* ptr) {
index = index - 1;
node* tmp = *arrayhead;
while (index--) {
tmp = tmp->next;
}
tmp->next = ptr;
}
EDIT: This is completely useless:
int n = 4;
node *A[n] ;
for ( int i = 0 ; i < n ; i++){
A[i] = NULL ;
}
All you need to create a linked list is a single node (e.g. list's head).
But as this is a linked list, you don't need to pass index really. All you need is a head, over which you could iterate until you find node->next which will be NULL - this is the place you need to insert your new node at (this is how it's typically done).
Finding a cycle in singly linked list and find the node from where cycle starts.
I have seen use of two pointers( generally slow and fast) to find the cycle but I have written this code and it seems to be working fine. My question is, is there something my code is missing out on, while finding the cycle in singly linked list.
Node* find_cycle_node(Node *head){
Node *p=head;
Node *q;
while(p->next!=null)
{
q=p->next;
while(q->next!=null)
{
if(p==q) return q; //Node repeated i.e cycle
else (q=q->next;)
}
p=p->next;
}
return null; // no cycle detected
}
Your inner loop will not terminate if there is cycle which is a couple nodes down the handle, e.g., it will be an infinite loop for something like this:
1 -> 2 -> 3 -> 4 -> 5
^ |
| |
+---------+
How about this ?
struct Node_
{
int ix ;
struct Node_* next ;
} ;
typedef struct Node_ NODE ;
NODE *head = NULL ;
int main()
{
NODE* n1 ;
n1 = (NODE*) malloc(sizeof(NODE)) ;
n1->ix = 0 ;
n1->next = NULL ;
head = n1 ;
NODE* n2 ;
n2 = (NODE*) malloc(sizeof(NODE)) ;
n2->ix = 1 ;
n2->next = NULL ;
n1->next = n2 ;
NODE* n3 ;
n3 = (NODE*) malloc(sizeof(NODE)) ;
n3->ix = 2 ;
n3->next = NULL ;
n2->next = n3 ;
NODE* n4 ;
n4 = (NODE*) malloc(sizeof(NODE)) ;
n4->ix = 3 ;
n4->next = n2 ;
n3->next = n4 ;
unordered_map<NODE*,int> hashx ;
int idx ;
NODE* p = head ;
while(p != NULL)
{
hashx[p] += 1 ;
if(hashx[p] >= 2)
{
printf("node p (%d) recycle !!\n",p->ix);
break ;
}
p = p->next ;
}
printf("done \n") ;
} //main
is there something my code is missing out on
return; // no cycle detected
This line looks pretty bad, it should be changed to s.th. like
return NULL; // no cycle detected
To me your inner loop condition appears to be ambiguous. You are analysing if (p==q) where q is p-> next. this means that the node p previously considered didn't haD A CYCLE. So to me your inner loop wil never terminate.
you must consider this:-
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node * next;
Node(int x){
data = x;
next = NULL;
}
Node(int x, Node * y){
data = x;
next = y;
}
};
class linkedList{
Node *head;
public:
linkedList(){
head = NULL;
}
void addNode(int value){
Node *p;
if(head == NULL)
head = new Node (value, NULL);
else{
p = head;
while(p->next !=NULL)
p=p->next;
p->next = new Node (value, NULL);
}
}
void print(){
Node * p;
p = head;
while(p != NULL){
cout << p->data;
p = p->next;
}
}
int findCycle(){
Node *p, *start, *q;
p = head;
while(p != NULL){
q = p->next;
while (q != NULL ){
if(p->data == q->data)
return q->data;
else
q = q->next;
}
p = p->next;
}
return 0;
}
};
int main(){
linkedList l1;
l1.addNode(1);
l1.addNode(2);
l1.addNode(3);
l1.addNode(4);
l1.addNode(5);
l1.addNode(3);
int node = l1.findCycle();
cout<<node;
return 0;
}
What do you say people about this code.
void LinkListOps::createCycledListAndFindACycleNode()
{
// build a list with a cycle in it
ZNODE* head = new ZNODE(0);
ZNODE* current = head;
ZNODE* cycle = 0;
for (int i = 1; i < 8; i++)
{
current->_next = new ZNODE(i);
current = current->_next;
if (i == 6)
cycle = current;
if (i == 7)
current->_next = cycle;
}
// verify that there is a cycle
ZNODE* slow = head;
ZNODE* fast = head;
ZNODE* cycleNode = 0;
while (slow && fast && fast->_next)
{
slow = slow->_next;
fast = fast->_next->_next;
if (slow == fast)
{
cycleNode = slow;
break;
}
}
if (cycleNode == 0)
{
printf("No cycle\n");
return;
}
// finally find a cycle node which will be p2
ZNODE* p1 = head;
ZNODE* p2 = cycleNode;
while (1)
{
for (p2 = cycleNode; p2->_next != cycleNode; p2 = p2->_next)
{
if (p2 == p1)
break;
}
if (p2 == p1)
break;
p1 = p1->_next;
}
printf("%d\n", p2->_i);
}
You can quickly find out if there is a loop in a linked list by doing the following:
ptr = head;
current = nullptr;
if (!ptr) {
current = ptr->next;
while(current && current!=ptr) {
current = current->next;
if (current) {
current = current->next;
}
ptr = ptr->next;
}
}
At the end of this, if current is not null, then a loop was found, and current will be somewhere inside of it. This works by iterating current twice as fast through the list as ptr, and will always find a loop, if any exists, before ptr has looped once.
I have a fully functioning hashMap class and everything seems to be working very well EXCEPT a rehash function designed to create a hashmap when the load factor of the previous hashmap reaches 0.8.
void HashMap::reHash()
{
logins = 0;
numberOfPairs = 0;
Node** newBucket = new Node* [(2 * lengthOfMap) + 1];
for(int i = 0; i < lengthOfMap; i++)
{
Node* oldHead = bucketList[i];
for(Node* temp = oldHead; temp != nullptr; temp = temp-> next)
{
std::string key = oldHead->key;
std::string value = oldHead->value;
unsigned int index = hash(key) % lengthOfMap;
if(newBucket[index] == nullptr)
{
std::cout << "HIT" << std::endl;
newBucket[i] = new Node;
newBucket[i]->key = key;
newBucket[i]->value = value;
newBucket[i]->next = nullptr;
numberOfPairs[index]++;
logins++;
}
else if (bucketList[index] != nullptr)
{
Node* temp = bucketList[index];
while(temp->next != nullptr)
{
temp = temp->next;
}
Node* n = new Node;
n->key = key;
n->value = value;
temp->next = n;
n->next = nullptr;
std::cout << "FAIL at index: " << index << std::endl;
//numberOfPairs[index]++;
logins++;
}
}
}
for(int i = 0; i < lengthOfMap; ++i)
{
if( bucketList[i] )
{
Node* first = bucketList[i];
while( first )
{
Node* temp = first->next;
delete first;
first = temp;
}
}
}
delete bucketList;
bucketList = newBucket;
lengthOfMap = (2 * lengthOfMap) + 1;
}
bucketList[] is my previous array full of Node* which each begin the first link in a linked list. I have added a couple std::cout for my own benefit, and I seem to be stuck in a permanent loop reading FAIL at index:0 over and over again. I will admit I am new to the for loop iterating through the linked list, which I think is the source of my problem, but I'm looking for any helpful input.
Thanks again.