Studying the Quicksort algorithm - quicksort

I study the Quicksort algorithm and created a sample program like this :
// Java program for implementation of QuickSort
class QuickSort
{
/* This function takes last element as pivot,
places the pivot element at its correct
position in sorted array, and places all
smaller (smaller than pivot) to left of
pivot and all greater elements to right
of pivot */
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low-1); // index of smaller element
for (int j=low; j<high; j++)
{
// If current element is smaller than or
// equal to pivot
if (arr[j] <= pivot)
{
i++;
// swap arr[i] and arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// swap arr[i+1] and arr[high] (or pivot)
int temp = arr[i+1];
arr[i+1] = arr[high];
arr[high] = temp;
return i+1;
}
/* The main function that implements QuickSort()
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void sort(int arr[], int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[pi] is
now at right place */
int pi = partition(arr, low, high);
// Recursively sort elements before
// partition and after partition
sort(arr, low, pi-1);
sort(arr, pi+1, high);
}
}
/* A utility function to print array of size n */
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i]+" ");
System.out.println();
}
// Driver program
public static void main(String args[])
{
int arr[] = {10, 7, 8, 9, 1, 5};
int n = arr.length;
QuickSort ob = new QuickSort();
ob.sort(arr, 0, n-1);
System.out.println("sorted array");
printArray(arr);
}
}
/*This code is contributed by Rajat Mishra */
Precisely in this part :
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low-1); // index of smaller element
for (int j=low; j<high; j++)
would you have an idea why the code says: int i = (low-1) ? The range of i will not become -1 with this instruction? I mean it was initialized previously to 0? Then do think is it possible such instruction? Or what as you it has to understand?
Best regard,
Thanks,
Intelego.

Yes of course,
First, "i" is initialized to 0
QuickSort ob = new QuickSort();
ob.sort(arr, 0, n-1);
And then,
high --> Ending index */
void sort(int arr[], int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[pi] is
now at right place */
int pi = partition(arr, low, high);
Low = 0 until here,
and the code gives "i" the value of -1.
from where "i" wanted to know if it is possible "i" could be -1 ?
In this case what could represent the index -1 ?
Thanks very much,
Intelegoit

Related

DPDK implementation of MPSC ring buffer

While going through the implementation of the DPDK MPSC (multi-produce & single-consumer) Ring Buffer API, i found the code to move the head of the producer for inserting new elements in the Ring buffer. The function is as follows :
static __rte_always_inline unsigned int
__rte_ring_move_prod_head(struct rte_ring *r, unsigned int is_sp,
unsigned int n, enum rte_ring_queue_behavior behavior,
uint32_t *old_head, uint32_t *new_head,
uint32_t *free_entries)
{
const uint32_t capacity = r->capacity;
uint32_t cons_tail;
unsigned int max = n;
int success;
*old_head = __atomic_load_n(&r->prod.head, __ATOMIC_RELAXED);
do {
/* Reset n to the initial burst count */
n = max;
/* Ensure the head is read before tail */
__atomic_thread_fence(__ATOMIC_ACQUIRE);
/* load-acquire synchronize with store-release of ht->tail
* in update_tail.
*/
cons_tail = __atomic_load_n(&r->cons.tail,
__ATOMIC_ACQUIRE);
/* The subtraction is done between two unsigned 32bits value
* (the result is always modulo 32 bits even if we have
* *old_head > cons_tail). So 'free_entries' is always between 0
* and capacity (which is < size).
*/
*free_entries = (capacity + cons_tail - *old_head);
/* check that we have enough room in ring */
if (unlikely(n > *free_entries))
n = (behavior == RTE_RING_QUEUE_FIXED) ?
0 : *free_entries;
if (n == 0)
return 0;
*new_head = *old_head + n;
if (is_sp)
r->prod.head = *new_head, success = 1;
else
/* on failure, *old_head is updated */
success = __atomic_compare_exchange_n(&r->prod.head,
old_head, *new_head,
0, __ATOMIC_RELAXED,
__ATOMIC_RELAXED);
} while (unlikely(success == 0));
return n;
}
The load and compare exchange of the producer's head is done using __ATOMIC_RELAXED memory ordering. Isn't this a problem when multiple producers from different threads produce to the queue. Or am I missing something?
https://doc.dpdk.org/guides/prog_guide/ring_lib.html describes the basic mechanism that DPDK uses for implementing the Ring buffer.

Alsa mixer and GtkVolumeButton

I make code to get and set alsa mixer volume:
snd_mixer_elem_t *elem = NULL;
long alsa_min, alsa_max, alsa_vol;
int alsa_get_volume( void )
{
long val;
assert (elem);
if (snd_mixer_selem_is_playback_mono(elem)) {
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &val);
return val;
} else {
int c, n = 0;
long sum = 0;
for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
if (snd_mixer_selem_has_playback_channel(elem, c)) {
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &val);
sum += val;
n++;
}
}
if (! n) {
return 0;
}
val = sum / n;
sum = (long)((double)(alsa_vol * (alsa_max - alsa_min)) / 100. + 0.5);
if (sum != val) {
alsa_vol = (long)(((val * 100.) / (alsa_max - alsa_min)) + 0.5);
}
return alsa_vol;
}
}
int alsa_set_volume( int percentdiff )
{
long volume;
alsa_get_volume();
alsa_vol += percentdiff;
if( alsa_vol > 100 ) alsa_vol = 100;
if( alsa_vol < 0 ) alsa_vol = 0;
volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + 0.5);
snd_mixer_selem_set_playback_volume_all(elem, volume + alsa_min);
snd_mixer_selem_set_playback_switch_all(elem, 1);
muted = 0;
mutecount = 0;
return alsa_vol;
}
I wont to make alsa mixer volume to changed by GtkVolumeButton. Tried this but when value from gtk button is changed up or down, alsa mixer always jumps to 100 %:
int gtk_volume_button_get_value (GtkWidget *button)
{
return (int) (gtk_scale_button_get_value(GTK_SCALE_BUTTON(button)) * 100);
}
void gtk_volume_button_set_value (GtkWidget *button, int value)
{
gtk_scale_button_set_value(GTK_SCALE_BUTTON(button), (gdouble) value / 100);
}
void volume_value_changed_cb(GtkVolumeButton *button, gpointer user_data)
{
int vol = (int)(gtk_volume_button_get_value(volume_button) + 0.5);
alsa_set_volume(vol);
}
Please help me to write a corect code for GtkVolumeButton.
Your problem has nothing to do with GtkVolume. In fact, it comes from you using two different approaches to handle volume. alsa_get_volume gives you an absolute sound level, which is an integer. One would expect alsa_set_volume to accept the same kind of value range. And that's how you use it in volume_value_changed_cb: « get the volume level of the volume control, between 0 and 100, and set it as current volume. ».
However, the implementation is completely different. It's implemented as if you wanted to tell it « add or substract x% of the current sound volume ». You get the current volume level and add that percentage, thus you're computing a relative sound level, not an absolute one. So, if your initial sound level is 50%, and you want to lower it to 45%, one would expect you'd call alsa_set_volume (45) to do it. But currently, calling alsa_set_volume (45) will set alsa_vol to 50 + 45 = 95%.
So you need to use absolute volume, not relative.
/* newvol: Desired volume level in the [0;100] range */
int alsa_set_volume (int newvol)
{
long volume;
alsa_vol = CLAMP(absvol, 0, 100);
volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + alsa_min);
snd_mixer_selem_set_playback_volume_all(elem, volume);
snd_mixer_selem_set_playback_switch_all(elem, 1);
muted = 0;
mutecount = 0;
return alsa_vol;
}

Memory Access Exceedingly Slow For a Simple Loop Through an Array

