I am trying to work on pointers.
I am under a situation that i want to traverse the linked list after the second node(from third node).
I have the basic idea to traversing the linked list is:
while(temp!=NULL)
{
temp=temp->next;
}
So what i want is this linked list must start from third position. Could anyone please help me in preparing logic for that? I am not interested in any using any in-built functions.
I will use this logic in other application.
If your list is temp then temp is also the first element.
Then temp->next will be second element, and temp->next->next will be the third.
So if you write
temp = temp->next->next;
temp will be pointing to the third element and you can start your traverse from there.
Node *nth(Node *head, int nth){//nth : 0 origin
while(nth && head){
--nth;
head = head->next;
}
return head;
}
...
Node *third = nth(head, 2);
Related
I have a question regarding linked lists and hash tables in C.
Is the so called head of the linked list supposed to be just a pointer to the first node or can the head be the first node?
void insert(int item)
{
//Making space for a new node
node *link = malloc(sizeof(node));
//Checking if valid
if (link == NULL)
{
return;
}
//Assigning the value of the node
link->value = item;
//Assigning the next to be the first element
link->next = first;
//Assigning first to be the current node
first = link;
}
Above code is from my insertion function of linked list. The "first" is assigned as node *first = NULL;
So the question here is that should I make a dedicated pointer that only holds the address of the first node or is this just fine. The code seems to work just fine.
And the same question sort of holds with hash tables. Should the array in hash table hold only the pointer to the first node or should the tables index slot hold the first node.
I hope my question is understandable. Feel free to ask if something doesn't make sense or need more of the linked list implementation I did.
Thanks in advance!
Hello guys could you please help me in writing a procedure to reverse the pointers in a linked list . for example A->B->C->D would become A<-B<-C<-D without using extra linked list .
Edit:
------ okay guys so i have been looking for solution for this problem here is the code in case u want it :
void reverse_list(){
struct node *next, *current,*previous;
previous = NULL;
current =head;
while(current != NULL){
next = current->next;
current->next = previous;
previous=current;
current = next;
}
head = previous;
}
You could think of the list as a stack. Then you could easily reverse such a list by "popping" the nodes and "pushing" them into a new list.
The above could be done both destructively (destroying the old list) and non-destructively (creating the new list as a reversed copy of the original list).
As you didn't mention if you are implementing the linked list yourself or not.
So firstly I am assuming that you are doing it by yourself. So following is an implementation of linked list and again its pointers are reversed to make the link list reverse. You can take an idea from it.
#include<stdio.h>
#include<stdlib.h>//for using malloc
struct Node//Defining a structure for linked list's node
{
int info;//assuming it is an integer linked list
struct Node *link;//this pointer links a node to it's immediate neighbor node
};
struct Node *head=NULL,*temp;//some initializations and declarations
void insertion(int data)//To insert elements to linked list
{
struct Node *ptr;
ptr=malloc(sizeof(*ptr));//creating a new node for the newcomer
ptr->info=data;//taking the given integer value for the node to hold
//initializing with null as the current node may be the last node and
//if it is then it will point nobody
//...but if it is not when a new node comes in the future it will eventually be
//replaced to point the newcomer
ptr->link=NULL;
if(head==NULL)//head still null means we are creating the first node
{ //handling the head separately as it has no parent node
head=ptr;
temp=ptr;//copying the current node's pointer to temp such that we can
//find it as a parent of next node
}
else//for the rest of the nodes' creation
{
//as temp is the pointer to the previous node, so previous node is linking
//to its next node, i.e, the current node
temp->link=ptr;
//updating the temp to point the current node such that it can act as a parent node
//when the next node comes
temp=ptr;
}
}
void reversePointers()
{
struct Node *trav,*from=NULL,*temp;
for(trav=head;;)
{
if(trav->link==NULL)//if we have reached to the end
{
head=trav;//then the reverse linked list's head should point to the last element
trav->link=from;//and making the second last node as it's next node
break;
}
temp=trav;//saving current node pointer to update the "from" pointer
trav=trav->link;//advancing current node pointer to forward
temp->link=from;//making the current node to point to it's previous node
from=temp;//saving current node's pointer which will be used in next iteration
}
}
void traverse()//to traverse the nodes
{
struct Node *ptr=head;
while(ptr!=NULL)
{
printf("%d ",ptr->info);
ptr=ptr->link;
}
printf("\n");
}
int main(void)
{
int i,n,t;
printf("Enter Number of elements: ");
scanf("%d",&n);
printf("Enter Elements: ");
for(i=0;i<n;i++)
{
scanf("%d",&t);
insertion(t);
}
printf("Before reversing the pointers the elements are: ");
traverse();
//let's reverse the pointers to make the list to go backward
reversePointers();
printf("After reversing the pointers the elements are: ");
traverse();
}
Secondly if you are using STL list then the approach is quite straightforward. Just use,
your_list_name.reverse()
Again if you want to reverse the STL list just for iteration purpose then there is no need to actually reverse it. Instead you can use reverse iterator as following (say for an integer list):
for(list<int>::reverse_iterator it=your_list_name.rbegin();it!=your_list_name.rend();it++)
{
//do whatever you want
}
I came up with this way of creating a linked list in C:
void queue(Node ** head, Node * object)
{
Node * tmp = (Node *)malloc(sizeof(Node));
*tmp = *object;
Node *last = get_Last((*head));
if (last) {
last->next = tmp;
tmp->next = NULL;
}
else {
(*head) = tmp;
tmp->next = NULL;
}
}
The idea is rather simple, pass a pointer to an object to queue(...) then traverse the list to find the last node and then edit a few pointers. However what I don't exactly like is the get_Last(...) function:
Node * get_Last(Node * head)
{
if (!head) {
return NULL;
}
while (head->next) {
head = head->next;
}
return head;
}
This function means that should queue(...) ever find itself in a loop then the algorithm I came up with has O(n²) time complexity which is just too much for something as simple as creating a linked list. What can be done to bring down the complexity to O(n)? I guess queue(...) still needs the address of the last node, but how do I obtain it without a loop?
Are you sure that items need to be inserted at the end of the list? Inserting/removing at the front of a linked list is O(1) for free.
If you do in fact want an efficient FIFO list, the best way to do this by far is to keep the address of the tail element. It requires only constant memory and allows O(1) inserts to the tail.
The most clear way to accomplish this would likely be to make a Queue struct that keeps a pointer to the head and tail, with utility functions accepting a pointer to Queue for enqueue and dequeue operations.
I have a singly linked list which has 100 node. I need to check this linked list circular or not?
It can be achieved by traversing list and need to check last node link field equal to head.
struct node *temp1, *temp2;
while(i != 100) {
temp2 = temp1->link;
if(temp2==head) {
printf("circular");
break;
else
temp1=temp1->link;
i++;
}
This method will take maximum of 100 iteration. I want to reduce this to half, i mean by 50 iteration i need to achieve this.
Is it possible to do this? If yes, how we can do this?
So you can do it in 50 iterations with a little hack. Keep another head(*head2) which points to head->link. This will still take constant space. Compare it with the current node in the if condition along with the original head. See the code below--
struct node *head, *head2, *temp;
temp = head; //assuming head points to start of the list
head2 = head->link;
while(i != 50) {
temp = temp->link->link;
if(temp==head || temp==head2) {
printf("circular");
break;
}
i++;
}
to check for circular linked list, just loop the linked list and for every iteration check the following:
if the head == temp->next than True, it does, than it's CircularLinkedList
else if temp->next == null than False
Using single linklist you have to traverse the whole linklist. This also applies for circular linklist. Else why would people make such ADT?
You can use double linklist to check the linklist circular or not. And you can check it in constant time.
The Tortoise and Hare algorithm will work for your purposes.
On each iteration the hare will move through two nodes and the tortoise just one. The hare will visit each node and some of them multiple times, but if you add the hare's total number of node visits and divide by two, the result will not be greater than the length of the list. It is possible that the tortoise will visit each node as well, but it will not visit the same node twice.
The algorithm is O(n)
Links:
http://codingfreak.blogspot.com/2012/09/detecting-loop-in-singly-linked-list_22.html
I have a linked list that is coming out backwards. I appear to be adding elements to the back of the list, when I want to place them on the front.
My nodes appear as follows:
struct node{
int data;
struct node* next;};
Next I set the head and variables
int info,x,listLength;
struct node *head = NULL;
struct node *temp;
printf("How many nodes?\n");
scanf("%d",&listLength);
Now I prompt for a new entry in the list, and move along the nodes
for(x=1;x<=listLength;x++){
printf("Insert an X value for node %d\n",x);
scanf("%d",&info);
temp = (struct node*)malloc(sizeof(struct node));
temp->data = info;
temp->next = head;
head = temp;
}
Finally I output the results and free the memory space
while(temp!=NULL){
printf("WE GOT %d\n",temp->data);
temp = temp->next;
}
free(temp);
However, if I enter input for three nodes and enter 1,2 and then 3, the output is 3,2, then 1! How can I change this to make sure the nodes are being added to the right place?
Thanks in advance!
Your code is saying
temp->next = head;
head = temp;
So you are adding to the start of the list, not the end, so "reverse order" is correct.
To add to the end you either need to keep track of the last node you added (e.g. struct node tail), or you need to search from head through the next ptrs until next = null to find where to add the new node.
Also: why the free(temp) at the end? Since it is after while(temp != NULL) it means temp must equal null. Are you trying to free the whole list or what?
Your head pointer points to the last object, thats why you get the numbers 'backwards'.
input: 1, 2, 3
head[data: 3] (last thing temp pointed to) -> next[data: 2] -> next[data: 1] -> NULL
it is working correctly..you want to put new node in front of the list, right? after 1, you are adding so. so now the list will be: 2->1, and in the same way, 3->2->1