每日一题 为了工作 2020 0404 第三十三题

/**
*
* 问题:单链表选择排序
*
* 给定一个无序单链表的头节点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+"\t");
			current=current.next;
		}
		System.out.println();
	}
}

 

public class Node {
	public int value;
	public Node next;
	public Node(int data){
		this.value=data;
	}
}

  

*运行结果

 

 

猜你喜欢

转载自www.cnblogs.com/walxt/p/12631399.html
今日推荐