程序员代码面试指南(左程云)读书笔记
第三章
单链表的选择排序
题目:
给定一个无序单链表的头节点head,实现单链表的选择排序。
要求:额外空间复杂度为O(1)
既然要求额外空间复杂度为O(1),就不能把链表装进数组等容器中排序,排好序之后再重新连接,而是要求在原链表上利用几个有限的变量完成排序过程,解法如下:
1.开始时默认整个链表都是未排序部分,对于找到第一个最小值节点,肯定是真个链表的最小节点,将其设置为新的头节点newHead.
2, 每次再未排序的部分中找到最小值的节点,然后把这个节点从未排序的链表中删除,删除过程要保证链表不断开。
3,把删除的节点(也就是每次的最小值节点)链接到排好序的链表的尾部。
4,全部过程完毕,返回newHead.
public class SNode {
public int value;
public SNode next;
public SNode(int data){
this.value=data;
}
}
package com.chen.zuocengyun;
public class SortNode {
public static void main(String[] args) {
SNode s1=new SNode(5);
SNode s2=new SNode(34);
SNode s3=new SNode(65);
SNode s4=new SNode(2);
SNode s5=new SNode(87);
s1.next=s2;
s2.next=s3;
s3.next=s4;
s4.next=s5;
SNode sn= selectionSortNode(s1);
while(sn!=null){
System.out.println(sn.value);
sn=sn.next;
}
}
public static SNode selectionSortNode(SNode head){
if(head==null){
return head;
}
SNode tail=null;//未排序链表的尾节点
SNode cur=head;//未排序链表的头节点
SNode smallPre=null;//最小节点的前一个节点
SNode small=null;//最小节点
while(cur!=null){
small=cur;
smallPre=getSmallPreNode(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;
}
private static SNode getSmallPreNode(SNode head) {
SNode pre=head;//未排序链表的尾节点
SNode cur=head.next;//未排序链表的头节点
SNode smallPre=null;//最小节点的前一个节点
SNode small=head;//最小节点
while(cur!=null){
if(cur.value<small.value){
smallPre=pre;
small=cur;
}
pre=cur;
cur=cur.next;
}
return smallPre;
}
}