I am taking about 50 times as long as expected to loop through a simple assignment. My first reaction was that I had disordered my memory access in the arrays, resulting in cache misses. This doesn't seem the case, however.
The pixel value assignment and updating the arrays takes a dogs age. Do any one of you folks have an inclining as to why this is happening? (I am compiling for an iPod with an A4)
memset(columnSumsCurrentFrameA, 0, sizeof(unsigned int) * (_validImageWidth/numSubdivisions) );
memset(rowSumsCurrentFrameA, 0, sizeof(unsigned int) * (_validImageHeight/numSubdivisions) );
int pixelValue = 0;
int startingRow = 0;
int startingColumn = 0;
for (int i = 0; i < _validImageHeight/numSubdivisions; i++)
{
int index = (i + startingRow) * _imageWidth;
for( int j = 0; j < (_validImageWidth/numSubdivisions); j++)
{
pixelValue = imageData[index + startingColumn + j];
columnSumsCurrentFrameA[j] += pixelValue;
rowSumsCurrentFrameA[i] += pixelValue;
}
}
The result of _validImageWidth/numSubdivisions must be an integer, are you sure that is always the case?
Also, you should calculate _validImageWidth/numSubdivisions before entering the double loops, it's not safe to assume your compiler takes care of it.
int limit = _validImageHeight/numSubdivisions;
for (int i = 0; i < limit; i++)
{
int index = (i + startingRow) * _imageWidth;
for( int j = 0; j < limit; j++)
{
pixelValue = imageData[index + startingColumn + j];
columnSumsCurrentFrameA[j] += pixelValue;
rowSumsCurrentFrameA[i] += pixelValue;
}
}

Bottoms-up mergesort problems!

I am having problems with bottoms-up mergesort. I have problems sorting/merging. Current code includes:
public void mergeSort(long[] a, int len) {
long[] temp = new long[a.length];
int length = 1;
while (length < len) {
mergepass(a, temp, length, len);
length *= 2;
}
}
public void mergepass(long[] a, long[] temp, int blocksize, int len) {
int k = 0;
int i = 1;
while(i <= (len/blocksize)){
if(blocksize == 1){break;}
int min = a.length;
for(int j = 0; j < blocksize; j++){
if(a[i*j] < min){
temp[k++] = a[i*j];
count++;
}
else{
temp[k++] = a[(i*j)+1];
count++;
}
}
for(int n = 0; n < this.a.length; n++){
a[n] = temp[n];
}
}
}
Obvious problems:
i is never incremented.
At no point do you compare two elements in the array. (Is that what if(a[i*j] < min) is supposed to be doing? I can't tell.)
Why are you multiplying i and j?
What's this.a.length?
Style problems:
mergeSort() takes len as an argument, even though arrays have an implicit length. To make matters worse, the function also uses a.length and length.
Generally poor variable names.
Nitpicks:
If you're going to make a second array of the same size, it is common to make one the "source" and the other the "destination" and swap them between passes, instead of sorting into a temporary array and copying them back again.

converting Biginteger to Bytearray(Raw data)

I have used the following code for converting the bigint in decimal to bytearray (raw data), but I'm getting wrong result.
What is the mistake here?
I'm trying this in Apple Mac ( for Iphone app)
COMP_BYTE_SIZE is 4
Is there any bigendian/ little endian issue, please Help.
void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
{
int i, j, k = size-1;
check(x);
memset(data, 0, size); /* ensure all leading 0's are cleared */
for (i = 0; i < x->size; i++)
{
for (j = 0; j < COMP_BYTE_SIZE; j++)
{
comp mask = 0xff << (j*8);
int num = (x->comps[i] & mask) >> (j*8);
data[k--] = num;
if (k < 0)
{
break;
}
}
}
Thanks.
The argument size is at least x->size*4, ie. the target array is big enough? Also use
comp mask = (comp)0xff << (j*8);
num should be cast to uint8_t before copy
data[k--] = (uint8_t)num;