亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#數據結構之單鏈表(LinkList)實例詳解

2020-01-24 01:21:33
字體:
來源:轉載
供稿:網友

本文實例講述了C#數據結構之單鏈表(LinkList)實現方法。分享給大家供大家參考,具體如下:

這里我們來看下“單鏈表(LinkList)”。在上一篇《C#數據結構之順序表(SeqList)實例詳解》的最后,我們指出了:順序表要求開辟一組連續的內存空間,而且插入/刪除元素時,為了保證元素的順序性,必須對后面的元素進行移動。如果你的應用中需要頻繁對元素進行插入/刪除,那么開銷會很大。

而鏈表結構正好相反,先來看下結構:

每個元素至少具有二個屬性:data和next。data用來存放數據,而next用來指出它后面的元素是誰(有點“指針”的意思)。

鏈表中的元素,通常也稱為節點Node,下面是泛型版本的Node.cs

namespace 線性表{  public class Node<T>  {    private T data;    private Node<T> next;    public Node(T val, Node<T> p)     {      data = val;      next = p;    }    public Node(Node<T> p)     {      next = p;    }    public Node(T val)     {      data = val;      next = null;    }    public Node()     {      data = default(T);      next = null;    }    public T Data     {      get { return data; }      set { data = value; }    }    public Node<T> Next     {      get { return next; }      set { next = value; }    }  }}

鏈表在存儲上并不要求所有元素按順序存儲,因為用節點的next就能找到下一個節點,這好象一根“用珠子串成的鏈子”,要找到其中的某一顆珠子,只要從第一顆節點(通常稱為Head節點)開始,不斷根據next指向找到下一個,直到找到需要的節點為止。

鏈表中需要有一個Head節點做為開始,這跟順序表有所不同,下面是單鏈表的實現:

