Method for deleting and adding elements during C collection traversal

  • 2021-10-24 23:34:49
  • OfStack

This article illustrates the method of deleting and adding elements during C # collection traversal. Share it for your reference, as follows:

Most of the time, it is not necessary to add or delete elements when traversing collection elements, but sometimes it is necessary. For example, if the elements in the collection are all people in the society, the elements will be deleted if someone dies, and the elements of the collection will be added if someone is born. In this case, traversal can't be done in the original way, and the collection in C # doesn't support foreach loop for such traversal with addition and deletion actions.

There are three ways to solve this problem.

Method 1: LinkedList using C # < > Double linked list. I originally imagined that, The elements that need to be deleted in the original linked list are directly remove, Those newly added elements are first loaded into a temporary linked list, and then the head node of the temporary linked list is added to the tail of the original linked list with Add, which makes the algorithm less complicated. However, unexpectedly, the double linked list of C # cannot add nodes belonging to another linked list to this linked list, and its Next attribute is also read-only. Helpless, only 1 side of the loop, 1 side in the end of the original linked list to add nodes, so the need to mark the end of the loop position, that is, the need to end the loop at the end of the original unchanged linked list, not at the end of the changed linked list. This requires that the reference of the tail node be obtained before the loop starts. The procedure is as follows (there are 0-29 integer value nodes in the linked list, if the iteration time encounters an integer multiple of 3, add 1 0 value node at the end of the linked list, and delete the node if it encounters an integer multiple of 2)


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace  Delete or add elements during collection traversal 
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
    private LinkedList<int> list = new LinkedList<int>();
    // Initialize, add 0-29 Enter the linked list into the integer of 
    private void button1_Click(object sender, EventArgs e)
    {
      for (int i = 0; i < 30; i++)
      {
        this.list.AddLast(i);
      }
    }
    // Traverse the linked list and do the following: 
    // Encounter can be 3 Divided, it is added after the linked list 1 A 0 Element, encountered can be 2 The element is deleted if it is divisible 
    private void button2_Click(object sender, EventArgs e)
    {
      LinkedListNode<int> nodeNow = this.list.First;// Linked list number 1 Elements 
      LinkedListNode<int> nodeLast = this.list.Last;// At the end of the original linked list 1 Elements, the tag for the end of the loop 
      LinkedListNode<int> nodeTmp;// Temporary node 
      // The condition that the loop ends is that the current node is the last of the original linked list 1 Node 
      while (nodeNow != nodeLast)
      {
        // If it can be 3 When divisible, add after the linked list 1 A 0
        if (nodeNow.Value % 3 == 0)
        {
          this.list.AddLast(0);
        }
        // If it can be 2 Divide exactly, the element is deleted 
        if (nodeNow.Value % 2 == 0)
        {
          // If nodeNow Has been deleted, so 1 It must not be used Next Get the following 1 Elements to judge 
          // Because it has automatically gone down 1 A move, this is about to be deleted nodeNow Before, 
          // Gets its Next , assign to nodeTmp , wait nodeNow After deleting, put nodeTmp Memory assigned to nodeNow
          nodeTmp = nodeNow.Next;
          this.list.Remove(nodeNow);
          nodeNow = nodeTmp;
        }
        else
        {
          // If you can't be 2 Divide, the element is retained in the linked list and the following is obtained 1 And make a judgment 
          nodeNow = nodeNow.Next;
        }
      }
      // Finally, don't forget to be right nodeLast (At the end of the original linked list 1 Elements) itself, the above while The loop does not include this nodeLast
      if (nodeNow.Value % 3 == 0)
      {
        this.list.AddLast(0);
      }
      if (nodeNow.Value % 2 == 0)
      {
        this.list.Remove(nodeNow);
      }
    }
    // Test results 
    private void button3_Click(object sender, EventArgs e)
    {
      foreach (int i in this.list)
      {
        Console.WriteLine(i);
      }
    }
  }
}


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace  Delete or add elements during collection traversal 
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
    private LinkedList<int> list = new LinkedList<int>();
    // Initialize, add 0-29 Enter the linked list into the integer of 
    private void button1_Click(object sender, EventArgs e)
    {
      for (int i = 0; i < 30; i++)
      {
        this.list.AddLast(i);
      }
    }
    // Traverse the linked list and do the following: 
    // Encounter can be 3 Divided, it is added after the linked list 1 A 0 Element, encountered can be 2 The element is deleted if it is divisible 
    private void button2_Click(object sender, EventArgs e)
    {
      LinkedListNode<int> nodeNow = this.list.First;// Linked list number 1 Elements 
      LinkedListNode<int> nodeLast = this.list.Last;// At the end of the original linked list 1 Elements, the tag for the end of the loop 
      LinkedListNode<int> nodeTmp;// Temporary node 
      // The condition that the loop ends is that the current node is the last of the original linked list 1 Node 
      while (nodeNow != nodeLast)
      {
        // If it can be 3 When divisible, add after the linked list 1 A 0
        if (nodeNow.Value % 3 == 0)
        {
          this.list.AddLast(0);
        }
        // If it can be 2 Divide exactly, the element is deleted 
        if (nodeNow.Value % 2 == 0)
        {
          // If nodeNow Has been deleted, so 1 It must not be used Next Get the following 1 Elements to judge 
          // Because it has automatically gone down 1 A move, this is about to be deleted nodeNow Before, 
          // Gets its Next , assign to nodeTmp , wait nodeNow After deleting, put nodeTmp Memory assigned to nodeNow
          nodeTmp = nodeNow.Next;
          this.list.Remove(nodeNow);
          nodeNow = nodeTmp;
        }
        else
        {
          // If you can't be 2 Divide, the element is retained in the linked list and the following is obtained 1 And make a judgment 
          nodeNow = nodeNow.Next;
        }
      }
      // Finally, don't forget to be right nodeLast (At the end of the original linked list 1 Elements) itself, the above while The loop does not include this nodeLast
      if (nodeNow.Value % 3 == 0)
      {
        this.list.AddLast(0);
      }
      if (nodeNow.Value % 2 == 0)
      {
        this.list.Remove(nodeNow);
      }
    }
    // Test results 
    private void button3_Click(object sender, EventArgs e)
    {
      foreach (int i in this.list)
      {
        Console.WriteLine(i);
      }
    }
  }
}

