Construct count array in better than O(n^2) time complexity - c

Given an array A[] of size n, construct two arrays C_min[] and C_max[] such that
C_min[i] represents number of elements smaller than A[i] in A[0 to i] and
C_max[i] represents number of elements greater than A[i] in A[i to n-1]
For example A[5] = {1,2,4,3,6} then C_min[] and C_max[] would be
C_min[5] = {0,1,2,2,4}
C_max[5] = {4,3,1,1,0}
I am not able to think of an algorithm better than O(n^2) but this post motivates me to think of some better way of doing this, but am not able to able apply similar kind of logic(which is mentioned in the post) here.
In the given post, problem given is to find no of inversion in an array. if array[i] > array[j] and j>i then it forms a inversion. for example The sequence 2, 4, 1, 3, 5 has three inversions (2, 1), (4, 1), (4, 3).
idea used to solve this problem is a merge sort algorithm.
In merge process, let i is used for indexing left sub-array(L[]) and j
for right sub-array(R[]). At any step in merge(), if L[i] is greater
than R[j], then there are (mid – i+1) inversions,where mid is the
middle index passed to the merge function of merge sort. because left
and right subarrays are sorted, so all the remaining elements in
left-subarray (L[i+1], L[i+2] … L[mid]) will be greater than R[j]
code for this logic is given below:
#include <bits/stdc++.h>
int _mergeSort(int arr[], int temp[], int left, int right);
int merge(int arr[], int temp[], int left, int mid, int right);
/* This function sorts the input array and returns the
number of inversions in the array */
int mergeSort(int arr[], int array_size)
{
int *temp = (int *)malloc(sizeof(int)*array_size);
return _mergeSort(arr, temp, 0, array_size - 1);
}
/* An auxiliary recursive function that sorts the input array and
returns the number of inversions in the array. */
int _mergeSort(int arr[], int temp[], int left, int right)
{
int mid, inv_count = 0;
if (right > left)
{
/* Divide the array into two parts and call _mergeSortAndCountInv()
for each of the parts */
mid = (right + left)/2;
/* Inversion count will be sum of inversions in left-part, right-part
and number of inversions in merging */
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);
/*Merge the two parts*/
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
}
/* This funt merges two sorted arrays and returns inversion count in
the arrays.*/
int merge(int arr[], int temp[], int left, int mid, int right)
{
int i, j, k;
int inv_count = 0;
i = left; /* i is index for left subarray*/
j = mid; /* i is index for right subarray*/
k = left; /* i is index for resultant merged subarray*/
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];
/*this is tricky -- see above explanation/diagram for merge()*/
inv_count = inv_count + (mid - i);
}
}
/* Copy the remaining elements of left subarray
(if there are any) to temp*/
while (i <= mid - 1)
temp[k++] = arr[i++];
/* Copy the remaining elements of right subarray
(if there are any) to temp*/
while (j <= right)
temp[k++] = arr[j++];
/*Copy back the merged elements to original array*/
for (i=left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
/* Driver progra to test above functions */
int main(int argv, char** args)
{
int arr[] = {1, 20, 6, 4, 5};
printf(" Number of inversions are %d \n", mergeSort(arr, 5));
getchar();
return 0;
}
so can this count array problem be done on similar lines.
Is it possible to construct count array in better than O(n^2)-time?

Suppose you kept an array, S, where S[0..x] is a sorted version of A[0..x]. Then computing C_min[x+1] when you have already computed C_min[0..x] would amount to inserting A[x+1] into S (an O(log n) operation) and locating A[x+1] within S (at worst, another O(log n) operation). That would make computing all of C_min O(n log n). Computing C_max would be similar, but would need its own version of S, making computing both C_min and C_max O(n log n).

Related

Signal: segmentation fault (core dumped) error code in C, but I cannot figure out why in merge sort

#include <stdio.h>
void msort(int *a, int n);
void msort_recursion(
int a[], int left,
int right);
void merge_arrays(int a[], int left, int middle,
int right); // merges the sorted portions of the array
int main() {
int a[] = {5, 2, 4, 1, 3};
int n = 5;
msort(a, n);
printf("[");
for (int i = 0; i < n; i++)
if (i == n - 1) {
printf("%d", a[i]);
} else {
printf("%d, ", a[i]);
}
printf("]\n");
return 0;
}
void msort(int *a, int n) { msort_recursion(a, 0, n - 1); }
void msort_recursion(int a[], int left, int right) {
if (left < right) {
int middle = left + (right - 1) / 2;
msort_recursion(a, left, middle);
msort_recursion(a, middle + 1,
right);
merge_arrays(a, left, middle,
right);
}
}
void merge_arrays(
int a[], int left, int middle,
int right) {
int left_size = middle - left + 1;
int right_size = right - middle;
int templ[left_size];
int tempr[right_size];
int i, j, k;
for (int i = 0; i < left_size; i++)
templ[i] = a[left + i];
for (int i = 0; i < right_size; i++)
tempr[i] = a[middle + 1 + i];
for (i = 0, j = 0, k = left; k <= right; k++) {
if ((i < left_size) && (j >= right_size || templ[i] <= tempr[j])) {
a[k] = templ[i];
i++;
} else {
a[k] = tempr[j];
j++;
}
}
}
Merge sort is implemented in Code, but when run, I receive the error code "signal: segmentation fault (core dumped)" which to my understanding, means that it has reached past the end of an array but I do not understand how this is... Merge sort is implemented in Code, but when run, I receive the error code "signal: segmentation fault (core dumped)" which to my understanding, means that it has reached past the end of an array but I do not understand how this is...
The reason is you called msort_recursion recursively to many times this happened because the middle is computed wrong and should be int middle = left + (right - left) / 2; notice it's the difference in position split in half.
make sure to read geeksforgeeks.org/merge-sort more carefully next time
void msort_recursion(int a[], int left, int right) {
if (left < right) {
int middle = left + (right - 1) / 2;
/* Here should be ^^^^^^^^^ right - left */
msort_recursion(a, left, middle);
msort_recursion(a, middle + 1,right);
merge_arrays(a, left, middle,right);
}
}
for msort_recursion, I was doing int middle = left + (right - 1) / 2 instead of int middle = left + (right - left) / 2
#include <stdio.h>
void msort(int *a, int n); // merge sort array a with n elements in place in C
void msort_recursion(int a[], int left, int right); // recursion where the array is continuously divided in half
// until there is only one element left
void merge_arrays(int a[], int left, int middle, int right); // merges the sorted portions of the array
int main() {
int a[] = {5, 2, 4, 1, 3};
int n = 5;
msort(a, n);
// print sorted array
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
void msort(int *a, int n) {
msort_recursion(a, 0, n - 1);
}
void msort_recursion(int a[], int left, int right) {
// as long as the left is less than the right, we will continuously divide the
// array
if (left < right) {
int middle = left + (right - left) / 2; // find the middle of the array
msort_recursion(a, left, middle); // recursion on the left side of the array
msort_recursion(a, middle + 1, right); // recursion on the right side of the array
merge_arrays(a, left, middle, right); // merge the sorted sections of the array
}
}
void merge_arrays(int a[], int left, int middle, int right) { // left is the index for the start of the array, middle is the
// middle index, right is the index of the last element in the
// right section of the array
int left_size = middle - left + 1; // size of left side of array
int right_size = right - middle; // size of right side of the array
// create 2 tepm sub arrarys and copy the portions into the sub arrays
int templ[left_size];
int tempr[right_size];
int i, j, k; // i is keeping track of left array, j is keeping track of right
// array, k is keeping track of original array a
for (int i = 0; i < left_size; i++)
// copy left side into left temp array
templ[i] = a[left + i];
for (int i = 0; i < right_size; i++)
// copy right side into right temp array
tempr[i] = a[middle + 1 + i];
// pick from the sorted left and right arrays to replace into the original
// array
for (i = 0, j = 0, k = left; k <= right; k++) {
if ((i < left_size) && (j >= right_size || templ[i] <= tempr[j])) {
// if the element in the left array is smaller than the element in the
// right array then replace it in array a as long as we don't reach the end
// of either the left or right arrays
a[k] = templ[i];
i++;
// otherwise, put the right element into the array a
} else {
a[k] = tempr[j];
j++;
}
}
}

inversion count mergesort in C

A permutation of integers from 1 to n is a sequence a1, a2, ..., an, such that each integer from 1 to n is appeared in the sequence exactly once.
Two integers in а permutation form an inversion, when the bigger one is before the smaller one.
As an example, in the permutation 4 2 7 1 5 6 3, there are 10 inversions in total. They are the following pairs: 4–2, 4–1, 4–3, 2–1, 7–1, 7–5, 7–6, 7–3, 5–3, 6–3.
Input n and array[n] 2<=n<=100,000
First I solved problem with bubble sorting but then i met time complexity problem.
Second I solved it mergesort but I didn't do well
Here is my cord
#include <stdio.h>
#include <malloc.h>
int n;
void sizein(){
scanf("%d",&n);
}
int count=0;
static void merge(int data[],int p,int q,int r){
int i,j,l;
int k=p;
int sorted[n];
for(i=p,j=q+1;i<=q&&j<=r;){
sorted[k++]=(data[i]<=data[j]) ? data[i++]:data[j++];
if(data[i>data[j]]){
count+=q-i;
}
}
if(i>q){
for(l=j;l<=r;l++,k++){
sorted[k]=data[l];
}
}
else{
for(l=i;l<=q;l++,k++){
sorted[k]=data[l];
}
}
for(l=p;l<=r;l++){
data[l]=sorted[l];
}
}
void merge_sort(int data[],int p,int r){
if(p<r){
int q=(p+r)/2;
merge_sort(data,p,q);
merge_sort(data,q+1,r);
merge(data,p,q,r);
}
}
int main(void){
int i;
int data[n];
for(i=0;i<n;i++){
scanf("%d",&data[i]);
}
merge_sort(data,0,n);
printf("%d",count);
return 0;
}
Where should i fix it
I cannot find some implementation bits in your code that divides the arrays into sub-arrays based on the index(as quick sort sorts based on value)
kindly have a look at the code provided below
int q = p + (r - l) / 2;//recommended to be used in the function mergesort
int q=(p+r)/2;//your implementation
try this code for your function part as my code runs well with over half a million values, I cannot clearly see any subarray to which values are copied in your implementation of the function merge I have added comments to make it easier for you to understand, the terminology of the variables are slightly different.
refer "ANANY LEVETIN-INTRODUCTION TO THE DESIGN AND ANALYSIS OF ALGORITHS" book for a vivid explanation on this algorithm
Have a look and try this
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
/* create temp arrays */
int L[n1], R[n2];
/* Copy data to temp arrays L[] and R[] */
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
/* Merge the temp arrays back into arr[l..r]*/
i = 0; // Initial index of first subarray
j = 0; // Initial index of second subarray
k = l; // Initial index of merged subarray
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
/* Copy the remaining elements of L[], if there
are any */
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
/* Copy the remaining elements of R[], if there
are any */
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
/* l is for left index and r is right index of the
sub-array of arr to be sorted */
void mergeSort(int arr[], int l, int r)
{
if (l < r) {
// Same as (l+r)/2, but avoids overflow for
// large l and h
int m = l + (r - l) / 2;
// Sort first and second halves
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
/* Driver code */
int main()
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
int arr_size = sizeof(arr) / sizeof(arr[0]);
printf("Given array is \n");
//printArray(arr, arr_size);
mergeSort(arr, 0, arr_size - 1);
printf("\nSorted array is \n");
//printArray(arr, arr_size);
return 0;
}
After reading the code for some time I still can not say I understand the idea of counting the inversions. However, I can point out three things in it which seem incorrect to me.
First, I can't see where you call the sizein() function to initialize the n variable.
The second problem is the condition here:
if(data[i>data[j]]){
count+=q-i;
}
You compare the index i to the value of a data item data[j] which looks strange. Even worse, if you were to sort an array of geometric figures or an array of songs it could be just impossible due to incompatibility of the types of data to be compared. What's even worse, even if comparison succeedes, as in the case of an int index and an int value in data[],the result of comparison is an int value 1 if comparison is satisfied or 0 otherwise. As a result this condition will resolve to
if(data[0]){
count+=q-i;
}
or to
if(data[1]){
count+=q-i;
}
which is obviously wrong.
The correct code looks like this:
if (data[i] > data[j]) {
count += q - i;
}
The error would be more apparent if you left appropriate spacing between operators and their operands.
Yet another error lurks in the call to merge_sort(). First, you fill the data[] array with this loop:
for (i = 0; i < n; i ++) {
scanf("%d", &data[i]);
}
Obviously, you fill an n-items array with data at indices from 0 through n-1.
Then you call the merge-sorting routine:
merge_sort( data, 0, n);
which suggests the parameter p is the index of the first item or the part to be sorted and q is one-past-the last item. However, this disagrees with recursive calls:
merge_sort( data, p, q);
merge_sort( data, q+1, r);
Setting q as the ending index in the first call and q+1 as the starting index in the second suggests the ending index is inclusive, that is, it is the position of the last item in the segment to be sorted. Otherwise the two calls would leave the item data[q] unsorted. This also follows from internal loops, which continue while i <= q or whle l <= r etc.
So the initial call shouldn't be
merge_sort( data, 0, n);
but rather
merge_sort( data, 0, n-1);

C implementation of quick sort produces garbage value at arr[0]

Consider the following algorithm:
void qsort(int arr[], int left, int right) {
if (left < right) {
int index = partition(arr, left, right);
qsort(arr, left, index - 1);
qsort(arr, index + 1, right);
}
}
int partition(int arr[], int left, int right) {
int pivot = arr[right];
int i = left - 1;
for (int j = left; j < right; j++) {
if (arr[j] <= pivot) {
++i;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[right]);
return i + 1;
}
inline void swap(int* i, int* j) {
int temp = *i;
*i = *j;
*j = temp;
}
After I fixed the segfaults, I noticed that the algorithm always produces a garbage value at arr[0]. So if the input array is: 5 5 1 3 7 0 0 0 3 , the output is -858993460 0 0 0 1 3 3 5 5. I've ran this through a debugger numerous times and nevertheless I still have no idea where the garbage value comes from. What's more interesting is that in Java pretty much the same algorithm works perfectly.
edit
The initial function is called like this: qsort(arr, 0, 9); where 9 is the length of the array - 1.
I suspect you have an off-by-one error in how you initialize arr or how you call qsort(). Likely it gets called with a garbage (uninitialized) element either at the start or at the end of the array. This also likely explains why the largest value, 7, is missing from the output.
If I were to speculate further, I'd guess that in Java, the array gets initialized with zeros and so you get an extra zero in the output (that perhaps you're overlooking amongst the other zeros?)
edit: The initial function is called like this: qsort(arr, 0, 9); where 9 is the length of the array - 1.
The 9 is clearly not correct for your example, so here is one error. It would account for the garbage element but not for the missing element.
My next hypothesis is that, having sorted a ten-element array (9 real + 1 garbage) you then only print out the first nine elements. This would account for the missing 7 in your output (it's the largest and so gets placed in the final spot, which is the spot that doesn't get printed out).
P.S. If I may offer some unsolicited advice for future questions, posting a Minimal, Complete, and Verifiable example would make all this debugging-by-conjecture completely unnecessary as we'd be able to see right away what exactly is going on with your code. :)
If you invoke the function with the size instead of the index of the right-most element (which is the size - 1), you access the array out of bounds.
This code works:
#include <stdio.h>
static
inline void swap(int *i, int *j)
{
int temp = *i;
*i = *j;
*j = temp;
}
static
int partition(int arr[], int left, int right)
{
int pivot = arr[right];
int i = left - 1;
for (int j = left; j < right; j++)
{
if (arr[j] <= pivot)
{
++i;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[right]);
return i + 1;
}
static
void qsort(int arr[], int left, int right)
{
if (left < right)
{
int index = partition(arr, left, right);
qsort(arr, left, index - 1);
qsort(arr, index + 1, right);
}
}
static void dump_array(const char *tag, int size, int *arr)
{
printf("%s (%d):", tag, size);
for (int i = 0; i < size; i++)
printf(" %d", arr[i]);
putchar('\n');
}
int main(void)
{
int arr[] = { 5, 5, 1, 3, 7, 0, 0, 0, 3, };
enum { ARR_SIZE = sizeof(arr) / sizeof(arr[0]) };
dump_array("Before", ARR_SIZE, arr);
qsort(arr, 0, ARR_SIZE - 1);
dump_array("After", ARR_SIZE, arr);
return 0;
}
Output:
Before (9): 5 5 1 3 7 0 0 0 3
After (9): 0 0 0 1 3 3 5 5 7

merge_sort not working, output is just a bunch of 1 -1 and 0

So I got the task to write merge_sort in a recursive way, and it just returns either an array of 0,-1, 1 of the same length as the original input. Any ideas where I did something wrong? input_merge_sort.h and input_merge_sort.c are given by the task and handle the input and output, so all I have to focus on is the algorithm itself. Some details about the algorithm, to make sure I understood it correctly:
MergeSort sorts lists by splitting them into equally sized lists, splitting them until they're single elements, to then 2 single-element lists together, comparing them and putting the smaller one in front. With the sub-lists you write into the original list by reading from 2 sublists, comparing the value and putting pointer 1 element further, to then compare it with the old element of the other sublist, which was bigger than the other.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "input_merge_sort.h"
/*
array: Pointer at the start of the array
first: Index of the first element
len : Index of the last element
*/
void merge(int a[], int i1, int j1, int j2) {
int temp[j2 - i1]; //array used for merging
int i, j, k;
i = i1; //beginning of the first list
int i2 = j1 + 1;
j = i2; //beginning of the second list
k = 0;
while (i <= j1 && j <= j2) { //while elements in both lists
if (a[i] < a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= j1) //copy remaining elements of the first list
temp[k++] = a[i++];
while (j <= j2) //copy remaining elements of the second list
temp[k++] = a[j++];
//Transfer elements from temp[] back to a[]
for (i = i1, j = 0; i <= j2; i++, j++)
a[i] = temp[j];
}
void merge_sort(int *array, int first, int last) {
int middle;
if (first < last) {
middle = ((first + last) / 2);
merge_sort(array, first, middle);
merge_sort(array, middle + 1, last);
merge(array, first, middle, last);
}
}
/*
Reads integers from files and outputs them into the stdout after mergesorting them.
How to run: ./introprog_merge_sort_rekursiv <max_amount> <filepath>
*/
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("usage: %s <max_amount> <filepath>\n", argv[0]);
exit(2);
}
char *filename = argv[2];
// Initialize array
int *array = (int*)malloc(atoi(argv[1]) * sizeof(int)); //MINE
int len = read_array_from_file(array, atoi(argv[1]), filename);
printf("Input:\n");
print_array(array, len);
// Call of "merge_sort()"
merge_sort(array, array[0], array[len - 1]); //MINE
printf("Sorted:\n");
print_array(array, len);
free(array);
return 0;
}
The function merge_sort takes an array and the indices of its first and last elements as arguments, but you pass the elements themselves. Change:
merge_sort(array, array[0],array[len-1]);
to:
merge_sort(array, 0, len - 1);
In merge you crate a temporary array on the stack, but it is one element short. It should be:
int temp[j2 - i1 + 1];
I recommend that you change the functions so that they don't take the last element as upper bound but the first element outside the range, as is usual in C arrays and loops. In my opinion, that makes the code simpler. The two halves of the array are then [low, mid) and [mid, high). The length of the whole array is high - low.

kth smallest number using variation of quicksort

I have the following partition method and kthsmallest method (Variation of quicksort) which works for some cases but gives me the value 32767 for a few cases.
void swap(int* a, int* b){
int temp = *b;
*b = *a;
*a = temp;
}
int partition(int* arr, int l, int r){
int pivot = arr[r];
int i = l, j=0;
for(j=l; j<=r-1; j++){
if(arr[j] <= pivot){
swap(&arr[i], &arr[j]);
i++;
}
}
swap(&arr[i], &arr[j]);
return i;
}
And the kthsmallest function is as follows:-
int kthsmallest(int* arr, int low, int high, int k){
/* low = 0 and high = #elements - 1 */
/* k is in between 1 to high + 1 */
if (k>0 & k<=high-low+1) {
// pos is partitioning index, arr[p] is now at right place
int pos = partition(arr, low, high);
// Separately sort elements before / partition and after partition
if(pos-low == k-1){
return arr[pos];
}
//if position returned is greater than k, recurse left subarray
else if(pos-low > k-1){
return kthsmallest(arr, low, pos-1, k);
}
return kthsmallest(arr, pos+1, high, k-(pos+1));
}
}
However it works when I change the last call in kthsmallest function i.e.
Change: return kthsmallest(arr, pos+1, high, k-(pos+1));
To: return kthsmallest(arr, pos+1, high, k-(pos+1)+low);
I want to understand why I need to add low to k-(pos+1). Because in my view, when we have the subarray on the right in which the recursion enters, the kth smallest number in the large array boils down to k - last partition element -1 i.e. k-(pos+1).
You need low because when you recursively start with a new array, low will be the reference for pos. So the new k will be calculated from low to pos.
Maybe an example would be more clarifying.
Lets find the 9th smallest element of this array:
Now we do the partition, so we get:
From pos to the left we've got the smallest elements in the array, that's the 3 smallest elements. Now we'll work with the subarray starting from pos+1. And we need to get the 6th smallest element:
We do a partition over this subarray:
Remember that we are working over a subarray trying to find the 6th smallest element. In this case we separated the (pos - low + 1)th smallest elements in the subarray. So our new k will be:
We do a new partition:
Now we exceeded the 4th smallest element of the last subarray, so we trim the last part:
We do the partition again:
And we get:
So our number is 17.
Hope it helps.
PD: As David C. Rankin says in comments you probably should change & for &&.
It appears one of the problems you are having is trying to shoehorn a quickselect routine into a recursive function when there is no reason to make the function recursive to begin with. All you need to do is identify the partition the 'k' element resides in, there is no need to sort. All you need for your kthsmallest is:
/** select the ZERO BASED 'k' element from 'arr'.
* where 'low' and 'high' are the ZERO BASED low
* and high indexes for 'arr'.
*/
int kthsmallest (int *arr, int low, int high, int k)
{
for (;;) {
if (low == high)
return arr[low];
int pos = partition (arr, low, high);
if (k == pos)
return arr[k];
else if (k < pos)
high = pos - 1;
else
low = pos + 1;
}
}
Using your exact partition and swap functions, you can write a small example program to test k for every element in an array. (note: the element returned is based on a zero indexed k, e.g. the first smallest element is offset zero from the end of the array -- just like in the rest of C)
#include <stdio.h>
void swap (int *a, int *b);
int partition (int *arr, int l, int r);
/** select the ZERO BASED 'k' element from 'arr'.
* where 'low' and 'high' are the ZERO BASED low
* and high indexes for 'arr'.
*/
int kthsmallest (int *arr, int low, int high, int k)
{
for (;;) {
if (low == high)
return arr[low];
int pos = partition (arr, low, high);
if (k == pos)
return arr[k];
else if (k < pos)
high = pos - 1;
else
low = pos + 1;
}
}
int main (void) {
int a[] = { 51, 86, 34, 79, 92, 68, 14, 47, 22, 6 },
nelem = sizeof a / sizeof *a;
for (int i = 0; i < nelem; i++)
printf (" nth (%2d) element is : %d\n", i,
kthsmallest (a, 0, nelem - 1, i));
return 0;
}
void swap (int *a, int *b)
{
int temp = *b;
*b = *a;
*a = temp;
}
int partition (int *arr, int l, int r)
{
int pivot = arr[r];
int i = l, j = 0;
for (j = l; j <= r - 1; j++) {
if (arr[j] <= pivot) {
swap (&arr[i], &arr[j]);
i++;
}
}
swap (&arr[i], &arr[j]);
return i;
}
Example Use/Output
$ ./bin/kthsmall
nth ( 0) element is : 6
nth ( 1) element is : 14
nth ( 2) element is : 22
nth ( 3) element is : 34
nth ( 4) element is : 47
nth ( 5) element is : 51
nth ( 6) element is : 68
nth ( 7) element is : 79
nth ( 8) element is : 86
nth ( 9) element is : 92

Resources