C linked lists - deleting element - c

if I have a linked list in C and I need to write a function that will delete one of it's elements in the the list (not the first or last one). The list is a global variable, so anywhere I use it it will be changed. If I do a while loop to get to the correct spot and then delete the element, wont the whole list change because I had to move the head to that point?
While doing head = head -> next in the while loop, the pointer is moving element by element and I have no way of going back to the first element once I have finished.
So how can I delete an element without erasing part of the list?

You shouldn't move the global head but rather make a new pointer that will work as a temporary head while iterating through the list.
Lets say the list looks like:
A -> B -> C -> D
If you want to delete C for example, you need to iterate to B (and see that it points to C). Then save it's pointer to C lets call it pC, move on to C and save it's pointer to D lets call it pD.
Then you can simply re-link the list by doing pC = pD so that B now links to D and skips C entirely. That way you remove an element from a linked list.
Your new list will be A -> B -> D.
Just remember to dump the variable before you lose the pointer to it.

Two options, off the top of my head :
Have the last element point to the first element. This way, no matter what node of your linked list you delete, you can always "go back".
Always keep a reference to your first element.
This being said, I don't think having a linked list as a global is a good idea ; is there no other way? Furthermore : is a linked list the right thing for what you're trying to achieve?

Related

Inserting an item to a linked list - is iteration necessary (C)?

I'm currently studying linked lists for interview prep, would appreciate if anybody could shed some light on this. The following function in C supposedly inserts a new element into the list after a certain Element elem (passed as an argument to the function):
bool insertAfter(Element * elem, int data){
Element * newElem, * curPos = head;
newElem->data = data;
while(curPos){
if(curPos == elem){
newElem->next = curPos->next;
curPos->next = newElem;
return true;
}
curPos = curPos->Next;
}
return false;
}
Although the above is specified in the textbook I am studying from, I tried coming up with a solution that does not use any iteration whatsoever:
bool insertAfter(Element * elem, int data){
Element * newElem;
newElem->next = elem->next
newElem->data = data
elem->next = newElem;
return true;
}
However, as it appears too simplistic, I sense that it may not work, but am not sure why. I need some insights on the technicalities on why this may or may not work, thanks.
Both versions suffer from the error of using newElem as though it were a valid pointer. It is not. It is not initialized to point to valid object.
You can correct that by allocating memory for an object before using:
Element * newElem = malloc(sizeof(*newElem));
The difference between the two versions is that if elem is not accessible from head for some reason or it is NULL, the first version will do nothing to the existing list. The second version does not deal with either of those scenarios. It assumes that elem is in the list and that it is not NULL.
Your solution is pretty much correct. The iteration in the example is almost completely useless.
What the example function is doing is: given an element to insert the new data after, it looks through the list starting with head to find that same element, then inserts the data - doing nothing with head or elem after finding it. Since all the loop does is "find" an element to which you already had a pointer, it essentially did nothing at all and is useless.
The only possible use of this is to constrain the insertion function to only work on this one list beginning with head, globally, throughout your program. This is such a strange design decision that one would likely assume it's a mistake unless given a reason to believe otherwise (dynamic data structures constrained to a single instance are an unusual pattern; more importantly, the whole point of linked lists is O(1) insertion, which the example function breaks by adding this useless loop). head is not needed for any other reason than to enforce this constraint, and if this is desired, it would make more sense to pass it in as a parameter as well so that the function is able to be used on more than one list per-program. (Or, not to perform the check at all: another use of linked lists is that you can pass around and insert after nodes without worrying about the head element.)
As other people have pointed out, you fail to actually allocate newElem, but so does the textbook. Overall, it's a rubbish example; not only did the author make a mistake with allocation, but they don't appear to understand the basic advantages of using linked lists. You should definitely treat this textbook with suspicion.
Your logic will work, because you just need a pointer to a node where you want to insert a node. If you already have such a pointer, no need to iterate and search for the node.
However the search (iteration) would be relevant if do not have in hand the node pointer where you want to insert the new node. Example: suppose the nodes have unique keys and you do not have the node pointer where the key exists and you want to insert after you find the node containing the specific key, then you need to find the correct node pointer and do the insertion (The function should then take in key as the argument).
However in your code (both cases), you have not allocated the memory for the new node. You need to do malloc for the new node and then go on with the insertion.
This will not work because you do not know your newElem. In linked list you have knowledge about a head and each element gives you information where to find the next one:
head -> e1 -> e2 -> ...
So you need to iterate till you will find the element you care about. But you can also iterate with the recursion.

