链表的选择排序

时间:2019-07-14 21:31:52

标签: java singly-linked-list selection-sort

我们在课堂上已经看到选择排序算法如何处理数组数据结构。在本实验中,我们将练习如何对链表ADT执行选择排序。 1.转换以下选择排序伪代码,以升序执行排序。 (selectionSort_asc函数) 一种。在长度为n的链表中找到最小值的节点 b。将min节点追加到新的结果链接列表中 C。从原始链接列表中删除分钟 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+" ");
               }
        }
}

1 个答案:

答案 0 :(得分:0)

问题与这些代码段中的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节点的方式。我的建议是保留另一组名为beforeMinbeforeMax的变量,并在找到新的最小值或最大值时将其设置为等于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;
}