CS61B Homework8 作业回顾(附代码)

一开始在mergeSortedQueues()中想到的是用nth()方法通过count i和j来对比q1和q2中值的大小,也能做出来。后面开始计时之后发现这个方法特别慢,因为每调用一次nth(n)方法,他都要进行n次循环,大大增加了计算次数。后来就干脆用front()得到的值进行对比,再用dequeue()和enqueue()方法。Linkedlist有remove first node的操作,但如果是Array的话就要用到计数器count或者下标了。

Stable or Not?
mergesort()每次从q1和q2中取出front()对比,元素相等时会优先将q1的元素enqueue到新队列,因此这种sort is not stable.
quickSort()中遇到与pivot相同元素时会将元素enqueue到qEqual中,因此这种sort is stable.



package com.homework8;/* ListSorts.java */

import com.homework8.list.*;

import java.util.Random;

public class ListSorts {

  private final static int SORTSIZE = 100;

  /**
   *  makeQueueOfQueues() makes a queue of queues, each containing one item
   *  of q.  Upon completion of this method, q is empty.
   *  @param q is a LinkedQueue of objects.
   *  @return a LinkedQueue containing LinkedQueue objects, each of which
   *    contains one object from q.
   **/
  public static LinkedQueue makeQueueOfQueues(LinkedQueue q) {
    // Replace the following line with your solution.
//    return null;
      LinkedQueue lq = new LinkedQueue();
      int length = q.size();
      try {
          for (int i = 0; i < length; i++){
              Object item = q.dequeue();
              LinkedQueue newqueue = new LinkedQueue();
              newqueue.enqueue(item);
              lq.enqueue(newqueue);
          }
      } catch (QueueEmptyException e){
          e.printStackTrace();
      }
      return lq;
  }

  /**
   *  mergeSortedQueues() merges two sorted queues into a third.  On completion
   *  of this method, q1 and q2 are empty, and their items have been merged
   *  into the returned queue.
   *  @param q1 is LinkedQueue of Comparable objects, sorted from smallest 
   *    to largest.
   *  @param q2 is LinkedQueue of Comparable objects, sorted from smallest 
   *    to largest.
   *  @return a LinkedQueue containing all the Comparable objects from q1 
   *   and q2 (and nothing else), sorted from smallest to largest.
   **/
  public static LinkedQueue mergeSortedQueues(LinkedQueue q1, LinkedQueue q2) {
    // Replace the following line with your solution.
//    return null;
      LinkedQueue lq = new LinkedQueue();
      while (q1.size() > 0 && q2.size() > 0){
          try{
              if (((Comparable)q1.front()).compareTo(q2.front()) <= 0){
                  lq.enqueue(q1.dequeue());
              } else {
                  lq.enqueue(q2.dequeue());
              }
          } catch (QueueEmptyException e){
              e.printStackTrace();
          }
      }
      while (q1.size() > 0){
          try {
              lq.enqueue(q1.dequeue());
          } catch (QueueEmptyException e){
              e.printStackTrace();
          }
      }
      while (q2.size() > 0){
          try {
            lq.enqueue(q2.dequeue());
          } catch (QueueEmptyException e){
              e.printStackTrace();
          }
      }

      return lq;


  }


  /**
   *  partition() partitions qIn using the pivot item.  On completion of
   *  this method, qIn is empty, and its items have been moved to qSmall,
   *  qEquals, and qLarge, according to their relationship to the pivot.
   *  @param qIn is a LinkedQueue of Comparable objects.
   *  @param pivot is a Comparable item used for partitioning.
   *  @param qSmall is a LinkedQueue, in which all items less than pivot
   *    will be enqueued.
   *  @param qEquals is a LinkedQueue, in which all items equal to the pivot
   *    will be enqueued.
   *  @param qLarge is a LinkedQueue, in which all items greater than pivot
   *    will be enqueued.  
   **/   
  public static void partition(LinkedQueue qIn, Comparable pivot, 
                               LinkedQueue qSmall, LinkedQueue qEquals, 
                               LinkedQueue qLarge) {
    // Your solution here.
      while(qIn.size() > 0){
          try {
              Comparable o = (Comparable) qIn.dequeue();
              if (o.compareTo(pivot) < 0){
                  qSmall.enqueue(o);
              } else if (o.compareTo(pivot) == 0){
                  qEquals.enqueue(o);
              } else {
                  qLarge.enqueue(o);
              }

          } catch (QueueEmptyException e ){
              e.printStackTrace();
          }
      }
  }

  /**
   *  mergeSort() sorts q from smallest to largest using mergesort.
   *  @param q is a LinkedQueue of Comparable objects.
   **/
  public static void mergeSort(LinkedQueue q) {
    // Your solution here.
      LinkedQueue lq = new LinkedQueue();
      LinkedQueue queue = makeQueueOfQueues(q);
      while (queue.size() > 1){
          LinkedQueue q1 = null;
          LinkedQueue q2 = null;
          try {
              q1 = (LinkedQueue) queue.dequeue();
              q2 = (LinkedQueue) queue.dequeue();

          } catch (QueueEmptyException e){
              e.printStackTrace();
          }

          lq = mergeSortedQueues(q1,q2);
          queue.enqueue(lq);
      }
      try{
          q.append((LinkedQueue) queue.dequeue());
      } catch (QueueEmptyException e){
          e.printStackTrace();
      }
  }