Linked List insert in C

I have recently started working with linked lists. To push an element into linked list in the insert(...) function, I saw we always check if(head == NULL) but it occurs only once.
I want to know if there is any way so that we can avoid the unnecessary check always. Please suggest something that would be relevant to most of the linked list operations. One solution I figured out is that writing a new function "add_first_element(....)" so that explicitly we add the first element and then other elements are added in a generic way.
I am looking for a better solution.
A common way is to use a sentinel node. That is, a node that contains no useful data, but merely serves as the placeholder for the one before the first node. This way you don't need to check for null.
For double-linked list, you will need two sentinel nodes to avoid null checking.

Losing parts in Link List in C

I'm trying to make a link list and I'm having trouble with the concept with linking the middle part, I'm just doing a little pseudo-code right now, haven't actually coded anything.
(struct pointers) *current, *ahead, *behind, *begin;
(behind)-->(current)-->(ahead) //This is what I want to do
behind->next = current;
current->next = ahead;
Is this the proper way to break and connect the list? Without losing anything..
What you have looks correct but rather incomplete. One of the unwritten rules of programming is that you cannot write a linked list implementation correctly the first time. There are four cases you need to deal with:
Insert into an empty list
Insert into a non-empty list
Removing the first element from the list
Removing any other element from the list
There are also doubly-linked lists, where each element has a pointer to both the previous element and the next element. That makes it easier to handle things like removal of a random element without traversing the list, but can be trickier to get right.

Array to Linked List C

I am trying to convert an array to an linked list.
so basically, im gonna have a structure called "head" which will be the first element
and node, which will be the other elements.
any ideas so i can it started?
I don't see any solution simpler than just iterating through the array and appending the elements to the list.
The standard way to implement linked lists in C is with a single node structure containing a data member and a next pointer. Every time you want a new node, malloc space for it and set the next pointer of the last node in the list to point to it. The last node's next pointer should point to NULL.
You only have to hold onto a regular pointer to the first element. That's your head pointer.
Without using malloc you won't be able to easily add a new node to store data in so its best to just use the array to avoid the mess (but why can't you use malloc now?)

please can some one help me explain linked list?

I have tried a lot to learn linked list.But all my efforts were wasted.Please can some one help me understand linked list by providing his/her own code?Thanks in advance.
A linked list is simply a list of elements (usually called nodes) where each node has a reference (or pointers, in C) to the next node:
http://img837.imageshack.us/img837/5613/ll1s.png
You keep track of the list by having a pointer to the first node (the "head"), and by having the last node point to null
Linked lists where each element points to both the next and previous nodes are called doubly-linked lists.
By following these references, you can traverse the list and get any node.
A common advantage of linked lists over arrays is that you can insert and remove the elements in O(1) (constant) time. The disadvantage is that you have O(N) random-access.
See Wikipedia for more.
Have you play some of these rally games? The organizer left this hints all around the city and you must get one hint and then solve the riddle for getting the position of the next hint. Now, imagine every hint comes with a little prize.
Well, linked list are like that: every element has "content" on it AND the memory address (the hint) for getting the next item. The next item, of course, has another prize and another hint.
A linked list is a series of object each pointing to the next one in the list. The last element in the list has NULL as it's next pointer.
You keep track of the head of the list in your program so you can traverse the list from the start.
You might want to keep track of the current position in the list, but that will depend on your application.
A doubly linked list has a previous element pointer too enabling you to traverse the list in both directions.
This:
typedef struct tagProp
{
rtPropertyKey key;
rtProperty property;
struct tagProp *next;
} TProperty;
defines a property key/value lookup list.
A linked list is implemented as a list of "nodes". The nodes are linked together using pointers. The following code describes one node. The pointer to the next node is called next. In my example, each node contains an integer value as its data.
struct node {
int val;
struct node * next;
};
The fun is how to actually create a list. You have to use malloc to create new nodes. When you malloc the new node, you have to tie into the list using the next pointer.
We can help you more if you specifically tell us what your issues are...

Resources