static void runQuickSort(int[] a, int N, int approxNumThreads) throws InterruptedException {
   Global.shuffleArray(a);
   double timePassed = System.currentTimeMillis();
   Global.allThreads = new ArrayList<quicksortThread>();
   quicksortThread main_qsth =
       new quicksortThread(
           a,
           0,
           N - 1,
           (int) (N / (double) (approxNumThreads / 1.95)),
           false); // 1.95 was calculated approximately; it's got to do with the log of the
                   // quicksort, and is the average branching factor??
   Global.allThreads.add(main_qsth);
   main_qsth.start();
   boolean done = false;
   int thcount = 1;
   while (!done) {
     done = true;
     thcount = Global.max(thcount, Global.allThreads.size());
     for (int i = 0; i < Global.allThreads.size(); i++) {
       if (Global.allThreads.get(i) != null
           && Global.allThreads.get(i).getState() != Thread.State.TERMINATED) {
         done = false;
         break;
       }
     }
     Thread.sleep(1);
   }
   timePassed = System.currentTimeMillis() - timePassed;
   timePassed = ((double) timePassed) / 1000;
   // Thread.sleep(1000);
   //        Global.printArray(a, N, "Sorted array");
   // Global.isArraySorted(a,N);
   Global.timePassed = timePassed;
   Global.thcount = thcount;
 }
  void quicksort(int[] a, int lb, int ub) {
    int i, j, temp;
    int pivpos, pivot;
    if (lb < ub) {
      i = lb;
      j = ub;
      //            pivpos = ((int)(Integer.MAX_VALUE*Math.random()))%(ub-lb+1) + lb;
      //            temp = a[lb];
      //            a[lb] = a[pivpos];
      //            a[pivpos] = temp;

      pivpos = lb;
      pivot = a[pivpos];

      if (PRINTING)
        System.out.println(
            "I am handling indices: "
                + lb
                + "-"
                + ub
                + "; I chose pivot as a["
                + pivpos
                + "]="
                + pivot);
      while (i < j) {
        i++;
        while (i <= ub && a[i] < pivot) i++;
        while (j >= lb && a[j] > pivot) j--;
        if (i < j) {
          temp = a[i];
          a[i] = a[j];
          a[j] = temp;
        }
      }
      temp = a[j];
      a[j] = a[pivpos];
      a[pivpos] = temp;

      // if there are too many elements, partition the array and assign it to threads.
      // if not, then just do it recursively
      int leftPartitionLB = lb, leftPartitionUB = j - 1;
      if (leftPartitionUB - leftPartitionLB > minElementsToCreateNewThread) {
        if (PRINTING)
          System.out.println(
              "    I am thread("
                  + lb
                  + "-"
                  + ub
                  + "), "
                  + "and I'm making a new thread for indices "
                  + "("
                  + leftPartitionLB
                  + "-"
                  + leftPartitionUB
                  + ")");
        quicksortThread qsth =
            new quicksortThread(
                a,
                leftPartitionLB,
                leftPartitionUB,
                this.minElementsToCreateNewThread,
                this.PRINTING);
        Global.allThreads.add(qsth);
        qsth.start();
      } else quicksort(a, leftPartitionLB, leftPartitionUB);

      int rightPartitionLB = j + 1, rightPartitionUB = ub;
      if (rightPartitionUB - rightPartitionLB > minElementsToCreateNewThread) {
        if (PRINTING)
          System.out.println(
              "    I am thread("
                  + lb
                  + "-"
                  + ub
                  + "), "
                  + "and I'm making a new thread for indices "
                  + "("
                  + rightPartitionLB
                  + "-"
                  + rightPartitionUB
                  + ")");
        quicksortThread qsth =
            new quicksortThread(
                a,
                rightPartitionLB,
                rightPartitionUB,
                this.minElementsToCreateNewThread,
                this.PRINTING);
        Global.allThreads.add(qsth);
        qsth.start();
      } else quicksort(a, rightPartitionLB, rightPartitionUB);
    }
  }