using System;using System.Text;namespace 線性表{  public class LinkList<T> : IListDS<T>  {    private Node<T> head;    public Node<T> Head    {      get { return head; }      set { head = value; }    }    public LinkList()    {      head = null;    }    /// <summary>    /// 類索引器    /// </summary>    /// <param name="index"></param>    /// <returns></returns>    public T this[int index]     {      get      {        return this.GetItemAt(index);      }    }    /// <summary>    /// 返回單鏈表的長度    /// </summary>    /// <returns></returns>    public int Count()    {      Node<T> p = head;      int len = 0;      while (p != null)      {        len++;        p = p.Next;      }      return len;    }    /// <summary>    /// 清空    /// </summary>    public void Clear()    {      head = null;    }    /// <summary>    /// 是否為空    /// </summary>    /// <returns></returns>    public bool IsEmpty()    {      return head == null;    }    /// <summary>    /// 在最后附加元素    /// </summary>    /// <param name="item"></param>    public void Append(T item)    {      Node<T> d = new Node<T>(item);      Node<T> n = new Node<T>();      if (head == null)      {        head = d;        return;      }      n = head;      while (n.Next != null)      {        n = n.Next;      }      n.Next = d;    }    //前插    public void InsertBefore(T item, int i)    {      if (IsEmpty() || i < 0)      {        Console.WriteLine("List is empty or Position is error!");        return;      }      //在最開頭插入      if (i == 0)      {        Node<T> q = new Node<T>(item);        q.Next = Head;//把"頭"改成第二個元素        head = q;//把自己設置為"頭"        return;      }      Node<T> n = head;      Node<T> d = new Node<T>();      int j = 0;      //找到位置i的前一個元素d      while (n.Next != null && j < i)      {        d = n;        n = n.Next;        j++;      }      if (n.Next == null) //說明是在最后節點插入(即追加)      {        Node<T> q = new Node<T>(item);        n.Next = q;        q.Next = null;      }      else      {        if (j == i)        {          Node<T> q = new Node<T>(item);          d.Next = q;          q.Next = n;        }      }    }    /// <summary>    /// 在位置i后插入元素item    /// </summary>    /// <param name="item"></param>    /// <param name="i"></param>    public void InsertAfter(T item, int i)    {      if (IsEmpty() || i < 0)      {        Console.WriteLine("List is empty or Position is error!");        return;      }      if (i == 0)      {        Node<T> q = new Node<T>(item);        q.Next = head.Next;        head.Next = q;        return;      }      Node<T> p = head;      int j = 0;      while (p != null && j < i)      {        p = p.Next;        j++;      }      if (j == i)      {        Node<T> q = new Node<T>(item);        q.Next = p.Next;        p.Next = q;      }      else      {        Console.WriteLine("Position is error!");      }    }    /// <summary>    /// 刪除位置i的元素    /// </summary>    /// <param name="i"></param>    /// <returns></returns>    public T RemoveAt(int i)    {      if (IsEmpty() || i < 0)      {        Console.WriteLine("Link is empty or Position is error!");        return default(T);      }      Node<T> q = new Node<T>();      if (i == 0)      {        q = head;        head = head.Next;        return q.Data;      }      Node<T> p = head;      int j = 0;      while (p.Next != null && j < i)      {        j++;        q = p;        p = p.Next;      }      if (j == i)      {        q.Next = p.Next;        return p.Data;      }      else      {        Console.WriteLine("The node is not exist!");        return default(T);      }    }    /// <summary>    /// 獲取指定位置的元素    /// </summary>    /// <param name="i"></param>    /// <returns></returns>    public T GetItemAt(int i)    {      if (IsEmpty())      {        Console.WriteLine("List is empty!");        return default(T);      }      Node<T> p = new Node<T>();      p = head;      if (i == 0)       {         return p.Data;       }      int j = 0;      while (p.Next != null && j < i)      {        j++;        p = p.Next;      }      if (j == i)      {        return p.Data;      }      else      {        Console.WriteLine("The node is not exist!");        return default(T);      }    }    //按元素值查找索引    public int IndexOf(T value)    {      if (IsEmpty())      {        Console.WriteLine("List is Empty!");        return -1;      }      Node<T> p = new Node<T>();      p = head;      int i = 0;      while (!p.Data.Equals(value) && p.Next != null)      {        p = p.Next;        i++;      }      return i;    }    /// <summary>    /// 元素反轉    /// </summary>    public void Reverse()    {      LinkList<T> result = new LinkList<T>();      Node<T> t = this.head;      result.Head = new Node<T>(t.Data);      t = t.Next;      //(把當前鏈接的元素從head開始遍歷,逐個插入到另一個空鏈表中,這樣得到的新鏈表正好元素順序跟原鏈表是相反的)      while (t!=null)      {                result.InsertBefore(t.Data, 0);        t = t.Next;      }      this.head = result.head;//將原鏈表直接掛到"反轉后的鏈表"上      result = null;//顯式清空原鏈表的引用,以便讓GC能直接回收    }    public override string ToString()    {      StringBuilder sb = new StringBuilder();      Node<T> n = this.head;      sb.Append(n.Data.ToString() + ",");      while (n.Next != null)      {        sb.Append(n.Next.Data.ToString() + ",");        n = n.Next;      }      return sb.ToString().TrimEnd(',');    }  }}

下面是單鏈表插入和刪除的算法圖解:

可以看到:鏈表在元素插入/刪除時,無需對后面的元素進行移動,只需要修改自身以及相鄰節點的next指向即可,所以插入/刪除元素的開銷要比順序表小得多。但是也應該注意到,其它操作比如:查找元素,反轉倒置鏈表等,有可能需要遍歷整個鏈表中的所有元素。

測試代碼片斷:

Console.WriteLine("-------------------------------------");Console.WriteLine("單鏈表測試開始...");LinkList<string> link = new LinkList<string>();link.Head = new Node<string>("x");link.InsertBefore("w", 0);link.InsertBefore("v", 0);link.Append("y");link.InsertBefore("z", link.Count());Console.WriteLine(link.Count());//5Console.WriteLine(link.ToString());//v,w,x,y,zConsole.WriteLine(link[1]);//wConsole.WriteLine(link[0]);//vConsole.WriteLine(link[4]);//zConsole.WriteLine(link.IndexOf("z"));//4Console.WriteLine(link.RemoveAt(2));//xConsole.WriteLine(link.ToString());//v,w,y,zlink.InsertBefore("x", 2);Console.WriteLine(link.ToString());//v,w,x,y,zConsole.WriteLine(link.GetItemAt(2));//xlink.Reverse();Console.WriteLine(link.ToString());//z,y,x,w,vlink.InsertAfter("1", 0);link.InsertAfter("2", 1);link.InsertAfter("6", 5);link.InsertAfter("8", 7);link.InsertAfter("A", 10);//Position is error!Console.WriteLine(link.ToString()); //z,1,2,y,x,w,6,v,8

至于具體在實際應用中應該選用順序表 or 鏈表,主要是看:對于元素插入/刪除的頻繁程度以及對于內存分配的苛刻程度。 如果不要求一開始就分配一組連續的內存區域,可以根據元素的增加而自動加大內存的使用量,或者插入/刪除的次數很多,那么建議使用鏈表,反之用順序表。

最后指出:可以給節點再添加一個prev元素,用于指出前一個節點是誰,即同時有next和prev二個指向,這種改進后的鏈表稱為“雙向鏈表”,它有助于某些情況下減少遍歷循環的次數,本文中的這種僅有一個next指向的鏈表,稱為“單鏈表”。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品亚洲第一区| 久久天堂av综合合色| 亚洲视频综合网| 久久免费国产精品1| 亚洲免费伊人电影在线观看av| 日韩视频免费观看| 成人午夜两性视频| 成人国内精品久久久久一区| 91精品免费久久久久久久久| 人人澡人人澡人人看欧美| 欧美主播福利视频| 国产丝袜精品第一页| 亚洲国产精品悠悠久久琪琪| 欧美最顶级的aⅴ艳星| 国产精品国内视频| 亚洲欧美国产视频| 亚洲欧美国产精品久久久久久久| 亚洲影院色无极综合| 国产精品亚洲片夜色在线| 国产丝袜视频一区| 精品国产乱码久久久久酒店| 日韩av黄色在线观看| 伊人男人综合视频网| 欧美激情久久久| 在线播放国产一区二区三区| 欧美另类69精品久久久久9999| 色偷偷av亚洲男人的天堂| 不卡av在线播放| 欧美日韩中文字幕日韩欧美| 日本三级韩国三级久久| 精品国产一区二区三区久久| 亚洲精品视频在线观看视频| 日韩高清电影免费观看完整版| 亚洲黄色片网站| 日韩天堂在线视频| 国产suv精品一区二区三区88区| 国产日韩欧美中文在线播放| 亚洲热线99精品视频| 日本成人黄色片| 欧美影院久久久| 亚洲欧美另类中文字幕| 日韩免费av一区二区| 国产精品入口免费视频一| 国产一区深夜福利| 久久99精品久久久久久青青91| 亚洲小视频在线| 亚洲欧美国内爽妇网| 成人黄色影片在线| 欧美精品videosex牲欧美| 亚洲自拍小视频| 亚洲精品成a人在线观看| 亚洲精品有码在线| 久久久久999| 亚洲精品久久久久中文字幕二区| 成人国产精品免费视频| 亚洲高清一二三区| 中文字幕亚洲一区| 久久久久久999| yw.139尤物在线精品视频| 日韩av片永久免费网站| 中文字幕九色91在线| 欧美日韩国内自拍| 91性高湖久久久久久久久_久久99| 91国偷自产一区二区三区的观看方式| 色偷偷av亚洲男人的天堂| 日韩av快播网址| 日韩精品免费在线| 国产亚洲美女精品久久久| 亚洲精品aⅴ中文字幕乱码| 国内精品美女av在线播放| 永久免费毛片在线播放不卡| 欧美日韩国产91| 欧洲s码亚洲m码精品一区| 国内精品久久久久久| 欧美孕妇与黑人孕交| 亚洲精品国产精品乱码不99按摩| 亚洲视频精品在线| 日韩电影在线观看永久视频免费网站| 91国产视频在线| 中文字幕av一区二区| 国产精品久久久久7777婷婷| 久热精品视频在线免费观看| 久久天天躁狠狠躁夜夜爽蜜月| 欧美电影免费观看电视剧大全| 国产一区二区三区视频免费| 97不卡在线视频| 亚洲最大中文字幕| 国产精品美女av| 亚洲精品电影在线| 青青久久aⅴ北条麻妃| 国产精品视频一| 精品久久久久久中文字幕大豆网| 国内精品久久影院| 亚洲精品美女久久久久| 亚洲免费精彩视频| 久久精品国产综合| 亚洲欧美中文字幕在线一区| 久久天天躁日日躁| 97色在线视频观看| 91亚洲人电影| 国产精品88a∨| 成人在线视频网| 日韩中文字在线| 成人网页在线免费观看| 亚洲摸下面视频| 亚洲欧美日韩第一区| 日韩中文字幕网| 国内精品久久久久| 国内伊人久久久久久网站视频| xvideos亚洲人网站| 夜夜狂射影院欧美极品| 中文字幕亚洲图片| 热草久综合在线| 国产激情999| 日韩美女主播视频| 久久av资源网站| 欧美另类交人妖| 国产亚洲人成a一在线v站| 久久99精品久久久久久青青91| 国模极品一区二区三区| 亚洲天堂成人在线视频| 日韩免费观看网站| 国语自产偷拍精品视频偷| 精品国产乱码久久久久酒店| 午夜精品99久久免费| 国产亚洲精品91在线| 亚洲最大的免费| 亚洲精品国产电影| 国产精品福利小视频| 亚洲精品国产suv| 懂色av中文一区二区三区天美| 亚洲午夜未满十八勿入免费观看全集| 成人有码在线播放| 久久亚洲国产精品成人av秋霞| 国产亚洲福利一区| 欧美性生交大片免费| 亚洲影视中文字幕| 欧美激情a∨在线视频播放| 亚洲国产精品久久久久秋霞不卡| 高跟丝袜欧美一区| 国产在线视频91| 日本久久久久久久| 91亚洲精品久久久久久久久久久久| 久久人人看视频| 成人福利在线观看| 亚洲wwwav| 国产精品一区二区久久国产| 午夜精品久久17c| 亚洲精品综合久久中文字幕| 亚洲精品www久久久久久广东| 日韩精品免费在线视频| 大胆欧美人体视频| 欧美激情国产精品| 色综合久久88| 亚洲国产精品久久| 精品国产一区二区三区久久久狼| 日韩中文娱乐网| 亚洲国产美女久久久久| 欧美精品免费看| 2019中文字幕在线观看| 中文字幕日韩精品有码视频| 亚洲综合国产精品| 亚洲免费视频在线观看| 亚洲国产精品va在看黑人|