【问题标题】:Simple List Merge C# (Without Generics)简单列表合并 C#(无泛型)
【发布时间】:2018-10-24 11:46:58
【问题描述】:

我从头开始创建了一个简单的列表类。这是一个我已经做了大约一周的课堂作业——对列表来说非常新。我们不能使用泛型,所以试图研究我下面的问题并没有取得成果。虽然我确实在 youtube 上观看了 BetterCoder 的 7 个教程,并且在我的书中找到了一些东西,但没有任何“合并”示例。

我有三个类 - 我的节点、我的列表和我的程序。在我的列表类中,我正在构建一个 Merge() 方法,该方法最终将比较两个列表中的数据并将它们合并到一个有序列表中。

现在,由于某种原因,我的 Merge 方法 - 这是帮助我了解正在发生的事情的非常基本的方法 - 无法正常工作。它有两个列表都传递给它,并且正在将 listTwo 中的数据添加到 listOne 但由于某种原因,当它打印到控制台时,第二个节点的数据显示了两次:

EX: 1 -> 2 -> 2

而不是打印头 (1),下一个 (2),然后是下一个 (3),它应该是。

EX: 1 -> 2 -> 3

在程序类中,我已经用 (listOne.firstNode.Next.Next.Data) = 3 的写行证明了这一点。它应该是。

谁能帮我弄清楚列表一中的节点是否没有正确指向彼此或发生了什么?

  • 我的合并方法必须同时传递两个列表对象(listOne 和 listTwo),最终我需要将它们作为引用传递,但我还没有完全弄清楚这一点,我想稍后会专注于这一点。

        namespace LinkedList
            {
      //This is my Node Class
                class Node
                {
                    public object Data { get; set; }
    
                    public Node Next { get; set; }
    
                    public Node(object dataValue) : this(dataValue, null) { }
    
                    public Node(object dataValue, Node nextNode)
                    {
                        Data = dataValue;
                        Next = nextNode;
                    }
                }
    
    
    
            //This is my List Class
    
                class List
                {
                    public Node firstNode;
                    public int count;
    
                    public List()
                    {
                        firstNode = null;
                    }
    
                    public bool Empty
                    {
                        get { return this.count == 0; }
                    }
    
                    public int Count
                    {
                        get { return this.count; }
                    }
    
                    public object Add(int index, object o)
                    {
                        if (index < 0)
                            throw new ArgumentOutOfRangeException("Index: " + index);
    
                        if (index > count)
                            index = count;
    
                        Node current = this.firstNode;
    
                        if (this.Empty || index == 0)
                        {
                            this.firstNode = new Node(o, this.firstNode);
                        }
                        else
                        {
                            for (int i = 0; i < index - 1; i++)
                                current = current.Next;
    
                            current.Next = new Node(o, current.Next);
                        }
    
                        count++;
    
                        return o;
                    }
    
                    public object Add(object o)
                    {
                        return this.Add(count, o);
                    }
    
                    public object Merge(List a, List b)
                    {
                        a.Add(b.firstNode.Data);
    
                        return a;
                    }
    
                    public void Print()
                    {
                        while (this.count > 0)
                        {
                            Console.Write(firstNode.Data + "->");
    
                            if(firstNode.Next != null)
                            firstNode.Data = firstNode.Next.Data;
    
                            count--;
                        }
    
                    }
    
                }
    
    
            //And here is my Program
    
                class Program
                {
    
                    static void Main(string[] args)
                    {
                        List listOne = new List();
    
                        List listTwo = new List();
    
                        listOne.Add(1);
                        listOne.Add(2);
    
                        listTwo.Add(3);
    
    
                        listTwo.Print();
    
                        Console.WriteLine("");
    
    
                        listOne.Merge(listOne, listTwo);
    
                        Console.WriteLine("");
    
                        listOne.Print();
    
                        //This line below shows that the data "3" from listTwo is being added to listOne in the list Merge Method
          //Console.WriteLine(listOne.firstNode.Next.Next.Data);
    
                        Console.ReadKey();
                    }
                }
       }
    

