Coursera Algorithms week3 归并排序 练习测验: Shuffling a linked list

题目原文:

Shuffling a linked list. Given a singly-linked list containing n items, rearrange the items uniformly at random. Your algorithm should consume a logarithmic (or constant) amount of extra memory and run in time proportional to nlogn in the worst case.

分析:

此题要求对单向链表进行随机排序,可以考虑先实现个链表的归并排序(见我的另一篇文章),再改造成这里的随机排序。

  1 import java.util.Iterator;
  2 import edu.princeton.cs.algs4.StdRandom;
  3 /**
  4  /**
  5  * 对单向链表的随机归并排序
  6  * @author evasean www.cnblogs.com/evasean/
  7  * @param <T>
  8  */
  9 public class ShuffleLinkedList<T extends Comparable<T>> implements Iterable<T>{
 10     private Node first = null;
 11     private Node last = null;
 12     private int n;
 13     private class Node{
 14         T element;
 15         Node next;
 16     }
 17     private boolean less(Comparable v, Comparable w) {
 18         return v.compareTo(w) < 0;
 19     }
 20     @Override
 21     public Iterator<T> iterator() {
 22         // TODO Auto-generated method stub
 23         return new ListIterator();
 24     }
 25     private class ListIterator implements Iterator<T>{
 26         private Node current = first;
 27         @Override
 28         public boolean hasNext() {
 29             // TODO Auto-generated method stub
 30             return current != null;
 31         }
 32 
 33         @Override
 34         public T next() {
 35             // TODO Auto-generated method stub
 36             T t = current.element;
 37             current = current.next;
 38             return t;
 39         }
 40     }
 41     public void add(T t){
 42         Node node = new Node();
 43         node.element = t;
 44         node.next = null;
 45         if(first == null && last == null){
 46             first = node;
 47             last = node;
 48         }else if(first != null && first == last){
 49             first.next = node;
 50             last = node;
 51         }else{
 52             last.next = node;
 53             last = node;
 54         }
 55         n++;
 56     }
 57     @Override
 58     public String toString(){
 59         Iterator<T> iter = iterator();
 60         String ret = iter.next().toString();
 61         while(iter.hasNext()){
 62             ret += ", "+ iter.next().toString() ;
 63         }
 64         return ret;    
 65     }
 66     public void mergeSort(){
 67         first = sort(first);
 68     }
 69     
 70     private Node sort(Node head){
 71         if(head == null || head.next == null) return head;
 72         Node slow = head;
 73         Node fast = head;
 74         //取中间节点
 75         while(fast.next != null && fast.next.next != null){
 76             slow = slow.next;
 77             fast = fast.next.next;
 78         }
 79         Node left = head;
 80         Node right = slow.next;
 81         slow.next = null; //将左右链表分开
 82         left = sort(left);
 83         right = sort(right);
 84         return merge(left,right);
 85     }
 86     private Node merge(Node left, Node right){
 87         //System.out.println("left="+left.element+",right="+right.element);
 88         Node aux = new Node(); //需要耗费logn的额外空间
 89         Node l= left;
 90         Node r = right;
 91         Node current = aux;
 92         while(l != null && r!=null){
 93             int rand = StdRandom.uniform(2);
 94             if(rand == 0){ //如果随机数选为0,则从左侧选取元素
 95                 current.next = l;
 96                 current = current.next;
 97                 l= l.next;
 98             }else{ //如果随机数选为1,则从右侧选取元素
 99                 current.next = r;
100                 current = current.next;
101                 r = r.next;
102             }
103         }
104         if(l!=null) current.next = l; // 如果左侧没遍历完,将其连接至current后
105         else if(r != null) current.next = r; //如果右侧没遍历完,将其连接至current后
106         return aux.next; //返回归并好的链表
107     }
108      public static void main(String[] args){
109          ShuffleLinkedList<Integer> sll = new ShuffleLinkedList<Integer>();
110          sll.add(1);
111          sll.add(2);
112          sll.add(11);
113          sll.add(9);
114          sll.add(10);
115          sll.add(4);
116          sll.add(7);
117          System.out.println(sll);
118          sll.mergeSort();
119          System.out.println(sll);
120      }
121 
122 }

 

posted @ 2017-07-25 10:30  evasean  阅读(1672)  评论(0编辑  收藏  举报