简体   繁体   English

将项目添加并排序到单链列表中

[英]adding and sorting items into a singly linked list

I am learning how to work with classes. 我正在学习如何上课。 I have made two classes and one is a list of cars. 我上了两堂课,一堂是汽车清单。 However, I need to modify the add function so that it will add cars sorted by price. 但是,我需要修改添加功能,以便它将添加按价格排序的汽车。 The problem I am having is that it will send the cheapest car to the beginning but kill the rest of the list. 我遇到的问题是,它将把最便宜的汽车送到起点,但杀死其余的汽车。 Here is my code for the add... 这是我添加的代码...

public void add_car(the_cars new_car)
        {// Method to add cars to list
            if (count == 0)
            {// If this is the first car 
                first = new_car;
                last = new_car;
                count = 1;
            }
            else
            {// If it is not the first car
                if (new_car.getPrice() < first.getPrice())
                {// If price of new car is lower than first car
                    last = first;
                    first = new_car; // new car becomes first car
                }
                else
                {
                    while (new_car.getPrice() > last.getPrice() || last.next != null)
                    {
                        last.next = new_car; // Null value now equal to car
                        last = new_car;
                    }
                }


                count++;

To insert an item into a singly linked list you need to: 要将项目插入单链列表,您需要:

  1. Change the previous nodes next (or first if it's the first item) to point to the new node. 改变以前的节点next (或first ,如果它的第一项),以指向新的节点。
  2. Change the next of the new item to be what next used to be for the item just before your new item. 更改next新项目将成为怎样的next使用的只是你的新项目之前的项目。 (You're not doing this in your code.) (您没有在代码中这样做。)

If you have a doubly linked list (it doesn't appear you do) you also need to: 如果您有一个双向链接列表(您似乎没有,则没有),您还需要:

  1. Change the current nodes previous to point to the node before you. 更改previous的当前节点以指向您之前的节点。
  2. Change the next node's previous to point to you. 更改下一个节点的previous以指向您。

Note that these operations may need to be done in an order other than what I've specified them here. 请注意,这些操作可能需要按照我在此处指定的顺序以外的顺序进行。

Since you also have a last pointer, you need to check if that needs to be updated and update it. 由于您还有last指针,因此需要检查是否需要更新并更新它。

Another problem that you have is that you're using last for adding anything after the first item. 您遇到的另一个问题是您正在使用last在第一项之后添加任何内容。 You...don't want to be doing that. 你...不想那样做。 You need to traverse the list, which will mean creating a new local variable to keep track of the current position. 您需要遍历列表,这意味着创建一个新的局部变量来跟踪当前位置。 As it is, your code is basically wiping out whatever was in last . 实际上,您的代码基本上清除了last

You have identified the cases correctly: 您已正确识别出案例:

  1. Is the list still empty? 列表是否仍然为空?
  2. Should the item be added at the beginning? 是否应在开始时添加项目?
  3. If not: after which item do we need to insert? 如果不是:我们需要在哪个项目之后插入?

You implemented the first case alright. 您实现了第一种情况。

The second case is wrong: Inserting in the beginning means to change the first element to new_car , but new_car.Next needs to point to the previous first element, otherwise you lose the link. 第二种情况是错误的:在开头插入意味着将第一个元素更改为new_car ,但是new_car.Next需要指向上一个第一个元素,否则将丢失链接。

The third case is also wrong: You need go towards the end of the list until either you've reached the last element (which is then the one you need to insert after) or until you find an element the successor of which has a greater price and insert after that. 第三种情况也是错误的:您需要转到列表的末尾,直到到达最后一个元素(然后是您需要在其后插入的元素),或者直到找到其后继元素更大的元素为止。价格,然后插入。

The reason why I can put the while condition like that is that if current != last I can be sure that there's a current.Next , otherwise it would be last by definition. 之所以可以设置while条件,是因为如果current != last我可以确定存在current.Next ,否则就可以定义为last The reason I need a temporary iteration element is that if I modify first I lose the entry point to the list. 我需要一个临时迭代元素的原因是,如果我first修改,则会丢失列表的入口点。

If have not tested the following code, but it should give you a clue and if it doesn't work, single-step debugging will help you. 如果尚未测试以下代码,但应该可以为您提供一个线索,如果它不起作用,则单步调试将为您提供帮助。

public void add_car(the_cars new_car)
{// Method to add cars to list
    if (count == 0)
    {// If this is the first car 
        first = new_car;
        last = new_car;
        count = 1;
    }
    else
    {// If it is not the first car
        if (new_car.getPrice() < first.getPrice())
        {// If price of new car is lower than first car
            new_car.Next = first; // Insert the first car as the first element
            first = new_car;
        }
        else
        {
            // Create temporary iteration element
            the_cars current = first;

            // Find the car
            while (current != last && new_car.getPrice() >= current.Next.getPrice())
                current = current.Next;

            // Insert after the given element
            new_car.Next = current.Next;
            current.Next = new_car;

            // Also you may need to update last to match the new end
            if (current == last)
                last = new_car;
        }

        count++;
    }
}

If you would like to use the LinkedList Class , here is a sample implementation based on your scenario: 如果您想使用LinkedList类 ,这是基于您的方案的示例实现:

class CarList : LinkedList<Car>
{
    public void AddCar(Car newCar)
    {
        if (this.Count == 0)
        {
            AddFirst(newCar);
        }
        else
        {
            var referenceCar = Find(this.OrderByDescending(i => i.Price).Where(i => newCar.Price > i.Price).FirstOrDefault());
            if (referenceCar == null)
            {
                AddBefore(First, newCar);

            }
            else
            {
                this.AddAfter(referenceCar, newCar);
            }
        }
    }
}

class Car
{
    public int Price { get; set; }
    public Car(int price)
    {
        Price = price;
    }
}

static void Main(string[] args)
{
    var list = new CarList();
    list.AddCar(new Car(20000));
    list.AddCar(new Car(10000));
    list.AddCar(new Car(15000));

    foreach (var item in list)
    {
        Console.WriteLine("Price {0}", item.Price);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM