I am creating a student list (linked list) that can add, view and edit student information. I have two fields namely Student Name and Student Grade and I add new students in the list in a way that it is sorted according to the student's grades in descending order.
I have finished doing the add and view portion. The problem is on the edit part because I need to edit the information, then I need to sort it again so that it would be on the proper location of the list.
For example, I have 3 students information arranged according to their grades:
student1 90 -> student2 85 -> student3 80 -> NULL
Then I need to edit student2's grade to 75 so the edited linked list should now be arranged as follows:
student1 90 -> student3 80 -> student2 75 -> NULL
How should I do that? You don't need to give me any code. I just want some advices on how I can implement the edit part of my program. I am thinking of creating a new node (with the edited info), delete the old node and insert the edited node into the list. Is my logic correct? or is there a better way on solving my problem.
You can accomplish your goal by
Removing target node
Editing target node data
Reinsert the node using your existing logic for inserting nodes.
Singly linked list?
Find the node you want to edit, and either keep a pointer to the previous node or write a routine to retrieve the previous node.
Remove your node from the linked list (by setting previous_node->next to thisOne->next)
Make your edits.
Insert the new node in the right place in the list (by traversing the list unti the next node is less than your edited value.
Splice edited into the list ( editedNode->next = nextNode; current->next = editedNode)
With doubly linked lists you can just use the "other"/back/up link to find the previous node
Basically your idea is correct except that I wouldn't create a new node. What I would do would be:
Identify if value has increased or decreased (and update node).
Unlink node from the list.
Search forwards or backwards (depending on increase or decrease of grade) for correct location.
Link node into new location.
Note that indexing the list into an array, etc. may give a quicker search than a linear traversal. If you already have such a mechanism it may be quicker to use that when finding the location to re-insert the node.
You could do a function that edits a specified node. Scan the list until you find that node and then directly edit it. Of course you will use a pointer. For the sorting part, say you have n nodes, compare every node i with the nodes after it and swap them if the one you are comparing with is larger:
for every node n1 in list
for every remaining node n2 in list
if n2->grade > n1->grade
swap 'em
you can swap them copying their memory, so you won't need to change any pointer.
Related
Can anyone help me with finding an algorithm to change a position of a node in a linked list according to the input?
Example:
I have the linked list: 1->2->3->4->END and the user chose the second node and the index 4.
The algorithm will give us the result:
1->3->4->2->END.
Thanks for your help!
It is really easy to move nodes in a linked list because they are done for that...
To change a node's position, just change it's next pointer to the next node address, and the previous node's next pointer to the node you want to move and that's done.
May I know if there is anything like the easiest node to be removed or deleted from a LinkedList.
I know that deleting a node from in between requires a change of the preceding nodes link, whereas deleting from beginning needs a change of pointer to the new head and deleting from the end needs a change of new end of the list.
But, if asked to delete a node from the LinkedList which is easier which of these should be preferred?
Sounds like you are on the right track with your thoughts on linked lists. Another thing to consider about removing the easiest node from a linked list is the following:
How often will these easiest nodes be removed? If the node is removed from the head of the list the removal will be complete in O(1) time, but if the easiest nodes are at the rear of the list removal will take a full traversal of the list completing in O(n) time.
I got a linked list with only one node. How do you remove that only node?
You can't "skip" it by pointing the *next struct of the previous struct to the next structure because there are no next structures, nor previous structures.
I've tried using free() but it didn't work either.
So the question is:
How do you remove the only node from a linked list? I've googled it, but no helpful links were found, unfortunately. Thank you for the help.
Because there are multiple ways in which linked lists are used, there's no single pattern which is best for every application. Nonetheless, a pattern which is very frequently helpful is to have one or two "special" and/or "pre-allocated" nodes which are used for the start and/or end of a linked list (sometimes it's helpful for doubly-linked lists to start and end with the same node; sometimes it's useful to have distinct "start" and "end" nodes). In a singly-linked list with one extra "start" node, the main reference to the list will typically identify the start node which will exist as long as the list does; that reference will never need to change. The fact that every "real" item in the list--even the very first one--will always have a node preceding it avoids the need to worry about special code to delete the first item or insert an item before it, since the first real item of the list may be treated just like any other.
Incidentally, when working with singly-linked lists, it is often a good idea to have each node contain a "deleted" flag. Generally in the process of finding a node, one will find the previous node as well; since deleting a node requires knowing which node preceded it, keeping track of the node which preceded a the most-recently-found node will often allow one to delete it without having to search for its predecessor. If, however, one finds multiple nodes and then performs actions upon them, it's possible that by the time one goes to perform an action on a node (e.g. deleting it), the node which used to precede it might no longer do so. Having a "deleted" flag in each node may make it easier to detect such conditions and handle them smoothly (if wants to delete a node and can't immediately identify the previous node, it may be best to simply set the "deleted" flag; if the invalidated node is later encountered by code which knows which node precedes it, that code can take care of actually removing the invalidated node from the list.
Assuming you have
struct foo * head;
somewhere which actually does point at your node, you should be able to
free(head);
If you can't, then you should post your code so that we can look at what you're actually doing wrong.
If you have the lasting node, then the head is that node. So, after you free(head) , make sure to declare head = NULL . This a good practice as long as I understand.
And, let's say you have a function to delete nodes. At the beginning, don't forget to code
if (*head == NULL)
return ("your error code");
This way, the programm won't try to free something that hasn't been allocated and get you a segmentation fault.
given a singly linked list, how to determine head node from a specified node (for e.g say node 4).total # of nodes: 10.Thanks. Logic will do,code is appreciated.
We know given a head node one can perform a forward traverse and determine next node easily.
For this case, use of doubly linked list would be simpler but i was wondering if it is possible to track down head node using singly linked list.Thanks.
Its not possible at all to do that with the kind of singly linked list you've described.
Your question isn't entirely clear. But the only way this is possible is if each of your candidates is the head of a unique list, and one of them is the head that you're after.
For each candidate, traverse the list that starts from it. You will eventually hit the corresponding tail, or you will hit the node in question.
You can also make this work even if your set of candidates are not all heads of unique lists. But you would need logic to detect overlap.
You simply cannot in the singly linked list.
From Wikipedia :
Singly linked lists contain nodes which have a data field as well as a
'next' field, which points to the next node in line of nodes.
You cannot go back to the previous node as you don't have any information about it. If you were given any random node of a singly linked list, the head of your new list will be that node, as you cannot go back any further.
I have a problem about Linked Lists. I already know how to create structures and linked list. But now I have to create arbitrary number of linked list which are also be kept in another structure. Which means :
struct list{int x, struct list *next; };
struct parent{int x, struct list *head, struct parent *next;}
And after lists are created when i enter this input for example "123134" linked list should look like :
1 -> 2 -> 3 -> 4
And for example 1 will contain 2->3 list inside of it, 3 will contain 1->4 list inside of it.
I need a starting point and a spark from you. So how can i do this?
Draw your list diagram, which often helps.
Start
|
list1 -> node1 -> node2
|
list2 -> node_a -> node_b -> node_c
|
list3 {empty}
|
list4 -> node_1A
Given a diagram like the above, the lists have two links, one to their own nodes, another to another list. Some objects may need more than one link field.
In your case, draw a diagram. Try inserting a new item. Write down the steps you take (and draw).
If you supply more details in your question, more people will assist.
For an example of a list with nodes containing many lists, see a BTree data structure. Each node contains an array of links to other "subtrees".