Lecture 11 Recursion and Quicksort

Joseph Haugh

University of New Mexico

Read Kernighan & Richie

  • Chapter 5 on Pointers and Arrays.

What is wrong with this program?

Assume #include <stdio.h> is included in all programs.

This program causes a segmentation fault, why?

void intToStr(int n) { 
  if (n / 10) {
    intToStr(n);
  }
  putchar(n % 10 + '0');
}

void main(void) { 
  intToStr(342);
}

Because it calls itself infinitely!

Corrected intToStr Function

void intToStr(int n) { 
  if (n / 10) {
    intToStr(n / 10);
  }
  putchar(n % 10 + '0');
}

void main(void) { 
  intToStr(342);
}
intToStr(342)
    intToStr(34)
        intToStr(3)
        putchar('3')
    putchar('4')
putchar('2')

Fibonacci Sequence

  • Fibonacci Sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …
  • Recursive definition: Fn = Fn − 1 + Fn − 2

Fibonacci Sequence by Loop

int fibonacci(int n) { 
  int f0 = 1, f1 = 1, f2, i;
  for (i = 0; i < n; i++) { 
    printf("%d, ", f0);
    f2 = f0 + f1;
    f0 = f1;
    f1 = f2; 
  }
  return f0;
}

int main() { 
  printf("\n%d\n", fibonacci(20));
}

Fibonacci Sequence by Recursion

int fibonacci(int n) { 
  if (n == 0 || n == 1) return 1; 
  return fibonacci(n-1) + fibonacci(n-2);
}

void main(void) { 
  printf("%d\n", fibonacci(20));
}

Each function call gets its own separate copy of all automatic variables.

Quicksort Algorithm

Quicksort is a divide and conquer algorithm that sorts by selecting a pivot and partitioning the array into elements less than and greater than the pivot.

Quicksort Algorithm

/* Used for display code, not part of algorithm. */
int arraySize;
int level;

void main(void) {
  int v[] = {23, 13, 82, 33, 51, 17, 45, 75, 11, 27};

  arraySize = sizeof(v)/sizeof(int);
  level = 0;

  quicksort(v, 0, arraySize-1);
}

Quicksort Algorithm

/* Fancy output, not part of sort */
void printArray(int levelCode, int v[],
                int left, int right) { 
    int i=0;
    if (levelCode < 0) { 
        printf("  Done%2d [", -levelCode);
    }
    else { 
        printf("Level=%2d [",levelCode);
    }

    for(i=0; iright) printf("   ");
        else printf("%2d ", v[i]);
    }
    printf("]\n");
}

Quicksort Implementation

swap helper function to swap two elements in an array.

void swap(int v[], int i, int j) {
  int temp = v[i];
  v[i] = v[j];
  v[j] = temp;
}

Quicksort Implementation

int i, last;
    level++;
    printArray(level, v, left, right);
    /* nothing to sort if fewer than two elements */
    if (left < right) { 
        /* Partition array - shown on next slide */
        quicksort(v, left, last-1);
        quicksort(v, last+1, right);
        printArray(-level, v, left, right);
    }

    level--;

Quicksort Implementation

/* Using middle element for pivot */
/* Move pivot out partition range */
swap(v, left, (left+right)/2);
last = left;

for (i= left + 1; i <= right; i++) { 
    if (v[i] < v[left]) { 
        last++;
        swap(v, last, i);
    }
}

/* restore pivot */
swap(v, left, last);

Quicksort Implementation

Level= 1 [23 13 82 33 51 17 45 75 11 27 ]
Level= 2 [27 13 33 23 17 45 11          ]
Level= 3 [11 13 17                      ]
Level= 4 [11                            ]
Level= 4 [      17                      ]
  Done 3 [11 13 17                      ]
Level= 3 [            33 45 27          ]
Level= 4 [            27 33             ]
Level= 5 [                              ]
Level= 5 [               33             ]
  Done 4 [            27 33             ]
Level= 4 [                              ]
  Done 3 [            27 33 45          ]
  Done 2 [11 13 17 23 27 33 45          ]

Quicksort Analysis

Level= 5 [               33             ]
  Done 4 [            27 33             ]
Level= 4 [                              ]
  Done 3 [            27 33 45          ]
  Done 2 [11 13 17 23 27 33 45          ]
Level= 2 [                        82 75 ]
Level= 3 [                        75    ]
Level= 3 [                              ]
  Done 2 [                        75 82 ]
  Done 1 [11 13 17 23 27 33 45 51 75 82 ]

Quicksort Analysis

Quicksort has an average performance of O(nlog n), but its worst-case performance is O(n2), depending on pivot selection.

What if we chose a different pivot?