给定一个无序单链表的头节点head,实现单链表的选择排序

要求额外空间复杂度O(1)

思路:

既然额外空间复杂度O(1),就不能把链表装进容器,排好序后再从新链接,而是要求面试者在原链表上利用有限几个变量完成选择排序的过程。

  选择排序是从未排序的部分找到最小值,然后放到排好序部分的尾部。

 

   1 开始时默认真个链表都是未排序的部分,对于找到的最小值节点肯定是整个链表的最小值节点,将其设置为新的头节点记:newHead

   2 每次在排序的部分中找到最小值的节点,然后哦把这个节点从未排序的链表删除,删除的过程保证未排序的不能断开

   3 把删除的节点链接到排好序的后面

   4 全部过程处理完后,整个链表已经有序,返回newHead

 

package TT;

public class Test111 {

    public static class Node{
         public int value;
         public Node next;
         
         public Node(int data){
             this.value=data;
         }
    }
    
    
    public static Node selectionSort(Node head){
        
        Node tail=null;
        Node cur = head;
        
        Node smallPre = null;
        Node small=null;
        
        while(cur !=null){
            small=cur;
            smallPre=getSmallestPreNode(cur);
            if(smallPre !=null){
                small = smallPre.next;
                smallPre.next=small.next;  //删除掉
            }
            cur=cur==small ? cur.next :cur;   //看看当前的值是不是最小的那个
            if(tail==null){
                head=small;  //第一个
            }else {
                tail.next=small;
            }
            tail=small;  //更新下尾部
        }
          return head;
    }
     
    public static Node getSmallestPreNode(Node head){
        
          Node smallPre=null;
          Node small=head;
          Node pre = head;
          Node cur=head.next;
        
        while(cur!=null){
            if(cur.value <small.value){
                smallPre=pre;
                small=cur;
            }
            pre=cur;
            cur=cur.next;
        }
        return smallPre;
    }
    
    
    
}