• c#双向链表


    分析

    双向链表的遍历,添加、修改、删除的操作思路

    • 遍历方合单链表一样,只是可以向前、向后查找
    • 添加(默认添加到双向链表的最后)

    (1)先找到双向链表的最后这个节点

    (2)temp.next = new DataNode();

    (3)newDataNode.Pre = temp;

    • 修改思路和原理跟单向链表一样
    • 删除

    (1)因为是双向链表,因此,我们可以实现自我删除某个节点

    (2)直接找到要删除的这个节点,比如temp

    (3)temp.pre.next = temp.next;

    (4)temp.next.pre = temp.pre;

     

    代码实现

    internal class DataNode{
      public int Id { get; set; }
    
      public string Name { get; set; }
    
      /// <summary>
      /// 指向下一个节点,默认为null
      /// </summary>
      public DataNode NextNode { get; set; }
    
      /// <summary>
      /// 指向上一个节点,默认为null
      /// </summary>
      public DataNode PreNode { get; set; }
    
      internal DataNode(int id,string name)
      {
          this.Id = id;
          this.Name = name;
      }
    
      public override string ToString()
      {
          return $"DataNode[no={Id}],name={Name}";
      }
    }
    
    /// <summary>
    /// 双向链表
    /// </summary>
    internal class MyDoubleLinkedList
    {
      //初始化一个头节点,头节点不要动,不存放具体的数据
      private DataNode head = new DataNode(0,"");
    
      /// <summary>
      /// 返回头节点
      /// </summary>
      /// <returns></returns>
      public DataNode GetHead()
      {
          return head;
      }
    
      /// <summary>
      /// 遍历双向链表
      /// </summary>
      public void List()
      {
          if (head.NextNode == null)
          {
              Console.WriteLine("链表为空");
              return;
          }
          //因为头节点,不能动,因此我们需要一个辅助变量来遍历
          DataNode temp = head.NextNode;
          while (true)
          {
              //判断是否到链表最后
              if (temp==null) break;
              Console.WriteLine(temp);
              //将temp后移
              temp = temp.NextNode;
          }
    
          Console.WriteLine();
      }
    
      /// <summary>
      /// 添加一个节点到双向链表的最后
      /// </summary>
      /// <param name="node"></param>
      public void Add(DataNode node)
      {
          //因为head节点不能动,因此我们需要一个辅助遍历的temp
          DataNode temp = head;
          //遍历链表,找到最后
          while (true)
          {
              //找到链表的最后
              if (temp.NextNode == null) break;
              //如果没有找到最后,将temp后移
              temp = temp.NextNode;
          }
          //当推出while循环时,temp就指向了链表的最后
          //形成一个双向链表
          temp.NextNode = node;
          node.PreNode = temp;
      }
    
      /// <summary>
      /// 修改一个节点的内容
      /// </summary>
      /// <param name="node"></param>
      public void Update(DataNode node)
      {
          if (head.NextNode == null)
          {
              Console.WriteLine("链表为空");
              return;
          }
    
          DataNode temp = head.NextNode;
          bool flag = false;
          while (true)
          {
              //判断是否到链表最后
              if (temp == null) break;
    
              if (temp.Id == node.Id)
              {
                  flag = true;
                  break;
              }
              //将temp后移
              temp = temp.NextNode;
          }
    
          if (flag)
          {
              temp.Name = node.Name;
          }
          else
          {
              Console.WriteLine($"没有找到编号{node.Id}的节点,不能修改!");
          }
      }
    
      /// <summary>
      /// 删除一个节点
      /// 1.对于双向链表,我们可以直接找到要删除的这个节点
      /// 2.找到后,自我删除即可
      /// </summary>
      /// <param name="id"></param>
      public void Delete(int id)
      {
          //判断当前链表是否为空
          if (head.NextNode == null)
          {
              Console.WriteLine("链表为空,无法删除");
              return;
          }
    
          DataNode temp = head.NextNode;
          bool flag = false;
          while (true)
          {
              if (temp == null) break;
    
              if (temp.Id == id)
              {
                  flag = true;
                  break;
              }
              temp = temp.NextNode;
          }
    
          if (flag)
          {
              temp.PreNode.NextNode = temp.NextNode;
              //如果时最后一个节点,就不需要指向下面这句话,否则会出现空指针
              if (temp.NextNode != null)
              {
                  temp.NextNode.PreNode = temp.PreNode;
              }
          }
          else
          {
              Console.WriteLine($"要删除{id},节点不存在。");
          }
      }
    }

     

    代码运行

    MyDoubleLinkedList list = new MyDoubleLinkedList();
    list.Add(new DataNode(1,"zhangsan"));
    list.Add(new DataNode(2, "lisi"));
    list.Add(new DataNode(3, "wangwu"));
    list.Add(new DataNode(4, "zhaoliu"));
    list.List();
    
    list.Update(new DataNode(2,"juster"));
    list.List();
    
    list.Delete(2);
    list.List();

     

     

    再添加一个有序插入方法

      /// <summary>
       /// 根据id号有序添加数据
       /// </summary>
       /// <param name="node"></param>
       public void AddOrderById(DataNode node)
      {
           //因为head节点不能动,因此我们需要一个辅助遍历的temp
           DataNode temp = head;
           bool flag = false;
           //遍历链表,找到最后
           while (true)
          {
               //找到链表的最后
               if (temp.NextNode == null) break;
    
               //当前的节点id小于需要插入的节点id,并且需要插入的节点id小于当前节点的下一个节点的id
               if (temp.Id < node.Id && node.Id < temp.NextNode.Id)
              {
                   flag = true;
                   break;
              }
               //后移
               temp = temp.NextNode;
          }
    
           if (flag)
          {
               //保存当前节点的下一个节点
               var tempNext = temp.NextNode;
               //将当前节点的下一个节点赋值为需要新增的节点
               temp.NextNode = node;
               node.PreNode = temp;
    
               temp.NextNode.NextNode = tempNext;
               tempNext.PreNode = temp.NextNode;
          }
           else
          {
               temp.NextNode = node;
               node.PreNode = temp;
          }
      }
    
    //调用
    MyDoubleLinkedList list = new MyDoubleLinkedList();
    list.AddOrderById(new DataNode(8, "haha"));
    list.AddOrderById(new DataNode(1,"zhangsan"));
    list.AddOrderById(new DataNode(7, "haha"));
    list.AddOrderById(new DataNode(4, "zhaoliu"));
    list.AddOrderById(new DataNode(2, "lisi"));
    list.AddOrderById(new DataNode(3, "wangwu"));
    
    list.List();
    

     

  • 相关阅读:
    LeetCode 669. 修剪二叉搜索树(Trim a Binary Search Tree)
    LeetCode 872. 叶子相似的树(Leaf-Similar Trees)
    LeetCode 513. 找树左下角的值(Find Bottom Left Tree Value)
    LeetCode 223. 矩形面积(Rectangle Area)
    LeetCode 704. 二分查找(Binary Search)
    LeetCode 74. 搜索二维矩阵(Search a 2D Matrix)
    LeetCode 240. 搜索二维矩阵 II(Search a 2D Matrix II) 37
    Html5 Css实现方形图片 圆形显示
    css 图片 圆形显示区域
    Visual Studio常用的快捷键
  • 原文地址:https://www.cnblogs.com/justzhuzhu/p/15866453.html
Copyright © 2020-2023  润新知