кодирование с односвязным списком и пузырьковой сортировкой в ​​java

У меня проблема с моим кодом, я создал класс односвязного списка, в котором вы можете добавлять, удалять, изменять, объединять и т. д., однако я пытаюсь выполнить простую пузырьковую сортировку и столкнулся с проблемами, в которых список не правильно отсортировано. вот некоторые вещи, чтобы отметить:

  • это пользовательская реализация связанного списка
  • узлы односвязного списка содержат 2 вещи: объект CustomerFile со всеми данными для клиента и указатель «следующий» узел на следующий элемент в списке
  • список отсортирован в порядке возрастания (A-Z) по фамилии, хранящейся в клиентском файле каждого узла
  • функция добавления записи вставляет узлы в правильное положение в списке, так что список не нужно сортировать изначально - однако, если фамилия изменена, как часть программы, список необходимо сортировать снова
  • Я бы предпочел не создавать новый список и повторно использовать эту запись вставки в этом списке, чтобы создать новый список, поскольку это интенсивно использует память, и моя задача - быть максимально эффективной.
  • сама структура связанного списка не может быть изменена - это решено и я слишком далеко, чтобы изменить что-то вроде массива
  • список имеет головной узел, в нем есть следующие элементы, но нет хвостового узла. Он имеет назначенный NULL следующий указатель, чтобы указать конец списка

код

public static void sortList()
{
    if (isEmpty() == true)
    {
        System.out.println("Cannot sort - the list is empty");
    }
    else if (getHead().getNext() == null)
    {
        System.out.println("List sorted");
    }
    else
    {
        Node current = getHead().getNext();
        CustomerFile tempDat;
        boolean swapDone = true;
        while (swapDone)
        {
            current = getHead().getNext();
            swapDone = false;
            while (current != null)
            {
                if (current.getNext() != null &&
                    current.getData().getSurname().compareTo(
                        current.getNext().getData().getSurname()) >0)
                {
                    tempDat = current.getData();
                    current.setData(current.getNext().getData());
                    current.getNext().setData(tempDat);
                    swapDone = true;
                }
                current = current.getNext();
            }
        }
        if (getHead().getData().getSurname().compareTo(
            getHead().getNext().getData().getSurname()) >0)
        {
            current = getHead().getNext();
            getHead().setNext(current.getNext());
            setHead(current);
        }
    }
}

буду признателен за отзыв


person Lukeg101    schedule 21.12.2012    source источник
comment
Действительно ли этот метод статичен и не имеет аргументов? Как вы получаете список, который вы сортируете?   -  person Don Roby    schedule 22.12.2012
comment
он находится внутри самого класса односвязного списка вместе с другими методами, используемыми списком - метод getHead() позволяет вам получить заголовок списка, и тогда он работает оттуда   -  person Lukeg101    schedule 22.12.2012
comment
Каким образом ваш список не отсортирован? 14358 -> 14358? 14358 -> 13485? 14358 -> 81345?   -  person Mike Rylander    schedule 22.12.2012
comment
старый список Джей Гэтсби, Боб Марли, Джон Смит, Зигги Стардаст изменяет фамилию Джей Гэтсби на Тернер новый список Боб Марли, Джей Тернер, Джон Смит, Зигги Стардаст зацикливается только один раз и перераспределяет один узел   -  person Lukeg101    schedule 22.12.2012
comment
Это не чувствительно к регистру, так как фамилии хранятся заглавными буквами.   -  person Lukeg101    schedule 22.12.2012


Ответы (3)


Ваш код представляет собой странную смесь, в основном обменивающую данные, но специально обрабатывающую голову, пытаясь поменять ее местами со следующей, переключая ссылки.

Как отмечено в другом ответе, этот последний обмен реализован неправильно, но на самом деле нет причин специально обрабатывать голову, если вы делаете что-то, меняя данные.

Все, что вам нужно сделать, это начать каждый обход списка с головы во внешнем цикле.

Это дает рабочее решение:

public void sortList()
{
    if (isEmpty())
    {
        System.out.println("An empty list is already sorted");
    }
    else if (getHead().getNext() == null)
    {
        System.out.println("A one-element list is already sorted");
    }
    else
    {
        Node current = getHead();
        boolean swapDone = true;
        while (swapDone)
        {
            swapDone = false;
            while (current != null)
            {
                if (current.getNext() != null && current.getData().getSurname().compareTo(current.getNext().getData().getSurname()) >0)
                {
                    CustomerFile tempDat = current.getData();
                    current.setData(current.getNext().getData());
                    current.getNext().setData(tempDat);
                    swapDone = true;
                }
                current = current.getNext();
            }
            current = getHead();
        }
    }
}

Я сделал это нестатичным, потому что, как отмечалось в комментариях, мне было непонятно, как ваш может работать как статический. Вы можете сделать его статичным в вашем контексте.

Я также изменил пару других мелких вещей. Никогда не нужно проверять условие по коду вроде

if (isEmpty() == true)

В Java это полностью эквивалентно

if (isEmpty())

И tempDat не нужно объявлять за пределами того места, где оно используется.

person Don Roby    schedule 22.12.2012

Я думаю, что главная проблема здесь в том, что вы начинаете с

current = getHead().getNext()

С помощью этого кода вы полностью исключите голову из процесса сортировки, и может случиться так, что данные здесь должны перейти на другой конец списка, но в этом случае это всегда будут либо данные в голове элемент или быть данными непосредственно после головного узла (последнее связано с вашим оператором if в конце).

Вместо этого попробуйте начать с начала списка и посмотрите, что получится.

person dbriggs    schedule 21.12.2012

Вы не включаете голову в свою сортировку.

public static void sortList()
{
    if (isEmpty() == true)
    {
        System.out.println("Cannot sort - the list is empty");
    }
    else if (getHead().getNext() == null)
    {
        System.out.println("List sorted");
    }
    else
    {
        Node current = getHead();
        // Node current = getHead().getNext();
        CustomerFile tempDat;
        boolean swapDone = true;
        while (swapDone)
        {
            current = getHead().getNext();
            swapDone = false;
            while (current != null)
            {
                if (current.getNext() != null && current.getData().getSurname().compareTo(current.getNext().getData().getSurname()) >0)
                {
                    tempDat = current.getData(); // td -> objectA, cd -> objectA
                    current.setData(current.getNext().getData()); // cd -> objectB
                    current.getNext().setData(tempDat); // nd -> td -> objectA
                    swapDone = true;
                }
                current = current.getNext();
            }
        }
        //if (getHead().getData().getSurname().compareTo(getHead().getNext().getData().getSurname()) >0)
        //{
        //  current = getHead().getNext(); // current -> head+1
        //  getHead().setNext(current.getNext()); //head+1 -> head+2
        //  setHead(current); // head -> head+1
        //}
    }
}

Также есть ошибка в закомментированном коде выше. Применение этого кода удаляет узел.

// list: a -> b -> c -> d
current = getHead().getNext(); // current = b
getHead().setNext(current.getNext()); // a -> c 
setHead(current); // head = b
// list: b -> c -> d
// and nothing points to 'a' anymore

Вместо того, чтобы обменивать данные, вы должны попробовать поменять местами узлы. Если вы пойдете по этому пути, вы должны найти лучшее решение.

person Mike Rylander    schedule 21.12.2012