Сортировка выбором для связанного списка

Мы видели в классе, как алгоритм сортировки выбором работает со структурой данных массива. В этой лабораторной работе мы попрактикуемся в том, как можно выполнить сортировку выбором для АТД со связанными списками. 1. Преобразуйте следующий псевдокод сортировки выбором, чтобы выполнить сортировку в порядке возрастания. (функция selectionSort_asc) а. Найдите узел с минимальным значением в связном списке длины n b. Добавить узел min в новый связанный список результатов c. Удалить min из исходного связанного списка d. Повторяйте шаги a-c, пока исходный связанный список не станет пустым e. Вернуть связанный список результатов 2. Преобразовать следующий псевдокод сортировки выбором, чтобы выполнить сортировку в порядке убывания. (функция selectionSort_desc) а. Найдите узел с максимальным значением в связном списке длины n b. Добавить максимальный узел в новый связанный список результатов c. Удалить макс. из исходного связанного списка d. Повторяйте шаги a-c, пока исходный связанный список не станет пустым e. Вернуть связанный список результатов

Я попробовал этот код ниже, но он не дает мне правильного вывода.

public class Sort {
    public static void main(String[] args){
        Node head = initializeList("ilovedata"); 
        System.out.println("\n List Before selectionSort_asc");
        printList(head);
        head = selectionSort_asc(head);
        System.out.println("\n List After selectionSort_asc");
        printList(head);
        // Expected answer: -> a -> a -> d -> e -> i -> l -> o -> t -> v
        head = initializeList("ilovedata"); 
        System.out.println("\n List Before selectionSort_desc");
        printList(head);
        head = selectionSort_desc(head);
        System.out.println("\n List After selectionSort_desc");
        printList(head);
        // Expected answer: -> v -> t -> o -> l -> i -> e -> d -> a -> a
        }
        public static Node selectionSort_asc(Node head){ 
            Node result = null;

            Node curr, prev, min;
            while(head!=null) {
                curr = head;
                prev = null;
                min = head;
                while(curr.next!=null) {
                    curr = curr.next;
                    if(curr.item<min.item) {
                        prev = min;
                        min = curr;
                    }
                }
                //append the min at the end of result list
                Node add_min = new Node(min.item);
                if(result==null)
                    result = add_min;
                else {
                    Node last = result;
                    while(last.next!=null) {
                        last = last.next;
                    }
                    last.next = add_min;
                }
                //delete the min node form original list    
                if(min==head) {
                    head = head.next;
                }
                else if(min.next==null){
                    prev.next = null;
                }else {
                    prev.next = prev.next.next;
                    min.next = null;
                }
            }
            return result;
        }
        public static Node selectionSort_desc(Node head){ 
            Node result = null;

            Node curr, prev, max;           
            while(head!=null) {
                curr = head;
                prev = null;
                max = head;
                //find out the max node
                while(curr.next!=null) {
                    curr = curr.next;
                    if(curr.item>max.item) {
                        prev = max;
                        max = curr;
                    }
                }
                //add max to the end of result list             
                Node add_max = new Node(max.item);
                if(result==null) {
                    result = add_max;
                }
                else {
                    Node last = result;
                    while(last.next!=null) {
                        last = last.next;
                    }
                    last.next = add_max;
                }
                //delete min from original list
                if(max == head) {
                    head = head.next;
                }
                else if(max.next==null){
                    prev.next = null;
                }
                else {
                    prev.next = max.next;
                    max.next = null;
                }

            }           
            return result;
        }
        // Method that takes a string and insert its characters into a linked list
        public static Node initializeList(String str){ 
            Node head= new Node(str.charAt(0)),cur; 
            int i;
            for(cur= head,i=1;i<str.length();i++,cur=cur.next){ 
                cur.next = new Node(str.charAt(i));
            }       
            return head;
        }
        // Method for printing linked list 
        public static void printList(Node head){
               Node cur = head;
               if(head==null) 
                   System.out.print("<EMPTY>"); 
               for(;cur!=null;cur=cur.next){
                   System.out.print("-> "+cur.item+" ");
               }
        }
}

person Andrew Wen    schedule 14.07.2019    source источник
comment
Вывод этого кода: Список до выбораSort_asc -> i -> l -> o -> v -> e -> d -> a -> t -> a Список после selectionSort_asc -> a -> a -> d - › e-›i Список Перед выделениемSort_desc-›i-›l-›o-›v-›e-›d-›a-›t-›a Список После выбораSort_desc-›v-›t-›o-›l -> я   -  person Andrew Wen    schedule 15.07.2019


Ответы (1)


Проблема связана с назначением вашей переменной prev в этих фрагментах кода.

public static Node selectionSort_asc(Node head){ 
...
    if(curr.item><min.item) {
        prev = min;
        min = curr;
    }
...
}

public static Node selectionSort_desc(Node head){ 
...
    if(curr.item>max.item) {
        prev = max;
        max = curr;
    }
...
}

В настоящее время вы назначаете prev старому min и старому max, но в соответствии с дизайном вашего кода вы хотите, чтобы prev указывал на узел перед новым min и новым max с тем, как вы удаляете узел min из исходного связанного списка. Я рекомендую сохранить другой набор переменных с именами beforeMin и beforeMax и установить их равными текущему значению prev, когда вы найдете новый минимум или максимум. В дополнение к этому вы также должны обновлять свою переменную prev на каждой итерации цикла while так же, как вы делаете это для curr. Вот как это будет выглядеть для selectionSort_asc, и вы можете выяснить, как настроить метод убывания, чтобы отразить его:

public static Node selectionSort_asc(Node head){ 
    Node result = null;

    Node curr, prev, min, beforeMin;
    while(head!=null) {
        curr = head;
        prev = null;
        min = head;
        beforeMin = prev; // new variable
        while(curr.next!=null) {
            prev = curr; // update prev with each iteration
            curr = curr.next;
            if(curr.item<min.item) {
                beforeMin = prev; // variable points to the node before the min node
                min = curr;
            }
        }
        //append the min at the end of result list
        Node add_min = new Node(min.item);
        if(result==null)
            result = add_min;
        else {
            Node last = result;
            while(last.next!=null) {
                last = last.next;
            }
            last.next = add_min;
        }
        //delete the min node form original list    
        if(min==head) {
            head = head.next;
        }
        else if(min.next==null){
            beforeMin.next = null; // no more prev here
        }else {
            beforeMin.next = beforeMin.next.next; // notice how beforeMin is used now
            min.next = null;
        }
    }
    return result;
}
person Chris Gong    schedule 14.07.2019
comment
Это имеет смысл! Спасибо большое за вашу помощь! Мой код теперь работает правильно. - person Andrew Wen; 15.07.2019
comment
@AndrewWen в любое время, рад, что это помогло! - person Chris Gong; 15.07.2019