Stephen Cavender
Stephen Cavender

Reputation: 3

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++;

Upvotes: 0

Views: 1836

Answers (3)

Alex Filipovici
Alex Filipovici

Reputation: 32561

If you would like to use the LinkedList Class, here is a sample implementation based on your scenario:

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);
    }
}

Upvotes: 0

Thorsten Dittmar
Thorsten Dittmar

Reputation: 56707

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.

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. The reason I need a temporary iteration element is that if I modify first I lose the entry point to the list.

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++;
    }
}

Upvotes: 0

Servy
Servy

Reputation: 203835

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.
  2. Change the next of the new item to be what next used to be for the item just before your new item. (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.
  2. Change the next node's previous to point to you.

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.

Another problem that you have is that you're using last for adding anything after the first item. 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.

Upvotes: 3

Related Questions