  /**
   *  quickSort() sorts q from smallest to largest using quicksort.
   *  @param q is a LinkedQueue of Comparable objects.
   **/
  public static void quickSort(LinkedQueue q) {
    // Your solution here.
      Random rand = new Random();
      int length = q.size();
      int n = rand.nextInt(length) + 1;
      Comparable pivot =(Comparable) q.nth(n);
      LinkedQueue qSmall = new LinkedQueue();
      LinkedQueue qEquals = new LinkedQueue();
      LinkedQueue qLarge = new LinkedQueue();
      partition(q,pivot,qSmall,qEquals,qLarge);
      if (qSmall.size() > 0){
          quickSort(qSmall);
      }
      if (qLarge.size() > 0){
          quickSort(qLarge);
      }
      q.append(qSmall);
      q.append(qEquals);
      q.append(qLarge);


  }

  /**
   *  makeRandom() builds a LinkedQueue of the indicated size containing
   *  Integer items.  The items are randomly chosen between 0 and size - 1.
   *  @param size is the size of the resulting LinkedQueue.
   **/
  public static LinkedQueue makeRandom(int size) {
    LinkedQueue q = new LinkedQueue();
    for (int i = 0; i < size; i++) {
      q.enqueue(new Integer((int) (size * Math.random())));
    }
    return q;
  }

  /**
   *  main() performs some tests on mergesort and quicksort.  Feel free to add
   *  more tests of your own to make sure your algorithms works on boundary
   *  cases.  Your test code will not be graded.
   **/
  public static void main(String [] args) {

    LinkedQueue q = makeRandom(10);
    System.out.println(q.toString());
    mergeSort(q);
    System.out.println(q.toString());

    q = makeRandom(10);
    System.out.println(q.toString());
    quickSort(q);
    System.out.println(q.toString());

//    /* Remove these comments for Part III.
    Timer stopWatch = new Timer();
    q = makeRandom(SORTSIZE);
    stopWatch.start();
    mergeSort(q);
    stopWatch.stop();
    System.out.println("Mergesort time, " + SORTSIZE + " Integers:  " +
                       stopWatch.elapsed() + " msec.");

    stopWatch.reset();
    q = makeRandom(SORTSIZE);
    stopWatch.start();
    quickSort(q);
    stopWatch.stop();
    System.out.println("Quicksort time, " + SORTSIZE + " Integers:  " +
                       stopWatch.elapsed() + " msec.");
//    */
      Timer stopWatch2 = new Timer();
      q = makeRandom(100);
      stopWatch2.start();
      mergeSort(q);
      stopWatch2.stop();
      System.out.println("Mergesort time, " + 1000 + " Integers:  " +
              stopWatch2.elapsed() + " msec.");

      stopWatch2.reset();
      q = makeRandom(1000);
      stopWatch2.start();
      quickSort(q);
      stopWatch2.stop();
      System.out.println("Quicksort time, " + 1000 + " Integers:  " +
              stopWatch2.elapsed() + " msec.");
//    */
//    */
      Timer stopWatch3 = new Timer();
      q = makeRandom(10000);
      stopWatch3.start();
      mergeSort(q);
      stopWatch3.stop();
      System.out.println("Mergesort time, " + 10000 + " Integers:  " +
              stopWatch3.elapsed() + " msec.");

      stopWatch3.reset();
      q = makeRandom(10000);
      stopWatch3.start();
      quickSort(q);
      stopWatch3.stop();
      System.out.println("Quicksort time, " + 10000 + " Integers:  " +
              stopWatch3.elapsed() + " msec.");
//    */
//    */
      Timer stopWatch4 = new Timer();
      q = makeRandom(100000);
      stopWatch4.start();
      mergeSort(q);
      stopWatch4.stop();
      System.out.println("Mergesort time, " + 100000 + " Integers:  " +
              stopWatch4.elapsed() + " msec.");

      stopWatch4.reset();
      q = makeRandom(100000);
      stopWatch4.start();
      quickSort(q);
      stopWatch4.stop();
      System.out.println("Quicksort time, " + 100000 + " Integers:  " +
              stopWatch4.elapsed() + " msec.");
//    */
//    */
      Timer stopWatch5 = new Timer();
      q = makeRandom(1000000);
      stopWatch5.start();
      mergeSort(q);
      stopWatch5.stop();
      System.out.println("Mergesort time, " + 1000000 + " Integers:  " +
              stopWatch5.elapsed() + " msec.");

      stopWatch5.reset();
      q = makeRandom(1000000);
      stopWatch5.start();
      quickSort(q);
      stopWatch5.stop();
      System.out.println("Quicksort time, " + 1000000 + " Integers:  " +
              stopWatch5.elapsed() + " msec.");
//    */
  }

}

猜你喜欢

转载自blog.csdn.net/everest115/article/details/79770419