<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      重溫?cái)?shù)據(jù)結(jié)構(gòu)系列隨筆:?jiǎn)捂湵恚╟#模擬實(shí)現(xiàn))

      重溫?cái)?shù)據(jù)結(jié)構(gòu)系列隨筆:?jiǎn)捂湵恚╟#模擬實(shí)現(xiàn))

       上一節(jié)我們講述了數(shù)據(jù)結(jié)構(gòu)的基本概念,這一節(jié)讓我們來(lái)討論下單鏈表的概念和實(shí)現(xiàn)

       我從書(shū)中簡(jiǎn)單摘錄下單鏈表概念

       

        簡(jiǎn)單而言單鏈表的是通過(guò)許多節(jié)點(diǎn)構(gòu)成,每個(gè)節(jié)點(diǎn)包含2個(gè)重要元素:該節(jié)點(diǎn)數(shù)據(jù)(數(shù)據(jù)域)和指向下個(gè)節(jié)點(diǎn)的地址(指針域)

        這樣說(shuō)太枯燥了,讓我們直接用c# 來(lái)一步步實(shí)現(xiàn)

        既然一個(gè)節(jié)點(diǎn)是由(數(shù)據(jù)域)和(指針域)構(gòu)成,那我們簡(jiǎn)單DIY一個(gè)LinkNode類

           /// <summary>
      /// 單鏈表的節(jié)點(diǎn)
      /// </summary>
      public class LinkNode
      {
      //節(jié)點(diǎn)數(shù)據(jù)域
      public object LinkNodeData { get; set; }
      //自己節(jié)點(diǎn)的地址
      public Guid SelfAddress { get; set; }
      //下個(gè)節(jié)點(diǎn)的地址指針(存儲(chǔ)位置)
      public Guid NextAddress { get; set; }
      }

      繼續(xù)來(lái)了解概念了,既然節(jié)點(diǎn)準(zhǔn)備好了,那我們要了解節(jié)點(diǎn)是怎么通過(guò)指針域連接在一起的,看圖

      圖中節(jié)點(diǎn)就是一個(gè)小矩形,數(shù)據(jù)域是姓名,指針域就是那個(gè)箭頭所表示的指向它的后繼,頭節(jié)點(diǎn)h->zhao->Qian->....Wang

      這樣連接起來(lái)就是一個(gè)完整的單鏈表,頭結(jié)點(diǎn)的數(shù)據(jù)域可以是任何信息,尾節(jié)點(diǎn)的地址域是空(他沒(méi)有后繼節(jié)點(diǎn)了)

      好,代碼中我們只有node 沒(méi)有LinkTable,那我們就按照上圖來(lái)建立一個(gè)LinkTable類

          public class LinkTable
      {
      //定義一個(gè)LinkNode集合
      List<LinkNode> list = new List<LinkNode>();

      public LinkTable()
      {

      }

      /// <summary>
      /// 進(jìn)行單向鏈表初始化
      /// </summary>
      public void InitialList()
      {

      //添加5個(gè)節(jié)點(diǎn)擁有唯一的guid作為自身地址,后繼節(jié)點(diǎn)地址為guid.empty
      for (int i = 0; i < 5; i++)
      {
      list.Add
      (
      new LinkNode { LinkNodeData = string.Format("第{0}個(gè)節(jié)點(diǎn)", i + 1), SelfAddress = Guid.NewGuid(), NextAddress = Guid.Empty }
      );
      }

      s
      var j = 0;
      //將節(jié)點(diǎn)的 指針域指向下一個(gè)節(jié)點(diǎn)的地址
      list.ForEach
      (
      (linkNode) =>
      {
      if (j < list.Count - 1)
      {
      linkNode.NextAddress = list.Skip(++j).FirstOrDefault().SelfAddress;
      }
      }
      );
      }
      }


      LinkTable類包含一個(gè)LinkNode集合 和一個(gè)初始方法,這個(gè)方法是先添加節(jié)點(diǎn)數(shù)據(jù)到集合中,然后將節(jié)點(diǎn)的地址域一一連接起來(lái)

      肯定會(huì)有朋友問(wèn)我,那么你怎么在單鏈表中插入數(shù)據(jù)或刪除數(shù)據(jù)呢?

      非常棒的問(wèn)題,看圖:

       

       圖中可以看出a節(jié)點(diǎn)的后繼是b節(jié)點(diǎn),a節(jié)點(diǎn)的指針域指向b節(jié)點(diǎn),那如果在a節(jié)點(diǎn)和b節(jié)點(diǎn)中添加一個(gè)新的節(jié)點(diǎn)那情況又如何?

       其實(shí)圖中已經(jīng)表達(dá)出來(lái)了,將a的指針域指向新節(jié)點(diǎn),然后將新節(jié)點(diǎn)的指針域指向b節(jié)點(diǎn)

       馬上看代碼理解

       既然是添加節(jié)點(diǎn)那我們?cè)贚inkTable類中添加方法就行

              /// <summary>
      /// 添加一個(gè)新節(jié)點(diǎn)
      /// </summary>
      /// <param name="node">節(jié)點(diǎn)</param>
      /// <param name="addIndex">在index處添加節(jié)點(diǎn)</param>
      public void AddNode(LinkNode node, int addIndex)
      {

      if (this.list == null || node == null)
      {
      // 如果鏈表為空則初始鏈表并且添加節(jié)點(diǎn)
      this.InitialList();
      }
      if (addIndex < 0 || addIndex > list.Count)
      {
      throw new IndexOutOfRangeException("removeIndex超出范圍");
      }
      var listCount = list.Count;
      //注意,得到新插入節(jié)點(diǎn)的前一個(gè)索引位置
      var prev = addIndex - 1 <= 0 || listCount <= 0 ? 0 : addIndex - 1;
      //注意,得到新插入節(jié)點(diǎn)的后一個(gè)索引位置
      var after = listCount <= 0 ? 0 :
      addIndex > listCount - 1 ? listCount - 1 : addIndex;
      //插入后前一個(gè)節(jié)點(diǎn)
      var prevNode = list[prev];
      //插入后后一個(gè)節(jié)點(diǎn)
      var afterNode = list[after];
      //將前一個(gè)節(jié)點(diǎn)的指針域指向新節(jié)點(diǎn)
      node.NextAddress = afterNode.SelfAddress;
      //將新節(jié)點(diǎn)的指針域指向后一個(gè)節(jié)點(diǎn)
      prevNode.NextAddress = node.SelfAddress;
      //判斷是否插入到最后一個(gè)位置
      if (addIndex == list.Count)
      {
      node.NextAddress = Guid.Empty;
      list.Add(node);
      }
      else
      {
      // 插入新節(jié)點(diǎn)
      list.Insert(addIndex, node);
      }
      }

      代碼注釋能夠幫助你了解下添加節(jié)點(diǎn)的具體過(guò)程,請(qǐng)大家仔細(xì)消化下

      最后是刪除一個(gè)節(jié)點(diǎn)的情況:

      和添加節(jié)點(diǎn)正好逆向思維,當(dāng)我們刪除b節(jié)點(diǎn)時(shí),我們要將a節(jié)點(diǎn)的指針域指向c節(jié)點(diǎn)保證我們的單鏈表不被破壞

      刪除方法同樣寫(xiě)在LinkTable類中

            /// <summary>
      /// 通過(guò)索引刪除
      /// </summary>
      /// <param name="removeIndex"></param>
      /// <returns></returns>
      public void Remove(int removeIndex)
      {
      if (this.list == null)
      {
      // 如果鏈表為空則初始鏈表并且添加節(jié)點(diǎn)
      this.InitialList();
      }
      if (removeIndex > this.list.Count - 1 || removeIndex < 0)
      {
      throw new IndexOutOfRangeException("removeIndex超出范圍");
      }

      var preIndex = removeIndex - 1;
      var afterIndex = removeIndex + 1;
      var preNode = list[preIndex];
      var afterNode = list[afterIndex];

      //將被刪除節(jié)點(diǎn)前后的指針域進(jìn)行整理
      preNode.NextAddress = afterNode.SelfAddress;
      //刪除該節(jié)點(diǎn)
      list.Remove(list[removeIndex]);



      }

      ok,這就是單鏈表的一個(gè)簡(jiǎn)單理解,請(qǐng)大家務(wù)必牢記,因?yàn)楹笳碌难h(huán)列表將更復(fù)雜,單鏈表只是一個(gè)鏈表的基礎(chǔ)(一以下是完整代碼及輸出情況)

      View Code
          class Program
      {
      static void Main(string[] args)
      {


      LinkTable table = new LinkTable();
      //初始化
      table.InitialList();
      //嘗試添加一個(gè)新節(jié)點(diǎn)
      table.AddNode
      (
      new LinkNode { LinkNodeData="新節(jié)點(diǎn)",NextAddress=Guid.Empty, SelfAddress=Guid.NewGuid()},
      4
      );
      //刪除一個(gè)節(jié)點(diǎn)
      table.Remove(1);

      var i = 0;
      //循環(huán)顯示
      table.list.ForEach
      (
      (linkNode) =>
      {
      if (i ==table.list.Count - 1)
      {
      Console.Write("{0} ->{1}", linkNode.LinkNodeData, "Null");
      }
      else
      {
      Console.Write("{0} ->", linkNode.LinkNodeData);
      }
      i++;
      }
      );


      Console.ReadLine();
      }



      }


      /// <summary>
      /// 單鏈表的節(jié)點(diǎn)
      /// </summary>
      public class LinkNode
      {
      //節(jié)點(diǎn)數(shù)據(jù)域
      public object LinkNodeData { get; set; }
      //自己節(jié)點(diǎn)的地址
      public Guid SelfAddress { get; set; }
      //下個(gè)節(jié)點(diǎn)的地址指針(存儲(chǔ)位置)
      public Guid NextAddress { get; set; }
      }

      /// <summary>
      /// 單鏈表
      /// </summary>
      public class LinkTable
      {
      //定義一個(gè)LinkNode集合
      public List<LinkNode> list = new List<LinkNode>();

      public LinkTable()
      {

      }

      /// <summary>
      /// 進(jìn)行單向鏈表初始化
      /// </summary>
      public void InitialList()
      {

      //添加10個(gè)節(jié)點(diǎn)擁有唯一的guid作為自身地址,后繼節(jié)點(diǎn)地址為guid.empty
      for (int i = 0; i < 5; i++)
      {
      list.Add
      (
      new LinkNode { LinkNodeData = string.Format("第{0}個(gè)節(jié)點(diǎn)", i + 1), SelfAddress = Guid.NewGuid(), NextAddress = Guid.Empty }
      );
      }


      var j = 0;
      //將節(jié)點(diǎn)的 指針域指向下一個(gè)節(jié)點(diǎn)的地址
      list.ForEach
      (
      (linkNode) =>
      {
      if (j < list.Count - 1)
      {
      linkNode.NextAddress = list.Skip(++j).FirstOrDefault().SelfAddress;
      }
      }
      );

      }

      /// <summary>
      /// 添加一個(gè)新節(jié)點(diǎn)
      /// </summary>
      /// <param name="node">節(jié)點(diǎn)</param>
      /// <param name="addIndex">在index處添加節(jié)點(diǎn)</param>
      public void AddNode(LinkNode node, int addIndex)
      {

      if (this.list == null || node == null)
      {
      // 如果鏈表為空則初始鏈表并且添加節(jié)點(diǎn)
      this.InitialList();
      }
      if (addIndex < 0 || addIndex > list.Count)
      {
      throw new IndexOutOfRangeException("removeIndex超出范圍");
      }
      var listCount = list.Count;
      //注意,得到新插入節(jié)點(diǎn)的前一個(gè)索引位置
      var prev = addIndex - 1 <= 0 || listCount <= 0 ? 0 : addIndex - 1;
      //注意,得到新插入節(jié)點(diǎn)的后一個(gè)索引位置
      var after = listCount <= 0 ? 0 :
      addIndex > listCount - 1 ? listCount - 1 : addIndex;
      //插入后前一個(gè)節(jié)點(diǎn)
      var prevNode = list[prev];
      //插入后后一個(gè)節(jié)點(diǎn)
      var afterNode = list[after];
      //將前一個(gè)節(jié)點(diǎn)的指針域指向新節(jié)點(diǎn)
      node.NextAddress = afterNode.SelfAddress;
      //將新節(jié)點(diǎn)的指針域指向后一個(gè)節(jié)點(diǎn)
      prevNode.NextAddress = node.SelfAddress;
      //判斷是否插入到最后一個(gè)位置
      if (addIndex == list.Count)
      {
      node.NextAddress = Guid.Empty;
      list.Add(node);
      }
      else
      {
      // 插入新節(jié)點(diǎn)
      list.Insert(addIndex, node);
      }
      }

      /// <summary>
      /// 通過(guò)索引刪除
      /// </summary>
      /// <param name="removeIndex"></param>
      /// <returns></returns>
      public void Remove(int removeIndex)
      {
      if (this.list == null)
      {
      // 如果鏈表為空則初始鏈表并且添加節(jié)點(diǎn)
      this.InitialList();
      }
      if (removeIndex > this.list.Count - 1 || removeIndex < 0)
      {
      throw new IndexOutOfRangeException("removeIndex超出范圍");
      }

      var preIndex = removeIndex - 1;
      var afterIndex = removeIndex + 1;
      var preNode = list[preIndex];
      var afterNode = list[afterIndex];

      //將被刪除節(jié)點(diǎn)前后的指針域進(jìn)行整理
      preNode.NextAddress = afterNode.SelfAddress;
      //刪除該節(jié)點(diǎn)
      list.Remove(list[removeIndex]);



      }

      }

      輸出:

      希望大家對(duì)單鏈表有比較深的理解,其實(shí)在效率性能上這樣的單鏈表不及數(shù)組,因?yàn)閿?shù)組更本沒(méi)有那么繁瑣,

      大家在實(shí)際項(xiàng)目還是用數(shù)組比較好,下章會(huì)和大家先補(bǔ)充下c#中的LinkList類和Array類的區(qū)別(*數(shù)組和鏈表的區(qū)別(很重要)),

      然后簡(jiǎn)單說(shuō)下循環(huán)鏈表。

      敬請(qǐng)期待 !

       

      posted @ 2012-03-20 23:14  逆時(shí)針の風(fēng)  閱讀(3757)  評(píng)論(8)    收藏  舉報(bào)
      主站蜘蛛池模板: 威海市| 熟女性饥渴一区二区三区| 国产乱码精品一区二区三区中文| 亚洲欧美日韩综合一区二区| 少妇撒尿一区二区在线视频| 国产精品久久精品| 青青草无码免费一二三区| 亚洲码欧洲码一二三四五| 亚洲综合小说另类图片五月天| 日本一区二区不卡精品| 2020国产成人精品视频| 午夜爽爽爽男女污污污网站| 天堂V亚洲国产V第一次| 在线观看成人av天堂不卡| 高清国产一区二区无遮挡| 欧美人与动zozo在线播放| 综合色综合色综合色综合| 欧美成人午夜精品免费福利| 欧美寡妇xxxx黑人猛交| 亚洲精品日韩久久精品| 黑人巨大精品欧美一区二区| 国产亚洲精品日韩av在| 最新亚洲av日韩av二区| aaa少妇高潮大片免费看| 蜜桃一区二区三区免费看| 欧美不卡无线在线一二三区观| 亚洲日韩国产成网在线观看| 日韩av一区二区不卡在线| 日韩av综合中文字幕| 西西午夜无码大胆啪啪国模| 欧美级特黄aaaaaa片| 欧美和黑人xxxx猛交视频| 成年男女免费视频网站| 国产精品自拍中文字幕| 精品亚洲精品日韩精品| 波多野结衣av一区二区三区中文| 尤物蜜芽国产成人精品区| 日本欧美一区二区三区在线播放 | 免费观看全黄做爰大片| 日本区二区三区不卡视频| 久久99精品久久久久久9|