Advertisement
nlw

Quicksort + insertion sort v.2

nlw
Oct 31st, 2012
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Demonstration of a few sorting algorithms
  2. // by Nicolau Werneck<nwerneck@gmail.com>, Sept. 2012, updated Oct. 2012.
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <math.h>
  7. #include <sys/times.h>
  8.  
  9. void print_array(unsigned int* arr, unsigned int size) {
  10.   unsigned int k;
  11.   for (k=0; k<size; k++) {
  12.     printf("%05u %16u\n", k, arr[k]);
  13.   }
  14. }
  15.  
  16. void fill_array(unsigned int* arr, unsigned int size, unsigned int bits) {
  17.   unsigned int k;
  18.   for(k = 0; k < size; k++)
  19.     arr[k] = rand() % (1<<(bits)) ;
  20. }
  21.  
  22. unsigned int* insertion_sort(unsigned int* arr, unsigned int size) {
  23.   if (size <= 1)
  24.     return;
  25.  
  26.   unsigned int p, q;
  27.   unsigned int tmp;
  28.  
  29.   for(p=1; p<size; p++) {
  30.     if (arr[p-1] <= arr[p])
  31.       continue;
  32.     q=p; // p will now be "inserted".
  33.     tmp = arr[q]; //Store the value to be "inserted".
  34.     // Sweep the list starting from p, moving the smaller items from
  35.     // the left to the right.
  36.     while((q > 0) && !(arr[q-1] <= tmp)) {
  37.       arr[q] = arr[q-1];
  38.       q--;
  39.     }
  40.     arr[q] = tmp;
  41.   }
  42. }
  43.  
  44. unsigned int* mixsort(unsigned int* arr, unsigned int size, unsigned int pivot) {
  45.  
  46.   // If the list size is small, just run insertion sort and get done with it.
  47.   if (size <= 8){
  48.     return insertion_sort(arr, size);
  49.   }
  50.  
  51.   // Just for safety really.
  52.   if (pivot == 0){
  53.     return;
  54.   }
  55.  
  56.   unsigned int k; // Loop variable
  57.   unsigned int tmp; // Temp variable to switch values
  58.  
  59.   // This variable points to the first item that is larger or equal
  60.   // than the pivot.
  61.   unsigned int sep;
  62.  
  63.   // Look for the first item that is larger or equal than the pivot.
  64.   for (k = 0; k < size && !(arr[k] & pivot); k++);
  65.   sep = k;
  66.  
  67.   // Now iterate through the remaining list items, and move the
  68.   // smaller ones to the first half of the list.
  69.   for (; k < size; k++) {
  70.     // If the current item is smaller than the pivot,
  71.     if (!(arr[k] & pivot)) {
  72.       // switch the current small value with head of second half
  73.       tmp = arr[sep];
  74.       arr[sep] = arr[k];
  75.       arr[k] = tmp;
  76.       // and increment head of the second half.
  77.       sep++;
  78.     }
  79.   }
  80.  
  81.   // Make the recursive calls for the two sublists, and the next less
  82.   // significant bit.
  83.   mixsort(arr, sep, pivot >> 1);
  84.   mixsort(arr+sep, size-sep, pivot >> 1);
  85. }
  86.  
  87. unsigned int* mixquicksort(unsigned int* arr, unsigned int size) {
  88.  
  89.   // If the list size is small, just run insertion sort and get done with it.
  90.   if (size <= 8){
  91.     return insertion_sort(arr, size);
  92.   }
  93.  
  94.   unsigned int k; // Loop variable
  95.   unsigned int tmp; // Temp variable to switch values
  96.  
  97.   // Select item to be the pivot using the median from 3 values.
  98.   unsigned int piv = 0;
  99.  
  100.   if (arr[0] < arr[size/2] && arr[size/2] < arr[size-1] || \
  101.       arr[size-1] < arr[size/2] && arr[size/2] < arr[0]) {
  102.   }
  103.   else if (arr[size/2] < arr[size-1] && arr[size-1] < arr[0] || \
  104.        arr[0] < arr[size-1] && arr[size-1] < arr[size/2]) {
  105.   }
  106.   else {
  107.     piv = 0;
  108.   }
  109.   unsigned int pivot = arr[piv];
  110.  
  111.   // This variable points to the first item that is larger or equal
  112.   // than the pivot.
  113.   unsigned int sep;
  114.  
  115.   // Switch pivot with last list item.
  116.   tmp = arr[size-1];
  117.   arr[size-1] = arr[piv];
  118.   arr[piv] = tmp;
  119.  
  120.   // Look for the first item that is larger or equal than the pivot.
  121.   for (k = 0; (k < size) && (arr[k] < pivot); k++);
  122.   sep = k;
  123.  
  124.   // Now iterate through the remaining list items, and move the
  125.   // smaller ones to the first half of the list.
  126.   for (; k < size; k++) {
  127.     // If the current item is smaller than the pivot,
  128.     if (arr[k] < pivot) {
  129.       // switch the current small value with head of second half
  130.       tmp = arr[sep];
  131.       arr[sep] = arr[k];
  132.       arr[k] = tmp;
  133.       // and increment head of the second half.
  134.       sep++;
  135.     }
  136.   }
  137.  
  138.   // Switch last item (pivot) with first.
  139.   tmp = arr[size-1];
  140.   arr[size-1] = arr[sep];
  141.   arr[sep] = tmp;
  142.  
  143.   // Make the recursive calls for the two sublists, and the next less
  144.   // significant bit.
  145.   mixquicksort(arr, sep);
  146.   mixquicksort(arr+sep+1, size-sep-1);
  147. }
  148.  
  149.  
  150.  
  151. unsigned int* radixsort(unsigned int* arr, unsigned int size, unsigned int pivot) {
  152.  
  153.   // Return if there are no more bits to test or if the list is empty.
  154.   if (pivot == 0 || size <= 1){
  155.     return;
  156.   }
  157.  
  158.   unsigned int k; // Loop variable
  159.   unsigned int tmp; // Temp variable to switch values
  160.  
  161.   // This variable points to the first item that is larger or equal
  162.   // than the pivot.
  163.   unsigned int sep;
  164.  
  165.   // Look for the first item that is larger or equal than the pivot.
  166.   for (k = 0; k < size && !(arr[k] & pivot); k++);
  167.   sep = k;
  168.  
  169.   // Now iterate through the remaining list items, and move the
  170.   // smaller ones to the first half of the list.
  171.   for (; k < size; k++) {
  172.     // If the current item is smaller than the pivot,
  173.     if (!(arr[k] & pivot)) {
  174.       // switch the current small value with head of second half
  175.       tmp = arr[sep];
  176.       arr[sep] = arr[k];
  177.       arr[k] = tmp;
  178.       // and increment head of the second half.
  179.       sep++;
  180.     }
  181.   }
  182.  
  183.   // Make the recursive calls for the two sublists, and the next less
  184.   // significant bit.
  185.   radixsort(arr, sep, pivot >> 1);
  186.   radixsort(arr+sep, size-sep, pivot >> 1);
  187. }
  188.  
  189. unsigned int* quicksort(unsigned int* arr, unsigned int size) {
  190.  
  191.   // Return if there are no more bits to test or if the list is empty.
  192.   if (size <= 1){
  193.     return;
  194.   }
  195.  
  196.   unsigned int k; // Loop variable
  197.   unsigned int tmp; // Temp variable to switch values
  198.  
  199.   // Select item to be the pivot using the median from 3 values.
  200.   unsigned int piv = 0;
  201.  
  202.   if (arr[0] < arr[size/2] && arr[size/2] < arr[size-1] || \
  203.       arr[size-1] < arr[size/2] && arr[size/2] < arr[0]) {
  204.   }
  205.   else if (arr[size/2] < arr[size-1] && arr[size-1] < arr[0] || \
  206.        arr[0] < arr[size-1] && arr[size-1] < arr[size/2]) {
  207.   }
  208.   else {
  209.     piv = 0;
  210.   }
  211.   unsigned int pivot = arr[piv];
  212.  
  213.   // This variable points to the first item that is larger or equal
  214.   // than the pivot.
  215.   unsigned int sep;
  216.  
  217.   // Switch pivot with last list item.
  218.   tmp = arr[size-1];
  219.   arr[size-1] = arr[piv];
  220.   arr[piv] = tmp;
  221.  
  222.   // Look for the first item that is larger or equal than the pivot.
  223.   for (k = 0; (k < size) && (arr[k] < pivot); k++);
  224.   sep = k;
  225.  
  226.   // Now iterate through the remaining list items, and move the
  227.   // smaller ones to the first half of the list.
  228.   for (; k < size; k++) {
  229.     // If the current item is smaller than the pivot,
  230.     if (arr[k] < pivot) {
  231.       // switch the current small value with head of second half
  232.       tmp = arr[sep];
  233.       arr[sep] = arr[k];
  234.       arr[k] = tmp;
  235.       // and increment head of the second half.
  236.       sep++;
  237.     }
  238.   }
  239.  
  240.   // Switch last item (pivot) with first.
  241.   tmp = arr[size-1];
  242.   arr[size-1] = arr[sep];
  243.   arr[sep] = tmp;
  244.  
  245.   // Make the recursive calls for the two sublists, and the next less
  246.   // significant bit.
  247.   quicksort(arr, sep);
  248.   quicksort(arr+sep+1, size-sep-1);
  249. }
  250.  
  251. int main(int argc, char* argv[]) {
  252.  
  253.   // Return if there is no argument.
  254.   if (argc < 5) {
  255.     return 1;
  256.   }
  257.  
  258.   // Select algorithm to use.
  259.   char func = argv[1][0];
  260.  
  261.   // Read word size from input argument.
  262.   int bits = atoi(argv[2]);
  263.  
  264.   // Read array size from input argument.
  265.   int size = atoi(argv[3]);
  266.  
  267.   // Read number of iterations from input argument.
  268.   int iters = atoi(argv[4]);
  269.  
  270.   // Return if conversion of arguments was not successful.
  271.   if (size == 0 || bits == 0 || bits > 31) {
  272.     return 1;
  273.   }
  274.  
  275.   // Allocate memory for the array to be sorted
  276.   unsigned int* arr = (unsigned int*) malloc(sizeof(int)*size);
  277.  
  278.   // Initialize random generator from current time.
  279.   srand ( time(NULL) );
  280.  
  281.   //////////////////////////////////////////////////////////////////////////
  282.   // Where the real action begins.  
  283.   //
  284.  
  285.   // Stuff to measure time.
  286.   struct tms tta;
  287.   struct tms ttb;
  288.   times(&tta);
  289.  
  290.  
  291.   // If iters = 0 just run once and print stuff.
  292.   if (iters == 0) {
  293.  
  294.     // Initialize array.
  295.     fill_array(arr, size, bits);
  296.     print_array(arr, size);
  297.        
  298.     // Make the initial call to the sort procedure.
  299.     if (func=='q') {
  300.       quicksort(arr, size);
  301.     } else if (func=='r') {
  302.       radixsort(arr, size,  1 << (bits-1));
  303.     } else if (func=='i') {
  304.       insertion_sort(arr, size);
  305.     } else if (func=='m') {
  306.       mixsort(arr, size,  1 << (bits-1));
  307.     } else if (func=='n') {
  308.       mixquicksort(arr, size);
  309.     }
  310.  
  311.     printf("\nSorting...\n\n");
  312.  
  313.     print_array(arr, size);
  314.  
  315.     return 0;
  316.   }
  317.  
  318.  
  319.   // Re-fill array and run quicksort for the specified number of iterations.
  320.   int k;
  321.   for(k=0;k<iters;k++) {
  322.     // Initialize array.
  323.     fill_array(arr, size, bits);
  324.        
  325.     // Make the initial call to the sort procedure.
  326.     if (func=='q') {
  327.       quicksort(arr, size);
  328.     } else if (func=='r') {
  329.       radixsort(arr, size,  1 << (bits-1));
  330.     } else if (func=='i') {
  331.       insertion_sort(arr, size);
  332.     } else if (func=='m') {
  333.       mixsort(arr, size,  1 << (bits-1));
  334.     } else if (func=='n') {
  335.       mixquicksort(arr, size);
  336.     } else if (func=='0') {
  337.       continue;
  338.     }
  339.   }
  340.  
  341.   times(&ttb);
  342.   printf("%d %e\n", size, \
  343.      ((double) (ttb.tms_utime - tta.tms_utime)*.01/iters ));
  344.  
  345.   return 0;
  346. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement