C#集合遍曆時刪除和增加元素的方法_C#教程

來源:互聯網
上載者:User

本文執行個體講述了C#集合遍曆時刪除和增加元素的方法。分享給大家供大家參考,具體如下:

大多數時候,遍曆集合元素的時候並不需要對元素進行增加或者刪除操作,但有些時候則需要,比如,如果集合中盛放的元素是社會上所有的人,那麼有人死亡則元素刪除,有人出生則是集合元素的增加。對於這種情況,遍曆不能按照原來那種方式去做了,而且C#中的集合對於這類有增刪動作的遍曆,也不支援foreach迴圈。

有三種辦法可以解決這一問題。

第一種方法:使用C#的LinkedList<>雙鏈表。我原來設想,把原來鏈表需要刪除的元素直接remove掉,那些新添加的元素,先裝入到一個臨時鏈表中,等迴圈結束,再用Add把臨時鏈表的頭結點添加到原來鏈表的尾部即可,這樣演算法的複雜度也較低,但是,出乎意料的是,C#的雙鏈表,無法將屬於另外一個鏈表的結點添加到本鏈表中,其Next屬性也唯讀。無奈,只能一邊迴圈,一邊在原鏈表尾端添加結點,這樣就需要標記處迴圈結束的位置,即需要在原來的未改動的鏈表的尾部結點處結束迴圈,而不是在改動後的鏈表的尾部結點處結束。這樣就要求在迴圈開始之前,先獲得尾部結點的引用。程式如下(鏈表中有0-29的整數值結點,遍曆時遇到3的整數倍,就在鏈表尾端添加一個0值結點,遇到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 集合遍曆時刪除或增加元素{  public partial class Form1 : Form  {    public Form1()    {      InitializeComponent();    }    private LinkedList<int> list = new LinkedList<int>();    //初始化,添加0-29的整數進入鏈表    private void button1_Click(object sender, EventArgs e)    {      for (int i = 0; i < 30; i++)      {        this.list.AddLast(i);      }    }    //遍曆鏈表,做如下操作:    //遇到能被3整除的,就在該鏈表後增加一個0元素,遇到能被2整除的就刪除該元素    private void button2_Click(object sender, EventArgs e)    {      LinkedListNode<int> nodeNow = this.list.First;//鏈表第一個元素      LinkedListNode<int> nodeLast = this.list.Last;//原鏈表的最後一個元素,迴圈結束的標記      LinkedListNode<int> nodeTmp;//臨時結點      //迴圈結束的條件是,等當前結點是原鏈表的最後一個結點      while (nodeNow != nodeLast)      {        //如果能被3整除時,則在鏈表後加一個0        if (nodeNow.Value % 3 == 0)        {          this.list.AddLast(0);        }        //如果能被2整除,則刪除該元素        if (nodeNow.Value % 2 == 0)        {          //如果nodeNow被刪除了,那麼一定不能用Next擷取下一個要判斷的元素          //因為已經自動向下一個移動了,這是就要在刪除nodeNow之前,          //擷取它的Next,賦給nodeTmp,待nodeNow刪除之後,再把nodeTmp的記憶體賦給nodeNow          nodeTmp = nodeNow.Next;          this.list.Remove(nodeNow);          nodeNow = nodeTmp;        }        else        {          //如果不能被2整除,則在鏈表中保留該元素,並獲得下一個並進行判斷          nodeNow = nodeNow.Next;        }      }      //最後不要忘記對nodeLast(原鏈表最後一個元素)本身進行處理,上面的while迴圈沒有包括這個nodeLast      if (nodeNow.Value % 3 == 0)      {        this.list.AddLast(0);      }      if (nodeNow.Value % 2 == 0)      {        this.list.Remove(nodeNow);      }    }    //測試結果    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 集合遍曆時刪除或增加元素{  public partial class Form1 : Form  {    public Form1()    {      InitializeComponent();    }    private LinkedList<int> list = new LinkedList<int>();    //初始化,添加0-29的整數進入鏈表    private void button1_Click(object sender, EventArgs e)    {      for (int i = 0; i < 30; i++)      {        this.list.AddLast(i);      }    }    //遍曆鏈表,做如下操作:    //遇到能被3整除的,就在該鏈表後增加一個0元素,遇到能被2整除的就刪除該元素    private void button2_Click(object sender, EventArgs e)    {      LinkedListNode<int> nodeNow = this.list.First;//鏈表第一個元素      LinkedListNode<int> nodeLast = this.list.Last;//原鏈表的最後一個元素,迴圈結束的標記      LinkedListNode<int> nodeTmp;//臨時結點      //迴圈結束的條件是,等當前結點是原鏈表的最後一個結點      while (nodeNow != nodeLast)      {        //如果能被3整除時,則在鏈表後加一個0        if (nodeNow.Value % 3 == 0)        {          this.list.AddLast(0);        }        //如果能被2整除,則刪除該元素        if (nodeNow.Value % 2 == 0)        {          //如果nodeNow被刪除了,那麼一定不能用Next擷取下一個要判斷的元素          //因為已經自動向下一個移動了,這是就要在刪除nodeNow之前,          //擷取它的Next,賦給nodeTmp,待nodeNow刪除之後,再把nodeTmp的記憶體賦給nodeNow          nodeTmp = nodeNow.Next;          this.list.Remove(nodeNow);          nodeNow = nodeTmp;        }        else        {          //如果不能被2整除,則在鏈表中保留該元素,並獲得下一個並進行判斷          nodeNow = nodeNow.Next;        }      }      //最後不要忘記對nodeLast(原鏈表最後一個元素)本身進行處理,上面的while迴圈沒有包括這個nodeLast      if (nodeNow.Value % 3 == 0)      {        this.list.AddLast(0);      }      if (nodeNow.Value % 2 == 0)      {        this.list.Remove(nodeNow);      }    }    //測試結果    private void button3_Click(object sender, EventArgs e)    {      foreach (int i in this.list)      {        Console.WriteLine(i);      }    }  }}

第二種方法:使用C#的List<>,List<>是基於數組的順序表,增加、刪除動作時間複雜度較高,不如鏈表的效率高。其基本原來同第一種方法相似,也需要使用一個int型的變數標記原順序表的尾部元素,當刪除一個元素時,這個變數需要自減。代碼略。

第三種方法,自訂單鏈表泛型類(鏈表類見http://www.jb51.net/article/87610.htm)。跟第一種方法比的好處,就是能夠靈活實現兩個鏈表的合并,只需要把第二個鏈表的頭結點設定成第一個鏈表的尾結點的Next的結點(或直接Add)就可以了。其實對於C#的雙鏈表,我並不是很清楚,為什麼AddLast()方法,無法將一個鏈表的元素添加到另一個鏈表中,而只能添加一個不屬於任何鏈表的結點(有人說第一種方法,其實可以使用結點Clone,但是這樣無非還是增加演算法的空間和時間複雜度,違背了使用鏈表的本意)。C#之所以不支援這種做法的原因可能是,MS擔心你加入的結點,位於一個環狀鏈表上,這樣會導致原鏈表的Last屬性、Count屬性等無法計算(形成死迴圈)。測試代碼如下:

//兩個鏈表的合并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();//兩個鏈表的合并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();

更多關於C#相關內容感興趣的讀者可查看本站專題:《C#遍曆演算法與技巧總結》、《C#程式設計之線程提示總結》、《C#操作Excel技巧總結》、《C#中XML檔案操作技巧匯總》、《C#常見控制項用法教程》、《WinForm控制項用法總結》、《C#資料結構與演算法教程》、《C#數組操作技巧總結》及《C#物件導向程式設計入門教程》

希望本文所述對大家C#程式設計有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.