/**
*
* 问题:单链表选择排序
*
* 给定一个无序单链表的头节点head, 实现单链表的选择排序。
*
* 要求:额外空间复杂度为0(1)。
*
* 既然要求额外空间复杂度为 0(1),就不能把链表装进数组等容器中排序,排好序之后再重新连接,
*而是要求在原链表上利用有限几个变量完成选择排序的过程。选择排序是从未排序的部分中找到最小值,
*然后放在排好序部分的尾部, 逐渐将未排序的部分缩小, 最后全部变成排好序的部分。
*
* 分析:
*
* 1.开始时默认整个链表都是未排序的部分, 对于找到的第一个最小值节点, 肯定是整个链表的敢小值节
* 点, 将其设置为新的头节点记为 newHead。
*
* 2.每次在未排序的部分中找到最小值的节点,然后把这个节点从未排序的链表中删除, 删除的过程当然
* 要保证未排序部分的链表在结构上不至于断开, 例如, 2->1->3, 删除节点 1之后, 链表应该变成 2->3,
* 这就要求我们应该找到要删除节点的前一个节点。
*
* 3.把删除的节点(也就是每次的最小值节点)连接到排好序部分的链表尾部。
*
* 4. 全部过程处理完后, 整个链表都已经有序, 返回 newHead。
*
* 如果链表的长度为 N, 时间复杂度为 O(N2), 额外空间复杂度为 0(1)。
*
* @author 雪瞳
*
*/
*代码
public class SortNode {
public Node sortNode(Node head){
//排序部分尾部
Node tailNode = null;
//未排序部分头部 初始为 head
Node current = head;
//最小节点的前一节点
Node preSmallNode = null;
//最小节点
Node smallNode = null;
//排序后的头节点
Node newHead = null;
while(current!=null){
//最小节点是头节点
smallNode = current;
preSmallNode = getPreSmallNode(current);
//最小节点不是头节点
if(preSmallNode!=null){
smallNode = preSmallNode.next;
preSmallNode.next=smallNode.next;
}
//重定义当前节点
current = current == smallNode?current.next:current;
if(tailNode == null){
newHead = smallNode;
}else{
tailNode.next=smallNode;
}
tailNode=smallNode;
}
return newHead;
}
public Node getPreSmallNode(Node head){
Node smallNode = head;
Node preSmallNode = null;
Node preNode = head;
Node current = head.next;
while(current!=null){
if(current.value<smallNode.value){
preSmallNode = preNode;
smallNode = current;
}
preNode=preNode.next;
current=current.next;
}
return preSmallNode;
}
}
import java.util.Random;
import java.util.Scanner;
public class TestSortNode {
public static void main(String[] args) {
TestSortNode test = new TestSortNode();
SortNode sort = new SortNode();
Scanner sc = new Scanner(System.in);
System.out.println("请输入链表长度...");
int len=0;
len =sc.nextInt();
Node head = test.getNodeList(len);
//test
test.showNodeList(head);
Node result = sort.sortNode(head);
test.showNodeList(result);
}
//获取链表
public Node getNodeList(int length){
Random rand = new Random();
Node nodeArray[]= new Node[length];
for(int i=0;i<length;i++){
nodeArray[i]=new Node(rand.nextInt(10));
}
for(int i=0;i<length-1;i++){
nodeArray[i].next = nodeArray[i+1];
}
return nodeArray[0];
}
//显示列表元素
public void showNodeList(Node head){
Node current = null;
current = head;
System.out.println("链表元素如下...");
while(current!=null){
System.out.print(current.value+" ");
current=current.next;
}
System.out.println();
}
}
public class Node {
public int value;
public Node next;
public Node(int data){
this.value=data;
}
}
*运行结果