程序员代码面试指南第二版 27.单链表的选择排序
题目描述
给定一个无序单链表,实现单链表的选择排序(按升序排序)。
输入描述:
第一行一个整数 n,表示单链表的节点数量。
第二行 n 个整数 val 表示单链表的各个节点。
输出描述:
在给出的函数内返回给定链表的头指针。
示例1
输入
5
1 3 2 4 5
输出
1 2 3 4 5
第一次做; 选择排序思想: 从未排序区域找出最小值, 将最小值放到排序区域的最后, 当未排序区域为空时, 元素全部有序; 这道题最麻烦的地方在于指针的操作以及循环条件, 考验代码功底, 要小心不能写错
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc.nextLine());
if(n<1)
return;
String[] str = sc.nextLine().split(" ");
ListNode head = new ListNode(Integer.parseInt(str[0]));
ListNode curr = head;
for(int i=1; i<n; i++){
curr.next = new ListNode(Integer.parseInt(str[i]));
curr = curr.next;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode dummy2 = new ListNode(0);
ListNode p = dummy2;
ListNode minLeft = dummy, min = head;
ListNode currLeft = dummy;
curr = head;
while(dummy.next!=null){
while(curr!=null){
if(curr.val < min.val){
minLeft = currLeft;
min = curr;
}
currLeft = curr;
curr = curr.next;
}
minLeft.next = min.next;
min.next = null;
p.next = min;
p = p.next;
minLeft = dummy;
min = dummy.next;
curr = dummy.next;
}
curr = dummy2.next;
while(curr!=null){
System.out.print(curr.val + " ");
curr = curr.next;
}
}
public static class ListNode{
int val;
ListNode next;
ListNode(int val){
this.val = val;
}
}
}
左神的解法; 将未排序部分值最小的节点的获取单独写成一个函数, 这样就不用将一堆指针变量写在一块了, 看着整洁些; 没有像我一样创建两个dummy节点; 最需要注意的地方是如何维护未排序部分的头结点: curr = curr == small ? curr.next : curr
, 只有curr恰好指向small时才更新
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc.nextLine());
if(n<1)
return;
String[] str = sc.nextLine().split(" ");
ListNode head = new ListNode(Integer.parseInt(str[0]));
ListNode curr = head;
for(int i=1; i<n; i++){
curr.next = new ListNode(Integer.parseInt(str[i]));
curr = curr.next;
}
head = selectionSort(head);
curr = head;
while(curr!=null){
System.out.print(curr.val + " ");
curr = curr.next;
}
}
public static ListNode selectionSort(ListNode head){
ListNode tail = null;
ListNode curr = head;
ListNode smallPre = null;
ListNode small = null;
while(curr != null){
small = curr;
smallPre = getSmallestPreNode(curr);
if(smallPre != null){
small = smallPre.next;
smallPre.next = small.next;
}
curr = small == curr ? curr.next : curr;
if(tail == null)
head = small;
else
tail.next = small;
tail = small;
}
return head;
}
public static ListNode getSmallestPreNode(ListNode head){
ListNode smallPre = null;
ListNode small = head;
ListNode pre = head;
ListNode curr = head.next;
while(curr != null){
if(curr.val < small.val){
smallPre = pre;
small = curr;
}
pre = curr;
curr = curr.next;
}
return smallPre;
}
public static class ListNode{
int val;
ListNode next;
ListNode(int val){
this.val = val;
}
}
}