• 每日一题 为了工作 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+"	");
    			current=current.next;
    		}
    		System.out.println();
    	}
    }
    

     

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

      

    *运行结果

     

     

  • 相关阅读:
    深度分析:java8的新特性lambda和stream流,看完你学会了吗?
    花了三天整理,Spring Cloud微服务如何设计异常处理机制?还看不懂算我输
    做了两年java,这些高性能高可用高并发的技术架构你都知道吗?
    面试阿里,字节跳动90%会被问到的微服务,你确定不进来看看吗?
    阿里面试官:小伙子,你给我说一下前后端分离的接口规范是什么?
    深度分析:面试阿里,字节跳动,美团几乎都会被问到的阻塞队列
    1. 线性DP 1143. 最长公共子序列
    1. 线性DP 300. 最长上升子序列 (LIS)
    GC 的认识(转) https://github.com/qcrao/Go-Questions/blob/master/GC/GC.md#1-什么是-gc有什么作用
    缓存淘汰算法--LRU算法
  • 原文地址:https://www.cnblogs.com/walxt/p/12631399.html
Copyright © 2020-2023  润新知