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 }
本文版权归evasean所有,转载请标明出处
http://www.cnblogs.com/evasean/