Reputation: 3475
as far as I can see, you can do:
If your list is a double linked.
But how do you do it with a single linked list? I have tried a lot of things, with no avail :( I simply get it to remove a specific index instead or it does nothing at all
Upvotes: 4
Views: 31977
Reputation: 4545
If you have "good taste" you could probably appreciate this solution that relies on ref
locals to mimic pointer magic.
public void Remove(T value) {
ref var indirect = ref _head;
while (indirect != null) {
if (EqualityComparer<T>.Default.Equals(indirect.Value, value)) {
indirect = indirect.Next;
return;
}
indirect = ref indirect.Next;
}
}
Upvotes: 0
Reputation: 14177
To Remove a particular Node from a Single LinkedList based on the index value of the List item. Below is the code
public void DeleteNode(int nodeIndex)
{
int indexCounter = 0;
Node TempNode = StartNode;
Node PreviousNode = null;
while (TempNode.AddressHolder != null)
{
if (indexCounter == nodeIndex)
{
PreviousNode.AddressHolder = TempNode.AddressHolder;
break;
}
indexCounter++;
PreviousNode = TempNode;
TempNode = TempNode.AddressHolder;
}
}
Complete Code can be found on http://fumycoder.com/2017/09/06/linked-list/
Upvotes: 0
Reputation: 446
Here is a working solution for deleting a node from LinkedList in C#.
If First Node, i.e. previous node is null, point Head to Next Node.
class LinkedList
{
private Node Head { get; set; } = null;
public void Insert(int d)
{
Console.WriteLine("Insert : " + d);
var newNode = new Node() { Data = d, Next = null };
if (Head == null)
{
Head = newNode;
}
else
{
newNode.Next = Head;
Head = newNode;
}
}
public void Delete(int d)
{
Console.WriteLine("Delete : "+d);
var node = Head;
Node currNode = Head;
Node prevNode = null;
while (node != null)
{
currNode = node;
if (node.Data == d)
{
if(prevNode != null)
{
prevNode.Next = currNode.Next;
}
else
{
Head = Head.Next;
}
break;
}
prevNode = currNode;
node = node.Next;
}
}
public void Print()
{
var list = Head;
Console.Write("Elements: ");
while (list != null)
{
Console.Write(list.Data + " ");
list = list.Next;
}
Console.WriteLine();
}
}
Upvotes: 0
Reputation: 21
You may find the comprehensive implementation of Singly Linked List with all the functions such Add, Remove, InsertAt etc., here. http://tech.bragboy.com/2010/01/linked-lists.html Note: This has a working Java code + Test classes so that you would not miss out on anything that a singly linked list is made of,
Upvotes: 2
Reputation: 1
static void Main(string[] args)
{
LinkedList<string> ll = new LinkedList<string>();
ll.AddLast("uno");
ll.AddLast("dos");
ll.AddLast("tres");
ll.Remove(ll.Find("uno")); // Remove
foreach (string item in sl)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
Upvotes: 0
Reputation: 1
struct node_t {
int data;
struct node_t *next;
}
void delete_node( struct node_t *random) {
struct node_t *temp;
/* Save the ptr to the next node */
temp = random->next;
/* Copy stuff from the next node to this node */
random->data = random->next->data;
random->next = random->next->next;
/* Delete the next node */
free (temp);
return;
}
This should work on most Operating Systems in my opinion.
Upvotes: 0
Reputation: 282895
Almost ironic you should just ask this. I'm trying to brush up on my singly linked lists too. I just wrote this function in C++ that seems to work:
void pop_back() {
if(head == NULL) {
return;
}
if(head->next == NULL) {
delete head;
head = NULL;
return;
}
Node *iter = head;
while(iter->next->next != NULL) {
iter = iter->next;
}
delete iter->next;
iter->next = NULL;
}
For popping the last element, but you can modify it slightly to work in the middle, I'm sure. Idea is pretty much the same in C#.
Upvotes: 0
Reputation: 241641
Start at the beginning of the list. Maintain a reference to the current item (currentItem
) and the previous item (previousItem
). Linearly search for the item that you want to remove always walking with previousItem = currentItem, currentItem = currentItem.Next
. If the item that you want to remove is the head of the list, reassign the head of the list to currentItem.Next
. Otherwise, set previousItem.Next = currentItem.Next
. If necessary (as you say, in a non-GC environment) dispose of currentItem
.
Basically you are using previousItem
to mimic the behavior of a currentItem.Previous
in the case of a doubly-linked list.
Edit: This is a correct implementation of Delete
:
public void Delete(int rangeStart, int rangeEnd) {
Node previousNode = null, currentNode = Head;
while (currentNode != null) {
if (currentNode.Data >= rangeStart && currentNode.Data <= rangeEnd) {
if (previousNode == null) {
Initial = currentNode.Next;
}
else {
previousNode.Next = currentNode.Next;
}
}
else {
previousNode = currentNode;
}
currentNode = currentNode.Next;
}
}
Upvotes: 11
Reputation: 28424
In THEORY, you could do this to remove any random node from a single link list:
void RemoveNode(Node toRemove)
{
toRemove.PointerToSomeValue = toRemove.NextNode.PointerToSomeValue ;
toRemove.NextNode = toRemove.NextNode.NextNode ;
}
But, you need to be carefull about concurency issues. (ie. somebody else has a link to your node assuming it still caries the old value (an ABA problem) ), and you need to have a "marker" (empty) node at the end of the list, which you must never attempt to delete.(because of the toRemove.next.next)
Edit: obviously PointerToSomeValue is whatever data you want to keep in your list. And you're not actually deleting the node, you're basically removing the next node in the list, oh,well.. you get the ideea
Upvotes: -1
Reputation: 19790
keep remebering the last node you been too.
//PSEUDO CODE
Node prevnode = null;
foreach (node n in nodes)
{
if (n.name.equals(name))
{
if (prevnode != null)
{
prevnode.next = n.next;
}
remove n;
break;
}
prevnode = n;
}
Upvotes: 1
Reputation: 19627
This is the primary weakness of the singly-linked list. You'll either need to have a reference to the previous node, or scan through the list from the beginning.
Upvotes: 1
Reputation: 1062915
Well, you could just use LinkedList<T>
and Remove
; but manually:
prev.next = node.next
Upvotes: 3
Reputation: 75985
The following code uses recursion to keep track of previous node: Source: http://www.cs.bu.edu/teaching/c/linked-list/delete/
nodeT *ListDelete(nodeT *currP, elementT value)
{
/* See if we are at end of list. */
if (currP == NULL)
return NULL;
/*
* Check to see if current node is one
* to be deleted.
*/
if (currP->element == value) {
nodeT *tempNextP;
/* Save the next pointer in the node. */
tempNextP = currP->next;
/* Deallocate the node. */
free(currP);
/*
* Return the NEW pointer to where we
* were called from. I.e., the pointer
* the previous call will use to "skip
* over" the removed node.
*/
return tempNextP;
}
/*
* Check the rest of the list, fixing the next
* pointer in case the next node is the one
* removed.
*/
currP->next = ListDelete(currP->next, value);
/*
* Return the pointer to where we were called
* from. Since we did not remove this node it
* will be the same.
*/
return currP;
}
Upvotes: 2
Reputation: 3197
You keep track of the last node while you try to find the "current node".
Then you can wire up the previouse.next to current.next and you are done
Upvotes: 5