【问题标题】:Queue Implementation using Linked List: C#使用链表实现队列:C#
【发布时间】:2020-04-17 03:56:12
【问题描述】:

我正在学习数据结构。今天,我想用链表来实现队列。因为我们有队列入口点的 FRONT 和 REAR 第一个索引。如果有人要求我使用 Linked List 实现 Queue,请确认我的以下实现(我能够在没有 REAR 对象的情况下实现 Queue 目标。)

这个实现有效吗?

class Queue
{
    Node head;
    class Node
    {
        public int Value;
        public Node next;

        public Node()
        {
            next = null;
        }
    }

    public void addElement(int val)
    {
        if (head == null)
        {
            Node temp = new Node();
            temp.Value = val;
            head = temp;
            return;
        }

        Node tempNode = head;
        while (tempNode.next != null)
        {
            tempNode = tempNode.next;
        }

        Node newElement = new Node();
        newElement.Value = val;
        tempNode.next = newElement;
    }

    public void Dequeue()
    {
        if (head != null)
        {
            if (head.next != null)
            {
                head = head.next;
                return;
            }
            head = null;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Queue queue = new Queue();
        queue.addElement(10);
        queue.addElement(20);
        queue.addElement(30);
        queue.addElement(40);

        queue.Dequeue();
        queue.Dequeue();
        queue.Dequeue();
        queue.Dequeue();
    }
}

【问题讨论】:

  • 您应该将其发布到 Code Review。
  • 这里的原因:我想确认我们是否需要在实现队列时同时实现 FRONT 和 REAR。
  • 你不需要需要,就像你不需要链表来创建队列一样。但是两者都改变​​了事情,一个人应该知道有或没有两者会发生什么。例如性能/时间复杂度。
  • 好的。我得到了它。谢谢@SamiKuhmonen

标签: c# data-structures collections linked-list queue


【解决方案1】:

好吧,如果我们想要有 frontrear 两端,让我们拥有它们:

private Node m_Head;
private Node m_Tail;

你只有一个Node head; 字段,这就是为什么你的实现至少效率低:你有O(N) 的时间复杂度到addElement

...
while (tempNode.next != null)
{
    tempNode = tempNode.next;
}
...

当你可以轻松拥有O(1)

我建议使用 典型 名称,例如 Enqueue 而不是 addElement 并使用 Try 方法(通常,如果队列为空,我们不希望出现异常)。最后,让我们使用泛型:MyQueue<T> 其中T 是项目的类型。

public class MyQueue<T> {
  private class Node {
    public Node(Node next, T value) {
      Next = next;
      Value = value;
    }

    public Node Next { get; internal set; }
    public T Value { get; }
  }

  private Node m_Head;
  private Node m_Tail;

  public void Enqueue(T item) {
    Node node = new Node(null, item);

    if (m_Tail == null) {
      m_Head = node;
      m_Tail = node;
    }
    else {
      m_Tail.Next = node;
      m_Tail = node;
    }
  }

  public bool TryPeek(out T item) {
    if (m_Head == null) {
      item = default(T);

      return false;
    }

    item = m_Head.Value;

    return true;
  }

  public T Peek() {
    if (m_Head == null)
      throw new InvalidOperationException("Queue is empty.");

    return m_Head.Value;
  }

  public bool TryDequeue(out T item) {
    if (m_Head == null) {
      item = default(T);

      return false;
    }

    item = m_Head.Value;
    m_Head = m_Head.Next;

    return true;
  }

  public T Dequeue() {
    if (m_Head == null)
      throw new InvalidOperationException("Queue is empty.");

    T item = m_Head.Value;
    m_Head = m_Head.Next;

    return item;
  }
}

【讨论】:

  • 感谢您的回复。我有一个问题:TryDequeue 和 TryPeek 有什么用。
  • @KiddoDeveloper:如果我们不希望 exception 被抛出空队列,我们​​可以放置,例如,TryDequeueif (nyQueue.TryDequeue(out item)) {/* success*/} else {/*queue is empty*/}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 2011-06-28
  • 2021-05-20
  • 1970-01-01
  • 2020-02-10
相关资源
最近更新 更多