【问题讨论】:

  • 在你的程序主方法中,将这一行listOne.Merge(listOne, listTwo);改为listOne = listOne.Merge(listOne, listTwo);
  • 在Print()方法中,firstNode.Data = firstNode.Next.Data的作用是什么?
  • @Paul Karam 我刚试过这个 - 我收到一个错误:“无法将类型 'object' 隐式转换为 'LinkedList.List' ..你是否缺少演员表?:我不确定我会把任何东西都投给..
  • @Andrew Morton 好吧,我关注了我在 youtube 上找到的视频,我的理解是,当将某些内容插入列表时,它会导致第一个节点停止指向下一个节点,这会使指针再次出现......我完全错了吗?
  • @BrookeCobb 是的,你需要转换它,因为该方法返回一个object,所以它更有可能是listOne = (List)listOne.Merge(listOne, listTwo);,但无论如何,这似乎不是你的问题。这是一个快速浏览的问题。

标签: c# merge singly-linked-list


【解决方案1】:

您的打印方法中的实际问题

    public void Print()
    {
        Node node = firstNode;
        for (int i = 0; i < this.count; i++)
        {
            Console.Write(node.Data + "->");

            if (node.Next != null)
                node = node.Next;
        }
    }

Alex Sikilinda,你说得对,merge 方法不完整。

        public object Merge(List a, List b)
    {
        Node bNode = b.firstNode;
        while (bNode != null)
        {
            a.Add(bNode.Data);
            bNode = bNode.Next;
        }

        return a;
    }

【讨论】:

  • 似乎这里有一点,因为 op 实际上是在改变类中的内部值并将其搞砸
  • 非常感谢。我已经更正了我的 Print 方法。
  • @BrookeCobb 如果您认为这是预期的正确答案,请标记它。
  • 它并没有修复 Merge 方法。
  • @Baskar John - 抱歉,我试图标记它,但我在网站上没有足够的声誉。我收到了一个弹出消息,指出它仍然被计算在内,但它不会公开显示。我还是新来的..
【解决方案2】:

我会这样写:

public void Merge(List b)
{
    Node lastNode = GetLastNode();

    if (lastNode != null)
    {
        lastNode.Next = b.firstNode;
    }
    else 
    {
        this.firstNode = b.firstNode;
    }
}

// this method is used to find the last node in current list
private Node GetLastNode()
{
    if (this.firstNode == null)
    {
        return null;
    }

    Node current = this.firstNode;

    while (current.Next != null)
    {
        current = current.Next;
    }

    return current;
}

首先,我将 Merge 的签名从 public object Merge(List a, List b) 更改为 public void Merge(List b)。现在我们可以这样使用它:

listOne.Merge(listTwo);

这会将listOne的最后一个元素与listTwo的第一个元素链接起来,从而将它们合并。

现在我们需要更改Print 方法,因为当前版本修改了列表,这不应该发生:

public void Print()
{
    Node currentNode = this.firstNode;

    while(currentNode != null)
    {
        Console.Write(currentNode.Data + ' ');
        currentNode = currentNode.Next;
    }
}

【讨论】:

  • 非常感谢这个例子。我可以将此应用于传递两个列表对象的方法然后正确吗?我现在正在尝试看看会发生什么。我书中的字面问题是这样的:“编写一个程序,将两个整数有序列表对象合并为一个整数有序列表对象。ListMerge 类的方法合并应该接收对每个要合并的列表对象的引用,并且应该返回对合并列表对象的引用。”我一直在尝试将问题分解为多个部分并解决制作列表,然后打印,然后合并,然后引用..
  • 根据问题的描述,您似乎实际上不应该修改您传递的列表,而是创建一个包含所有值的新列表。
  • 好吧,这看起来很可行。我现在将致力于此。非常感谢您的指导。我希望像我这样的其他新手发现这个帖子很有用。
【解决方案3】:

我没有将数据分配回第一个节点,而是分配了

 firstNode = firstNode.Next;

请检查下面的打印代码

     public void Print()
    {
        while (this.count > 0)
        {
            Console.Write(firstNode.Data + "->");

            if (firstNode.Next != null)
                firstNode = firstNode.Next;

            count--;
        }

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 1970-01-01
    • 2010-12-06
    • 2015-05-05
    • 1970-01-01
    相关资源
    最近更新 更多