【问题标题】:Sortable linked list of objects对象的可排序链表
【发布时间】:2011-10-01 22:24:01
【问题描述】:

对于学校实验室,我必须制作一个消息链接列表,然后按优先级对这些消息进行排序,首先取出“高”优先级,然后是中优先级,然后是低优先级。几天来我一直试图弄清楚这一点,但我无法将注意力集中在排序上。我一直试图让它排序,而不是在我的 ListofMessages 类中添加头部和大小字段以外的任何内容,但我似乎所做的只是添加垃圾代码。我想自己解决这个问题,但现在我被难住了。

这是我目前所拥有的。希望你能理解它:

class ListOfMessages
{
    private int m_nSize;
    public Message m_cListStart;
    //public Message m_cNextItem;
    public Message m_cLastItem;

    public ListOfMessages()
    {
        m_nSize = 0;
        m_cListStart = null;
        //m_cNextItem = null;
    }

    public int Count
    {
        get { return m_nSize; }
    }       

    public string Display(Message cMessage)
    {
        return "Message: " + cMessage.m_strMessage + "\nPriority: " + cMessage.m_strPriority;
    }

    //list additions
    public int Add(Message newMessage)
    {
        Message nextMessage = new Message();
        //inserts objects at the end of the list
        if (m_nSize == 0)
        {
            m_cListStart = newMessage;
                //m_cLastItem = newMessage;
        }
        else
        {
            Message CurrentMessage = m_cListStart;

            if (newMessage.m_strPriority == "High")
            {

                    if (m_cListStart.m_strPriority != "High")
                    {
                        //Make the object at the start of the list point to itself
                        CurrentMessage.m_cNext = m_cListStart;
                        //Replace the object at the start of the list with the new message
                        m_cListStart = newMessage;

                    }
                else
                {
                    Message LastMessage = null;

                    for (int iii = 0; iii < m_nSize; iii++)//(newmessage.m_strpriority == iii.m_strpriority)
                    //&& (iii.m_cnext == null);)
                    {
                        if (m_cListStart.m_strPriority != "High")
                        {
                            nextMessage = newMessage;
                            nextMessage.m_cNext =
                            CurrentMessage = nextMessage;
                            //LastMessage.m_cNext = CurrentMessage;
                        }
                        LastMessage = CurrentMessage;

                        if (m_cListStart.m_cNext != null)
                            m_cListStart = m_cListStart.m_cNext;
                    }
                }
                //iii = iii.m_cnext;
            }
                    // for (int iii = m_cListStart; ; iii = iii.m_cNext)//(newMessage.m_strPriority == iii.m_strPriority)
                    //    //&& (iii.m_cNext == null);)
                    //{
                    //    //Message lastMessage = iii;
                    //    if (iii.m_strPriority != iii.m_strPriority)
                    //    {
                    //        //iii.m_cNext = newMessage;
                    //        newMessage.m_cNext = iii.m_cNext;
                    //        iii.m_cNext = newMessage;
                    //    }


                    //m_cLastItem.m_cNext = newMessage;
        }
            //m_cLastItem = newMessage;
            return m_nSize++;
    }

    public Message Pop()
    {
        //Message Current = m_cListStart;
        //if the object at the start of the list has another object after it, make that object the start of the list
        //and decrease the size by 1 after popping an object off if there is more than 1 object after the start of the list
        if (m_cListStart.m_cNext != null)
        {
            m_cListStart = m_cListStart.m_cNext;
        }
        if (m_nSize > 0)
            m_nSize--;
        else
            m_cListStart = null;
        return m_cListStart;
        //if (m_cListStart.m_cNext != null)
        //    m_cListStart = m_cListStart.m_cNext;
        //if (m_nSize > 1)
        //    m_nSize--;
        //return m_cListStart;
    }

我检索消息的 pop 函数可能需要一些改进,但现在大部分工作都在 Add 函数中。我真的只是在黑暗中跌跌撞撞。

有谁知道按照我的要求做的简单方法?

【问题讨论】:

  • 我把我的乱码扔给你。
  • 你会被那个代码折磨自己,首先尝试了解链表的工作原理并查看一些代码示例。
  • 您应该考虑的另一件事是列表是否主要用于插入元素,然后是单个排序,然后是删除元素。或者如果插入和删除将混合使用。如果它会被混合,您可以通过按其排序顺序插入元素来维护排序的列表。由于您的列表将始终进行排序,因此还可以使您不必执行排序。
  • 为什么每个人都试图避免排序?排序有什么问题?你只是想破解它并让它工作吗?让他学习。
  • @user177883,排序(相对)慢。如果时间复杂度很重要(在这里似乎很重要)并且您可以在线性时间内解决某些问题,那么该解决方案比排序要好得多。

标签: c# visual-studio-2010 sorting linked-list


【解决方案1】:

你为什么不写一个自定义的链表如下:

class Node<T> : IComparable<T>
{
   public int Priority {set;get;}
   public T Data {set;get;}
   public Node<T> Next {set;get;}
   public Node<T> Previous {set;get;}

   // you need to implement IComparable here for sorting.
}

这是您的节点定义。现在我们需要实现一个 LinkedList 类。

您的链表类可以是双向链表,因为您没有任何规范。使用双向链表会更容易。

这是定义:

class LinkedList<T> : IEnumerable<T> where T: IComparable
{
    public Node<T> Head {set;get;}
    public Node<T> Tail {set;get;}

    // set of constructors
    //.....

    public void Insert(Node<T> node)
    {
       // you can do recursive or iterative impl. very easy.
    }

    // other public methods such as remove, insertAfter, insert before, insert last etc.

    public void Sort()
    {
       // easiest solution is to use insertion sort based on priority.
    }

}

如果您可以通过创建额外的内存来摆脱困境,即:另一个链表。插入排序会很好。为此,您还需要实现 insert after 功能。

我有一个LinkedList 实现,你可以看看。只需要实现基于优先级的排序,可以使用冒泡排序、插入排序或归并排序。

另外,您可能想查看可用于实现优先级队列的堆,它可以达到目的。我有一个Heap Data Structure 实现,你可以看看。

【讨论】:

  • 我从来没有真正做过这样的事情。您能否提供更多详细信息或链接来帮助解释您所指的内容?
  • 我们的老师没有教我们任何关于你提到的东西:(
  • @Greener,上面的代码所做的是创建一个扩展IComparableNode 对象。一个节点基本上就是你的链接,在链表中,它指向上一个和下一个节点。然后,您的列表类将根据您为其设置的任何优先级来排列这些节点。对于这个特定场景,我能想到的最佳解决方案是创建一个通用链表,然后根据优先级插入和删除元素。要了解有关如何执行此操作的更多信息,请搜索链接列表实现。这样一来,您甚至不需要外部排序机制。
【解决方案2】:

最简单的解决方案是拥有三个单链表,每个优先级一个。

添加时,您添加到正确列表的末尾。删除时,您首先尝试从最高优先级列表中删除。如果那是空的,请尝试中间的。如果那是空的,请使用最低的列表。

如果优先级数量恒定,则两种情况下的时间复杂度都是 O(1)。

【讨论】:

  • 如果有 10 个优先级怎么办?还是 N 个优先事项?
  • @user177883,这个问题具体说有三个优先事项。如果有 N 个优先级,你仍然可以使用这个解决方案,但它不再是 O(1)。
  • @user177883:当您的程序需要处理 10 或 N 个优先级时,您可以实现该要求。程序员往往难以预测他们的代码在未来将如何使用。
  • @svick 如果允许他这样做,那么您的解决方案将是最简单的方法。
猜你喜欢
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
相关资源
最近更新 更多