Method 2: List using C # < > , List < > It is a sequence table based on array, which has high time complexity in adding and deleting actions, and is not as efficient as linked list. It is basically similar to the first method, and it also needs to use an int variable to mark the tail element of the original sequence table. When deleting an element, this variable needs to subtract itself. The code is omitted.

The third method is to customize the generic class of single linked list (see https://www. ofstack. com/article/87610. htm for linked list class). Compared with the first method, the advantage is that the merging of two linked lists can be realized flexibly, and only the head node of the second linked list needs to be set as the node of Next of the tail node of the first linked list (or Add directly). In fact, I am not very clear about the double linked list of C #. Why AddLast () method can't add the elements of one linked list to another linked list, but can only add one node that doesn't belong to any linked list (some people say that the first method can actually use node Clone, but it only increases the space and time complexity of the algorithm, which goes against the original intention of using linked list). The reason why C # does not support this practice may be that MS is worried that the node you join is located on a circular linked list, which will cause the Last attributes and Count attributes of the original linked list to be unable to be calculated (forming an infinite loop). The test code is as follows:


// Merging of two linked lists 
LinkedList<int> list = new LinkedList<int>();
for (int i = 0; i < 10; i++)
{
   list.Add(i);
}
LinkedList<int> list2 = new LinkedList<int>();
for (int i = 10; i < 20; i++)
{
   list2.Add(i);
}
list.Add(list2.Head);
Node<int> n = list.Head;
while(n!=null)
{
   Console.WriteLine(n.Data);
   n = n.Next;
}
Console.ReadLine();
Console.WriteLine(list.GetLength());
Console.ReadLine();
// Merging of two linked lists 
LinkedList<int> list = new LinkedList<int>();
for (int i = 0; i < 10; i++)
{
 list.Add(i);
}
LinkedList<int> list2 = new LinkedList<int>();
for (int i = 10; i < 20; i++)
{
 list2.Add(i);
}
list.Add(list2.Head);
Node<int> n = list.Head;
while(n!=null)
{
 Console.WriteLine(n.Data);
 n = n.Next;
}
Console.ReadLine();
Console.WriteLine(list.GetLength());
Console.ReadLine();

More readers interested in C # can check the topic of this site: "C # Traversal Algorithm and Skills Summary", "C # Programming Thread Use Skills Summary", "C # Operating Excel Skills Summary", "C # Common Control Usage Tutorial", "WinForm Control Usage Summary", "C # Data Structure and Algorithm Tutorial", "C # Array Operation Skills Summary" and "C # Object-Oriented Programming Introduction Tutorial"

I hope this article is helpful to everyone's C # programming.


Related articles: