【问题标题】:Creating a very simple linked list创建一个非常简单的链表
【发布时间】:2011-04-18 22:33:53
【问题描述】:

我正在尝试创建一个链接列表,只是想看看是否可以,但我很难理解它。有没有人有一个非常简单的使用 C# 实现链表的示例?到目前为止,我发现的所有例子都太过分了。

【问题讨论】:

    标签: c# linked-list


    【解决方案1】:

    这个不错:

      namespace ConsoleApplication1
        {
    
        // T is the type of data stored in a particular instance of GenericList.
        public class GenericList<T>
        {
            private class Node
            {
                // Each node has a reference to the next node in the list.
                public Node Next;
                // Each node holds a value of type T.
                public T Data;
            }
    
            // The list is initially empty.
            private Node head = null;
    
            // Add a node at the beginning of the list with t as its data value.
            public void AddNode(T t)
            {
                Node newNode = new Node();
                newNode.Next = head;
                newNode.Data = t;
                head = newNode;
            }
    
            // The following method returns the data value stored in the last node in
            // the list. If the list is empty, the default value for type T is
            // returned.
            public T GetFirstAdded()
            {
                // The value of temp is returned as the value of the method. 
                // The following declaration initializes temp to the appropriate 
                // default value for type T. The default value is returned if the 
                // list is empty.
                T temp = default(T);
    
                Node current = head;
                while (current != null)
                {
                    temp = current.Data;
                    current = current.Next;
                }
                return temp;
            }
        }
    }
    

    测试代码:

    static void Main(string[] args)
    {
        // Test with a non-empty list of integers.
        GenericList<int> gll = new GenericList<int>();
        gll.AddNode(5);
        gll.AddNode(4);
        gll.AddNode(3);
        int intVal = gll.GetFirstAdded();
        // The following line displays 5.
        System.Console.WriteLine(intVal);
    }
    

    我在msdnhere遇到过

    【讨论】:

    • 很好的例子...但为什么不GetHead()
    • 我认为你在那里有点错误我认为“GetLast”是方法是正确的
    • @A. Nosal - @Shane 似乎是正确的。你是对的;重命名不太对。我只是想添加一种获取列表头的新方法。
    【解决方案2】:

    链表,其核心是一堆链接在一起的节点。

    所以,你需要从一个简单的 Node 类开始:

    public class Node {
        public Node next;
        public Object data;
    }
    

    那么你的链表将有一个代表链表头(开始)的节点作为成员:

    public class LinkedList {
        private Node head;
    }
    

    然后您需要通过添加方法将功能添加到列表中。它们通常涉及沿所有节点的某种遍历。

    public void printAllNodes() {
        Node current = head;
        while (current != null) 
        {
            Console.WriteLine(current.data);
            current = current.next;
        }
    }
    

    另外,插入新数据是另一种常见的操作:

    public void Add(Object data) {
        Node toAdd = new Node();
        toAdd.data = data;
        Node current = head;
        // traverse all nodes (see the print all nodes method for an example)
        current.next = toAdd;
    }
    

    这应该是一个很好的起点。

    【讨论】:

    • @Justin 你确定对于初学者来说“遍历所有节点”是什么意思很清楚吗?
    • @insertNick,我在介绍 PrintAllNodes 方法时使用了这个术语。但这可能有点令人困惑
    • 头部不是一直为空吗?是这样的吗?
    • @shane,好吧,在这个例子中是的。您必须有一些特殊情况才能添加到空列表。
    • 我想知道为什么必须有两个类,一个用于节点,一个用于 LinkedList?为什么我不能在 LinkedList 类中声明节点?
    【解决方案3】:

    我是初学者,这对我有帮助:

    class List
    {
        private Element Root;
    }
    

    首先,您创建将包含所有方法的类 List。 然后你创建Node-Class,我称它为Element

    class Element
    {
        public int Value;
        public Element Next;
    }
    

    然后您可以开始向您的 List 类添加方法。例如,这里是一个“添加”方法。

    public void Add(int value)
    {
        Element newElement = new Element();
        newElement.Value = value;
    
        Element rootCopy = Root;
        Root = newElement;
        newElement.Next = rootCopy;
    
        Console.WriteLine(newElement.Value);
    }
    

    【讨论】:

      【解决方案4】:
      public class Node
      {
          private Object data;
      
          public Node next {get;set;}
      
          public Node(Object data)
          {
          this.data = data;
           }
      
      }
      
       public class Linkedlist
        {
          Node head;
      
          public void Add(Node n) 
          {
          n.Next = this.Head;
          this.Head = n;
          }
       }
      

      使用:

      LinkedList sample = new LinkedList();
      sample.add(new Node("first"));
      sample.Add(new Node("second"))
      

      【讨论】:

      • 感谢您的示例。您能否包括描述 每一 行代码正在做什么的 cmets?
      【解决方案5】:

      根据@jjnguy 所说的,并修复了他的 PrintAllNodes() 中的错误,这是完整的控制台应用程序示例:

      public class Node
      {
          public Node next;
          public Object data;
      }
      
      public class LinkedList
      {
          private Node head;
      
          public void printAllNodes()
          {
              Node current = head;
              while (current != null)
              {
                  Console.WriteLine(current.data);
                  current = current.next;
              }
          }
      
          public void AddFirst(Object data)
          {
              Node toAdd = new Node();
      
              toAdd.data = data;
              toAdd.next = head;
      
              head = toAdd;
          }
      
          public void AddLast(Object data)
          {
              if (head == null)
              {
                  head = new Node();
      
                  head.data = data;
                  head.next = null;
              }
              else
              {
                  Node toAdd = new Node();
                  toAdd.data = data;
      
                  Node current = head;
                  while (current.next != null)
                  {
                      current = current.next;
                  }
      
                  current.next = toAdd;
              }
          }
      }
      
      class Program
      {
          static void Main(string[] args)
          {
              Console.WriteLine("Add First:");
              LinkedList myList1 = new LinkedList();
      
              myList1.AddFirst("Hello");
              myList1.AddFirst("Magical");
              myList1.AddFirst("World");
              myList1.printAllNodes();
      
              Console.WriteLine();
      
              Console.WriteLine("Add Last:");
              LinkedList myList2 = new LinkedList();
      
              myList2.AddLast("Hello");
              myList2.AddLast("Magical");
              myList2.AddLast("World");
              myList2.printAllNodes();
      
              Console.ReadLine();
          }
      }
      

      【讨论】:

      • 在 AddLast() 下添加新节点时,将“当前”设置为私有节点并在类内部并更新当前节点是否有意义。这将有助于避免每次都从头到最后一个节点遍历节点。
      • 当然会!但这将不再是“简单的链接列表”,而是“更新了很棒的 Ronak 的超级链接列表”,这不是原始问题的一部分。这一切都归结为您所有操作的所需复杂性。使用额外的指针,AddLast 操作将具有 O(1) 复杂性,但如果要添加 DeleteLast 操作,则需要再次遍历完整列表以将新指针更新到新的最后一个节点,这将使它成为在)。更好的是,查找双向链表... WAAAY 更有趣..
      • @Dmytro,您的 AddLast 函数存在问题。添加节点后,您错过了分配头值。如果条件应该是这样的: if (head==null) { Node add = new Node(); add.data = 数据; add.next = null;头=添加; }
      • @Sagar,因此您正在创建一个新变量,向其添加“数据”和“下一个”,然后将此变量分配给 head...这使得 head 和您的新变量相同东西,对吧?那么,如果它们相同,为什么要创建一个新变量来重新分配它呢?我们只是在 head 本身上执行这些操作。
      • @Dmytro,今天突然间我的大脑筋疲力尽。为什么我们使用 Node current = head;在 AddLast 而不是 Node current = new Node()?然后分配属性 current.data=head.data?
      【解决方案6】:
      public class DynamicLinkedList
      {
      
          private class Node
          {
              private object element;
              private Node next;
      
              public object Element
              {
                  get { return this.element; }
                  set { this.element = value; }
              }
      
              public Node Next
              {
                  get { return this.next; }
                  set { this.next = value; }
              }
      
              public Node(object element, Node prevNode)
              {
                  this.element = element;
                  prevNode.next = this;
              }
      
              public Node(object element)
              {
                  this.element = element;
                  next = null;
              }
          }
      
          private Node head;
          private Node tail;
          private int count;
      
          public DynamicLinkedList()
          {
              this.head = null;
              this.tail = null;
              this.count = 0;
          }
      
          public void AddAtLastPosition(object element)
          {
              if (head == null)
              {
                  head = new Node(element);
                  tail = head;
              }
              else
              {
                  Node newNode = new Node(element, tail);
                  tail = newNode;
              }
      
              count++;
          }
      
          public object GetLastElement()
          {
              object lastElement = null;
              Node currentNode = head;
      
              while (currentNode != null)
              {
                  lastElement = currentNode.Element;
                  currentNode = currentNode.Next;
              }
      
              return lastElement;
          }
      
      }
      

      测试:

      static void Main(string[] args)
      {
          DynamicLinkedList list = new DynamicLinkedList();
          list.AddAtLastPosition(1);
          list.AddAtLastPosition(2);
          list.AddAtLastPosition(3);
          list.AddAtLastPosition(4);
          list.AddAtLastPosition(5);
      
          object lastElement = list.GetLastElement();
          Console.WriteLine(lastElement);
      }
      

      【讨论】:

        【解决方案7】:
        public class Node<T>
        {
            public T item;
            public Node<T> next;
            public Node()
            {
                this.next = null;
            }
        }
        
        
        class LinkList<T>
        {
            public Node<T> head { get; set; }
            public LinkList()
            {
                this.head = null;
            }
        
        
            public void AddAtHead(T item)
            {
                Node<T> newNode = new Node<T>();
                newNode.item = item;
                if (this.head == null)
                {
                    this.head = newNode;
                }
                else
                {
                    newNode.next = head;
                    this.head = newNode;
                }
            }
        
            public void AddAtTail(T item)
            {
                Node<T> newNode = new Node<T>();
                newNode.item = item;
                if (this.head == null)
                {
                    this.head = newNode;
                }
                else
                {
                    Node<T> temp = this.head;
                    while (temp.next != null)
                    {
                        temp = temp.next;
                    }
                    temp.next = newNode;
                }
            }
        
            public void DeleteNode(T item)
            {
                if (this.head.item.Equals(item))
                {
                    head = head.next;
                }
                else
                {
                    Node<T> temp = head;
                    Node<T> tempPre = head;
                    bool matched = false;
                    while (!(matched = temp.item.Equals(item)) && temp.next != null)
                    {
                        tempPre = temp;
                        temp = temp.next;
                    }
                    if (matched)
                    {
                        tempPre.next = temp.next;
                    }
                    else
                    {
                        Console.WriteLine("Value not found!");
                    }
                }
            }
        
            public bool searchNode(T item)
            {
                Node<T> temp = this.head;
                bool matched = false;
                while (!(matched = temp.item.Equals(item)) && temp.next != null)
                {
                    temp = temp.next;
                }
                return matched;
        
            }
            public void DisplayList()
            {
                Console.WriteLine("Displaying List!");
                Node<T> temp = this.head;
                while (temp != null)
                {
                    Console.WriteLine(temp.item);
                    temp = temp.next;
                }
            }
        
        }
        

        【讨论】:

          【解决方案8】:

          Dmytro 做得很好,但这里有一个更简洁的版本。

          class Program
          {
              static void Main(string[] args)
              {
                  LinkedList linkedList = new LinkedList(1);
          
                  linkedList.Add(2);
                  linkedList.Add(3);
                  linkedList.Add(4);
          
                  linkedList.AddFirst(0);
          
                  linkedList.Print();            
              }
          }
          
          public class Node
          {
              public Node(Node next, Object value)
              {
                  this.next = next;
                  this.value = value;
              }
          
              public Node next;
              public Object value;
          }
          
          public class LinkedList
          {
              public Node head;
          
              public LinkedList(Object initial)
              {
                  head = new Node(null, initial);
              }
          
              public void AddFirst(Object value)
              {
                  head = new Node(head, value);            
              }
          
              public void Add(Object value)
              {
                  Node current = head;
          
                  while (current.next != null)
                  {
                      current = current.next;
                  }
          
                  current.next = new Node(null, value);
              }
          
              public void Print()
              {
                  Node current = head;
          
                  while (current != null)
                  {
                      Console.WriteLine(current.value);
                      current = current.next;
                  }
              }
          }
          

          【讨论】:

          • 有点狡猾,你为什么要强迫 LL 至少有 1 个项目?根据您的构造函数 public LinkedList(Object initial)
          【解决方案9】:

          添加一个节点类。
          然后添加一个LinkedList类来实现链表
          添加执行链表的测试类

          namespace LinkedListProject
          {
              public class Node
              {
                  public Node next;
                  public object data;
              }
          
              public class MyLinkedList
              {
                  Node head;
                  public Node AddNodes(Object data)
                  {
                      Node node = new Node();
          
                      if (node.next == null)
                      {
                          node.data = data;
                          node.next = head;
                          head = node;
                      }
                      else
                      {
                          while (node.next != null)
                              node = node.next;
          
                          node.data = data;
                          node.next = null;
          
                      }
                      return node;
                  }
          
                  public void printnodes()
                  {
                      Node current = head;
                      while (current.next != null)
                      {
                          Console.WriteLine(current.data);
                          current = current.next;
                      }
                      Console.WriteLine(current.data);
                  }
              }
          
          
              [TestClass]
              public class LinkedListExample
              {
                  MyLinkedList linkedlist = new MyLinkedList();
                  [TestMethod]
                  public void linkedlisttest()
                  {
                      linkedlist.AddNodes("hello");
                      linkedlist.AddNodes("world");
                      linkedlist.AddNodes("now");
                      linkedlist.printnodes();
                  }
              }
          }
          

          【讨论】:

            【解决方案10】:

            这是一个很好的实现。

            1. 它很短,但实现了 Add(x)、Delete(x)、Contain(x) 和 Print()。
            2. 在添加到空列表或删除第一个元素时避免特殊处理。 而其他大多数示例在删除第一个元素时都做了特殊处理。
            3. 列表可以包含任何数据类型。

              using System;
              
              class Node<Type> : LinkedList<Type>
              {   // Why inherit from LinkedList? A: We need to use polymorphism.
                  public Type value;
                  public Node(Type value) { this.value = value; }
              }
              class LinkedList<Type>
              {   
                  Node<Type> next;  // This member is treated as head in class LinkedList, but treated as next element in class Node.
                  /// <summary> if x is in list, return previos pointer of x. (We can see any class variable as a pointer.)
                  /// if not found, return the tail of the list. </summary>
                  protected LinkedList<Type> Previos(Type x)
                  {
                      LinkedList<Type> p = this;      // point to head
                      for (; p.next != null; p = p.next)
                          if (p.next.value.Equals(x))
                              return p;               // find x, return the previos pointer.
                      return p;                       // not found, p is the tail.
                  }
                  /// <summary> return value: true = success ; false = x not exist </summary>
                  public bool Contain(Type x) { return Previos(x).next != null ? true : false; }
                  /// <summary> return value: true = success ; false = fail to add. Because x already exist. 
                  /// </summary> // why return value? If caller want to know the result, they don't need to call Contain(x) before, the action waste time.
                  public bool Add(Type x)
                  {
                      LinkedList<Type> p = Previos(x);
                      if (p.next != null)             // Find x already in list
                          return false;
                      p.next = new Node<Type>(x);
                      return true;
                  }
                  /// <summary> return value: true = success ; false = x not exist </summary>
                  public bool Delete(Type x)
                  {
                      LinkedList<Type> p = Previos(x);
                      if (p.next == null)
                          return false;
                      //Node<Type> node = p.next;
                      p.next = p.next.next;
                      //node.Dispose();       // GC dispose automatically.
                      return true;
                  }
                  public void Print()
                  {
                      Console.Write("List: ");
                      for (Node<Type> node = next; node != null; node = node.next)
                          Console.Write(node.value.ToString() + " ");
                      Console.WriteLine();
                  }
              }
              class Test
              {
                  static void Main()
                  {
                      LinkedList<int> LL = new LinkedList<int>();
                      if (!LL.Contain(0)) // Empty list
                          Console.WriteLine("0 is not exist.");
                      LL.Print();
                      LL.Add(0);      // Add to empty list
                      LL.Add(1); LL.Add(2); // attach to tail
                      LL.Add(2);      // duplicate add, 2 is tail.
                      if (LL.Contain(0))// Find existed element which is head
                          Console.WriteLine("0 is exist.");
                      LL.Print();
                      LL.Delete(0);   // Delete head
                      LL.Delete(2);   // Delete tail
                      if (!LL.Delete(0)) // Delete non-exist element
                          Console.WriteLine("0 is not exist.");
                      LL.Print();
                      Console.ReadLine();
                  }
              }
              

            顺便说一下,在 http://www.functionx.com/csharp1/examples/linkedlist.htm 有问题:

            1. 当只有 1 个元素时,Delete() 将失败。 (在“Head.Next = Current.Next;”行抛出异常,因为 Current 为空。)
            2. 删除第一个元素时删除(位置)将失败, 也就是说,调用 Delete(0) 会失败。

            【讨论】:

              【解决方案11】:

              这是一个带有IEnumerable 和递归反向方法的方法,尽管它并不比Reverse 方法中的while循环快,两者都是O(n):

                 public class LinkedList<T> : IEnumerable
              {
                  private Node<T> _head = null;
              
                  public Node<T> Add(T value)
                  {
                      var node = new Node<T> {Value = value};
              
                      if (_head == null)
                      {
                          _head = node;
                      }
                      else
                      {
                          var current = _head;
                          while (current.Next != null)
                          {
                              current = current.Next;
                          }
                          current.Next = node; //new head
                      }
              
                      return node;
                  }
              
                  public T Remove(Node<T> node)
                  {
                      if (_head == null)
                          return node.Value;
              
                      if (_head == node)
                      {
                          _head = _head.Next;
                          node.Next = null;
                          return node.Value;
                      }
              
                      var current = _head;
                      while (current.Next != null)
                      {
                          if (current.Next == node)
                          {
                              current.Next = node.Next;
                              return node.Value;
                          }
              
                          current = current.Next;
                      }
              
                      return node.Value;
                  }
              
                  public void Reverse()
                  {
                      Node<T> prev = null;
                      var current = _head;
              
                      if (current == null)
                          return;
              
                      while (current != null)
                      {
                          var next = current.Next;
                          current.Next = prev;
                          prev = current;
                          current = next;
                      }
              
                      _head = prev;
                  }
              
                  public void ReverseRecursive()
                  {
                      reverseRecursive(_head, null);
                  }
              
                  private void reverseRecursive(Node<T> current, Node<T> prev)
                  {
                      if (current.Next == null)
                      {
                          _head = current;
                          _head.Next = prev;
                          return;
                      }
              
                      var next = current.Next;
                      current.Next = prev;
                      reverseRecursive(next, current);
                  }
              
                  public IEnumerator<T> Enumerator()
                  {
                      var current = _head;
                      while (current != null)
                      {
                          yield return current.Value;
                          current = current.Next;
                      }
                  }
              
                  public IEnumerator GetEnumerator()
                  {
                      return Enumerator();
                  }
              }
              
              public class Node<T>
              {
                  public T Value { get; set; }
                  public Node<T> Next { get; set; }
              }
              

              【讨论】:

                【解决方案12】:

                AddItemStart、AddItemEnd、RemoveItemStart、RemoveItemEnd和DisplayAllItems操作实现单链表的简单c#程序

                 using System;
                    using System.Collections.Generic;
                    using System.Linq;
                    using System.Text;
                    using System.Threading.Tasks;
                
                    namespace SingleLinkedList
                    {
                        class Program
                        {
                            Node head;
                            Node current;
                            int counter = 0;
                            public Program()
                            {
                                head = new Node();
                                current = head;
                            }
                            public void AddStart(object data)
                            {
                                Node newnode = new Node();
                                newnode.next = head.next;
                                newnode.data = data;
                                head.next = newnode;
                                counter++;
                            }
                            public void AddEnd(object data)
                            {
                                Node newnode = new Node();
                                newnode.data = data;
                                current.next = newnode;
                                current = newnode;
                                counter++;
                            }
                            public void RemoveStart()
                            {
                                if (counter > 0)
                                {
                                    head.next = head.next.next;
                                    counter--;
                                }
                                else
                                {
                                    Console.WriteLine("No element exist in this linked list.");
                                }
                            }
                            public void RemoveEnd()
                            {
                                if (counter > 0)
                                {
                                    Node prevNode = new Node();
                                    Node cur = head;
                                    while (cur.next != null)
                                    {
                                        prevNode = cur;
                                        cur = cur.next;
                                    }
                                    prevNode.next = null;
                                }
                                else
                                {
                                    Console.WriteLine("No element exist in this linked list.");
                                }
                            }
                            public void Display()
                            {
                                Console.Write("Head ->");
                                Node curr = head;
                                while (curr.next != null)
                                {
                                    curr = curr.next;
                                    Console.WriteLine(curr.data.ToString());
                                }
                            }
                            public class Node
                            {
                                public object data;
                                public Node next;
                            }
                            static void Main(string[] args)
                            {
                                Program p = new Program();
                                p.AddEnd(2);
                                p.AddStart(1);
                                p.AddStart(0);
                                p.AddEnd(3);
                                p.Display();
                                p.RemoveStart();
                                Console.WriteLine("Removed node from Start");
                                p.Display();
                                Console.WriteLine("Removed node from End");
                                p.RemoveEnd();
                                p.Display();
                                Console.ReadKey();
                            }
                        }
                    }
                

                【讨论】:

                • 超级简单的实现。 RemoveEnd() 需要这个:current = prevNode; counter--; 才能正常工作。 :)
                【解决方案13】:

                所选答案没有迭代器;它更基本,但可能没有那么有用。

                这里有一个迭代器/枚举器。我的实现是基于 Sedgewick 的包;见http://algs4.cs.princeton.edu/13stacks/Bag.java.html

                void Main()
                {
                    var b = new Bag<string>();
                    b.Add("bike");
                    b.Add("erasmus");
                    b.Add("kumquat");
                    b.Add("beaver");
                    b.Add("racecar");
                    b.Add("barnacle");
                
                    foreach (var thing in b)
                    {
                        Console.WriteLine(thing);
                    }
                }
                
                // Define other methods and classes here
                
                public class Bag<T> : IEnumerable<T>
                {
                    public Node<T> first;// first node in list
                
                    public class Node<T>
                    {
                        public T item;
                        public Node<T> next;
                
                        public Node(T item)
                        {
                            this.item = item;
                        }
                    }
                
                
                    public void Add(T item)
                    {
                        Node<T> oldFirst = first;
                        first = new Node<T>(item);
                        first.next = oldFirst;
                    }
                
                    IEnumerator IEnumerable.GetEnumerator()
                    {
                        return GetEnumerator();
                    }
                
                    public IEnumerator<T> GetEnumerator()
                    {
                        return new BagEnumerator<T>(this);
                    }
                
                    public class BagEnumerator<V> : IEnumerator<T>
                    {
                        private Node<T> _head;
                        private Bag<T> _bag;
                        private Node<T> _curNode;
                
                
                        public BagEnumerator(Bag<T> bag)
                        {
                
                            _bag = bag;
                            _head = bag.first;
                            _curNode = default(Node<T>);
                
                        }
                
                        public T Current
                        {
                            get { return _curNode.item; }
                        }
                
                
                        object IEnumerator.Current
                        {
                            get { return Current; }
                        }
                
                        public bool MoveNext()
                        {
                            if (_curNode == null)
                            {
                                _curNode = _head;
                                if (_curNode == null)
                                return false;
                                return true;
                            }
                            if (_curNode.next == null)
                            return false;
                            else
                            {
                                _curNode = _curNode.next;
                                return true;
                            }
                
                        }
                
                        public void Reset()
                        {
                            _curNode = default(Node<T>); ;
                        }
                
                
                        public void Dispose()
                        {
                        }
                    }
                }
                

                【讨论】:

                • 这里已经有其他答案有和迭代器,而且做得更好。为链表编写迭代器需要全部 4 行代码,而不是您这里的所有代码。
                • 你能告诉我这四行吗?你觉得哪个更好?
                • 好的。感谢您的帮助-您对我进行了巨魔并且没有具体回应。我看到一个实现 IEnumerable 的答案,它使用收益回报。那个更好吗?这个答案更简单吗?我会让其他人来评判。
                • 我发现它令人困惑......尤其是。因为 OP 明确要求简单、明确的实施。使用 yield 的迭代器更清晰、更简单,是支持迭代的标准方式。
                • 好的,当然。但这是您实现迭代器的方式。我想你指出了为什么引入了 yield 关键字。然而,对我来说,明确地看到它会更清楚。但是,如果您认为这样更简单,请使用关键字。
                【解决方案14】:

                我将摘录“Joseph Albahari 和 Ben Albahari 所著的 C# 6.0 in a Nutshell”一书

                下面是LinkedList的使用演示:

                var tune = new LinkedList<string>();
                tune.AddFirst ("do"); // do
                tune.AddLast ("so"); // do - so
                tune.AddAfter (tune.First, "re"); // do - re- so
                tune.AddAfter (tune.First.Next, "mi"); // do - re - mi- so
                tune.AddBefore (tune.Last, "fa"); // do - re - mi - fa- so
                tune.RemoveFirst(); // re - mi - fa - so
                tune.RemoveLast(); // re - mi - fa
                LinkedListNode<string> miNode = tune.Find ("mi");
                tune.Remove (miNode); // re - fa
                tune.AddFirst (miNode); // mi- re - fa
                foreach (string s in tune) Console.WriteLine (s);
                

                【讨论】:

                • OP 询问有关创建自定义 LinkedList 的问题,而您正在谈论 System.Collections.Generic 下可用的现成 LinkedList 对象。完全不同的主题。
                【解决方案15】:

                我创建了以下具有许多功能的 LinkedList 代码。它可在CodeBase github 公共回购下公开。

                类: NodeLinkedList

                Getter 和 Setter: FirstLast

                功能AddFirst(data), AddFirst(node), AddLast(data), RemoveLast(), AddAfter(node, data), RemoveBefore(node), Find(node), Remove(foundNode), Print(LinkedList)

                using System;
                using System.Collections.Generic;
                
                namespace Codebase
                {
                    public class Node
                    {
                        public object Data { get; set; }
                        public Node Next { get; set; }
                
                        public Node()
                        {
                        }
                
                        public Node(object Data, Node Next = null)
                        {
                            this.Data = Data;
                            this.Next = Next;
                        }
                    }
                
                    public class LinkedList
                    {
                        private Node Head;
                        public Node First
                        {
                            get => Head;
                            set
                            {
                                First.Data = value.Data;
                                First.Next = value.Next;
                            }
                        }
                
                        public Node Last
                        {
                            get
                            {
                                Node p = Head;
                                //Based partially on https://en.wikipedia.org/wiki/Linked_list
                                while (p.Next != null)
                                    p = p.Next; //traverse the list until p is the last node.The last node always points to NULL.
                
                                return p;
                            }
                            set
                            {
                                Last.Data = value.Data;
                                Last.Next = value.Next;
                            }
                        }
                
                        public void AddFirst(Object data, bool verbose = true)
                        {
                            Head = new Node(data, Head);
                            if (verbose) Print();
                        }
                
                        public void AddFirst(Node node, bool verbose = true)
                        {
                            node.Next = Head;
                            Head = node;
                            if (verbose) Print();
                        }
                
                        public void AddLast(Object data, bool Verbose = true)
                        {
                            Last.Next = new Node(data);
                            if (Verbose) Print();
                        }
                
                        public Node RemoveFirst(bool verbose = true)
                        {
                            Node temp = First;
                            Head = First.Next;
                            if (verbose) Print();
                            return temp;
                        }
                
                        public Node RemoveLast(bool verbose = true)
                        {
                            Node p = Head;
                            Node temp = Last;
                
                            while (p.Next != temp)
                                p = p.Next;
                
                            p.Next = null;
                            if (verbose) Print();
                
                            return temp;
                        }
                
                        public void AddAfter(Node node, object data, bool verbose = true)
                        {
                            Node temp = new Node(data);
                            temp.Next = node.Next;
                            node.Next = temp;
                
                            if (verbose) Print();
                        }
                
                        public void AddBefore(Node node, object data, bool verbose = true)
                        {
                            Node temp = new Node(data);
                
                            Node p = Head;
                
                            while (p.Next != node) //Finding the node before
                            {
                                p = p.Next;
                            }
                
                            temp.Next = p.Next; //same as  = node
                            p.Next = temp;
                
                            if (verbose) Print();
                        }
                
                        public Node Find(object data)
                        {
                            Node p = Head;
                
                            while (p != null)
                            {
                                if (p.Data == data)
                                    return p;
                
                                p = p.Next;
                            }
                            return null;
                        }
                
                        public void Remove(Node node, bool verbose = true)
                        {
                            Node p = Head;
                
                            while (p.Next != node)
                            {
                                p = p.Next;
                            }
                
                            p.Next = node.Next;
                            if (verbose) Print();
                        }
                
                        public void Print()
                        {
                            Node p = Head;
                            while (p != null) //LinkedList iterator
                            {
                                Console.Write(p.Data + " ");
                                p = p.Next; //traverse the list until p is the last node.The last node always points to NULL.
                            }
                            Console.WriteLine();
                        }
                    }
                }
                

                在她使用微软内置的LinkedList和LinkedListNode回答问题时使用@yogihosting回答,可以达到同样的效果:

                using System;
                using System.Collections.Generic;
                using Codebase;
                
                namespace Cmd
                {
                    static class Program
                    {
                        static void Main(string[] args)
                        {
                            var tune = new LinkedList(); //Using custom code instead of the built-in LinkedList<T>
                            tune.AddFirst("do"); // do
                            tune.AddLast("so"); // do - so
                            tune.AddAfter(tune.First, "re"); // do - re- so
                            tune.AddAfter(tune.First.Next, "mi"); // do - re - mi- so
                            tune.AddBefore(tune.Last, "fa"); // do - re - mi - fa- so
                            tune.RemoveFirst(); // re - mi - fa - so
                            tune.RemoveLast(); // re - mi - fa
                            Node miNode = tune.Find("mi"); //Using custom code instead of the built in LinkedListNode
                            tune.Remove(miNode); // re - fa
                            tune.AddFirst(miNode); // mi- re - fa
                 }
                }
                

                【讨论】:

                • 为什么需要 First 和 Head 节点?
                【解决方案16】:

                链表是一种基于节点的数据结构。每个节点设计有两个部分(数据和节点引用)。实际上,数据总是存储在数据部分(可能是原始数据类型,例如 Int、Float 等,或者我们也可以存储用户定义的数据类型,例如对象引用),类似地节点引用还应该包含对下一个节点的引用,如果没有下一个节点,则链将结束。

                这条链将一直持续到任何没有指向下一个节点的参考点的节点。

                请从我的技术博客-http://www.algonuts.info/linked-list-program-in-java.html找到源代码

                package info.algonuts;
                
                import java.util.ArrayList;
                import java.util.Arrays;
                import java.util.Iterator;
                import java.util.List;
                
                class LLNode {
                    int nodeValue;
                    LLNode childNode;
                
                    public LLNode(int nodeValue) {
                        this.nodeValue = nodeValue;
                        this.childNode = null;
                    }
                }
                
                class LLCompute {
                    private static LLNode temp;
                    private static LLNode previousNode;
                    private static LLNode newNode;
                    private static LLNode headNode;
                
                    public static void add(int nodeValue) {
                        newNode = new LLNode(nodeValue);
                        temp = headNode;
                        previousNode = temp;
                        if(temp != null)
                        {   compute();  }
                        else
                        {   headNode = newNode; }   //Set headNode
                    }
                
                    private static void compute() {
                        if(newNode.nodeValue < temp.nodeValue) {    //Sorting - Ascending Order
                            newNode.childNode = temp;
                            if(temp == headNode) 
                            {   headNode = newNode; }
                            else if(previousNode != null) 
                            {   previousNode.childNode = newNode;   }
                        }
                        else
                        {
                            if(temp.childNode == null)
                            {   temp.childNode = newNode;   }
                            else
                            {
                                previousNode = temp;
                                temp = temp.childNode;
                                compute();
                            }
                        }
                    }
                
                    public static void display() {
                        temp = headNode;
                        while(temp != null) {
                            System.out.print(temp.nodeValue+" ");
                            temp = temp.childNode;
                        }
                    }
                }
                
                public class LinkedList {
                    //Entry Point
                    public static void main(String[] args) {
                        //First Set Input Values
                        List <Integer> firstIntList = new ArrayList <Integer>(Arrays.asList(50,20,59,78,90,3,20,40,98));   
                        Iterator<Integer> ptr  = firstIntList.iterator();
                        while(ptr.hasNext()) 
                        {   LLCompute.add(ptr.next());  }
                        System.out.println("Sort with first Set Values");
                        LLCompute.display();
                        System.out.println("\n");
                
                        //Second Set Input Values
                        List <Integer> secondIntList = new ArrayList <Integer>(Arrays.asList(1,5,8,100,91));   
                        ptr  = secondIntList.iterator();
                        while(ptr.hasNext()) 
                        {   LLCompute.add(ptr.next());  }
                        System.out.println("Sort with first & Second Set Values");
                        LLCompute.display();
                        System.out.println();
                    }
                }
                

                【讨论】:

                  【解决方案17】:

                  我有一个双向链表,可以用作堆栈或队列。如果你查看代码并思考它的作用以及它是如何工作的,我敢打赌你会理解它的一切。很抱歉,但不知何故,我无法在这里找到完整的代码,所以我在这里是链接列表的链接(我也得到了解决方案中的二叉树):https://github.com/szabeast/LinkedList_and_BinaryTree

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2011-07-27
                    • 2016-07-16
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-06-16
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多