#include <stdio.h>
#define ARRAY_SIZE 10
void lomuto (int A[], int l, int r, int smallerAtLeft)
{
if (smallerAtLeft == 1) //move elements smaller than pivot to the left and the greater ones to the right
{
int tmp, tmp2,pivot,i,j;
pivot = A[r];
i = l-1;
for (j =0; j<r-1; j++)
{
if (A[j] <= pivot)
{
i++;
tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
}
tmp2 = A[i+1];
A[i+1] = A[r];
A[r] = tmp2;
}
if (smallerAtLeft == 0) //move elements smaller than pivot to the right and the greater ones to the left
{
int tmp3, tmp4,pivot,i,j;
pivot = A[r];
i = l-1;
for (j=0; j<r-1; j++)
{
if (A[j]>= pivot)
{
i++;
tmp3 = A[i];
A[i] = A[j];
A[j] = tmp3;
}
}
tmp4 = A[i+1];
A[i+1] = A[r];
A[r] = tmp4;
}
}
void quicksort (int A[], int l, int r, int ascending)
{
lomuto (A,l,r,ascending);
}
int main()
{
int testarray;
int testArray[ARRAY_SIZE] = {4, 2, 5, 3, 6, 7, 8, 1, 0};
quicksort (testarray,0,8,1);
return testarray;
}
Good evening.
Usually I search almost every forum and deepest threads for dubiety in my codes.
But this time I did not found an answer that could help me. I would be so thankful if anyone could tell my why the code-exe stops working but during compiling there is no error showing onscreen.
We have to implement the quicksort algorithm with the lomuto-partitioning. If the variable "smallerAtLeft" ist equal to 1, the array should be ordered by an increasing property and if its equal to 0 decreasingly.
Furthermore we have to implement to void functions like you see in the code. The "lomuto-fct" and the "quicksort-fct" that contains the lomuto one.
Maybe this Reverse-Lomuto-Thread will help some other people too in the future..
I don't think you understand what the return value from main is and what it's used for. It is usually an indicator of success and failure, with the typical values 0 for success and a small positive value for failure. There are even macros defined for this purpose in the <stdlib.h> header file: EXIT_SUCCESS and EXIT_FAILURE.
If you want to see the sorted array you need to print it:
printf("Sorted array = {");
for (unsigned i = 0; i < ARRAY_SIZE; ++i)
{
printf(" %d", testArray[i]);
}
printf(" }\n");
That of course requires you to pass the actual array to your sorting function.
Related
Wrong output!
I have tried each and every condition but failed to get the real result
I tried to accomplish this from the clrs book pseudo-code but I failed.
I am trying to write merge sort using iterators to implement myself pseudo-code in c language, but for some reason, this code is compiling but the outcome is not sorted. Can someone figure out what is wrong with it? it seems perfectly fine to my untrained eyes.
#include <stdio.h>
#include<math.h>
#include <stdlib.h>
int a[] = {5,3,65,6,7,3,7,8};
void print_array(int a[], int size)
{
int i;
for(i = 0;i < size;i++)
{
printf("%d ",a[i]);
}
}
void merge(int a[],int p,int q,int r)
{
int n1,n2,i,j,k;
n1 = q - p + 1;
n2 = r - q;
int l[n1];
int m[n2];
for(i = 0; i < n1; i++)
l[i] = a[i+p];
for(j = 0; j < n2; j++)
m[j] = a[q+1+j];
l[n1] = 9999999;
m[n2] = 9999999;
i = 0;
j = 0;
for(k = p;k < r; k++)
{
if(l[i] <= m[j])
{
a[k] = l[i];
i = i+1;
}
else
{
a[k] = m[j];
j = j+1;
}
}
}
void merge_sort(int a[],int p,int r)
{
if(p < r)
{
int q = floor((p + r) / 2);
merge_sort(a,p,q);
merge_sort(a,q+1,r);
merge(a,p,q,r);
}
}
int main()
{
int size = (sizeof(a) / sizeof(a[0]));
print_array(a,size);
printf("\n");
merge_sort(a,0,size);
print_array(a,size);
return 0;
}
//for this input out put is showing
//-1 -1 3 3 3 -1 6 7
Please pay attention to array bounds and sizes:
Your parameter r is not the size of the array, but the index of the rightmost element, so you should call merge_sort(a, 0, size - 1);.
When you want to use a large sentinel value, after the actual array, you must allocate space for it, so:
int l[n1];
int m[n2];
Because your value r is the index of the last element, you must consider it when merging and your loop condition should be for(k = p; k <= r; k++).
(Not really a problem, but you don't need to use floor like in JavaScript. When a and b are integers, a / b will perform a division that results in an integer.)
In C, arrays (and ranges in general) have inclusive lower bounds and exclusive upper bounds: lo is the first valid index and hi is the first invalid index after the valid range. For array indices, lo and hi are zero and the array size.
Embrace this convention. The C indices lead to the following style:
The length of a range is hi - lo;
Forward loops are for (i = lo; i < hi; i++);
Adjacent ranges share the hi and lo values.
For example, in your merge function the middle value p would be the first value in the right range, but also the exclusive upper bound of the left range.
If pseudocode or code in other languages uses one-based indices, I recommend translating it to the zero-based, exclusive upper-bound style of C. After a while, you'll get suspicious of spurious - 1's and <='s. :)
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 program that finds starting and ending indexes of subarray to remove to make given array have equal sums of left and right side. If its impossible print -1. I need it to work for any array, this is just for testing. Heres a code that finds equilibrium.
#include <stdio.h>
int equilibrium(int arr[], int n)
{
int i, j;
int leftsum, rightsum;
/* Check for indexes one by one until
an equilibrium index is found */
for (i = 0; i < n; ++i) {
/* get left sum */
leftsum = 0;
for (j = 0; j < i; j++)
leftsum += arr[j];
/* get right sum */
rightsum = 0;
for (j = i + 1; j < n; j++)
rightsum += arr[j];
/* if leftsum and rightsum are same,
then we are done */
if (leftsum == rightsum)
return i;
}
/* return -1 if no equilibrium index is found */
return -1;
}
// Driver code
int main()
{
int arr[] = { -7, 1, 5, 2, -4, 3, 0 };
int arr_size = sizeof(arr) / sizeof(arr[0]);
printf("%d", equilibrium(arr, arr_size));
getchar();
return 0;
}
You could solve this problem in O(NlogN) or O(N)(in average case).
First, you need to make a pre-processing, saving all the sums from right to left in a data structure, specifically a balanced binary search tree(e.g. Red Black tree, AVL Tree, Splay Tree, etc, if you could use stdlib, just use std::multiset) or a HashTable(in stdlib it's std::unordered_multiset):
void preProcessing(dataStructure & ds, int * arr, int n){
int sum = 0;
int * toDelete = (int) malloc(n)
for(int i = n-1; i >= 0; --i){
sum += arr[i];
toDelete[i] = sum; // Save items to delete later.
tree.insert(sum);
}
So to solve problem you just need to traverse the array one time:
// It considers that the deleted subarray could be empty
bool Solve(dataStructure & ds, int * arr, int n, int * toDelete){
int sum = 0;
bool solved = false; // true if a solution is found
for(int i = 0 ; i < n; ++i){
ds.erase(toDelete[i]); // deletes the actual sum up to i-th element from data structure, as it couldn't be part of the solution.
// It costs O(logN)(BBST) or O(1)(Hashtable)
sum += arr[i];
if(ds.find(sum)){// If sum is in ds, then there's a leftsum == rightsum
// It costs O(logN)(BBST) or O(1)(HashTable)
solved = true;
break;
}
}
return solved;
}
Then, if you use a BBST(Balanced Binary Search Tree) your solution would be O(NlogN), but, if you use HashTable, your solution would be O(N) on average. I wouldn't implemented it, so maybe there's a bug, but I try to explain the main idea.
Hi can someone help me with my code im not sure where I went wrong
this is for iterative quicksort using stack the arrays are passed by using void ** pointers
int partition(void **A, int n, void *pivot){
void * temp;
int left = 0,j = 0;
int right = n-1;
int i = left;
for (j=left;j<right;j++){
if ((long)A[j] < (long)pivot){
i++;
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
temp = A[i+1];
A[right] = A[i+1];
A[i+1] = temp;
return i+1;
}
void myQuicksort(void **A, int n) {
Stack *s = stack_new(); /*making new stack and allocating memory*/
stack_push(s,(int*)0); /*pushing left and then right*/
stack_push(s,(int*)(n-1));
while (!stack_isEmpty(s)){
int right = (int)stack_pop(s); /*poping return right then left*/
int left = (int)stack_pop(s);
if (right-left >=1){
int pivot = (right+left)/2; /* taking middle element as pivot */
int p = partition(A+left , right-left+1 , A[pivot]);/*getting partition index*/
stack_push(s, (int*)left);
stack_push(s, (int*)(p-1));
stack_push(s,(int*)(p+1));
stack_push(s,(int*)right);
}
}
}
Apparently this is the quicksort algorithm you want to implement http://en.wikipedia.org/wiki/Quicksort#Algorithm
First a handy function to swap two pointers to long in A.
void swap(long **A, int i, int j)
{
long *temp = A[i];
A[i] = A[j];
A[j] = temp;
}
The partition function is below.
Note that your code is missing the first swap. You don't need it if you choose hi as pivotIndex. But that is not what you do.
Note also that you do a preincrement of i (storeIndex) which is an error. You should first do the swap and then increment i. I combine the swap and increment in one instruction by using postincrement. Swapping i+1 and returning i+1 at the end is thus wrong.
int partition(long **A, int lo, int hi)
{
int pivotIndex = (hi+lo)/2, storeIndex = lo, i;
long pivotValue = *A[pivotIndex];
swap(A, pivotIndex, hi);
for (i = lo; i < hi; ++i)
if (*A[i] < pivotValue)
swap(A, i, storeIndex++); /* Note: post increment of storeIndex */
swap(A, storeIndex, hi);
return storeIndex;
}
Your function
Je ne serai donc pas disponible mercredi prochain à 11h comme nous avions convenu. myQuickSort then becomes as follow.
Note that your stack must now store int (indexes) and not int*.
void myQuicksort(void **A, int n)
{
int lo, hi, p;
Stack *s = stack_new(); /* making new stack and allocating memory */
stack_push(s, 0); /* pushes initial lo and hi values */
stack_push(s, n-1);
while (!stack_isEmpty(s))
{
hi = stack_pop(s);
lo = stack_pop(s);
if (lo < hi)
{
p = partition(A, lo, hi);
stack_push(s, lo);
stack_push(s, p-1);
stack_push(s, p+1);
stack_push(s, hi);
}
}
}
This code has not been tested because I don't have the stack and the array at hand.
In order to use this code you have to fix your stack so that it stores integers.
I changed your variable name and use hi and lo instead of your method because in this way you only stored integer values on the stack. It's simpler and more clear.
Update:
Since the signature of partition() is imposed here is a new code proposal.
The problem with this signature is that you don't know where the pivot was stored in A. When partition() ends, the pivot value must be stored in A[i]. So we have to find it and store it in A[right] before we start the partitioning.
int partition(void **A, int n, void *pivot){
void * temp;
int left = 0, j = 0;
int right = n-1;
int i = left;
// locate the pivot
for (j = 0; j < n; ++j)
if (*(long*)A[j] == *(long*)pivot)
break;
// swap it with the right most value in A
temp = A[j];
A[j] = A[right];
A[right] = temp;
// do the partition
for (j = 0; j < right; j++){
if (*(long*)A[j] < *(long*)pivot){
temp = A[i];
A[i] = A[j];
A[j] = temp;
i++; // post increment i
}
}
// store the pivot in place
temp = A[i];
A[right] = A[i];
A[i] = temp;
// return the index of the pivot
return i;
}
Here is another possible implementation
int partition(void **A, int n, void *pivot){
void * temp;
int left = 0, j = 0;
int right = n-1;
int i = left;
// do the partition
for (j = 0; j < n; j++){
if (*(long*)A[j] < *(long*)pivot){
temp = A[i];
A[i] = A[j];
A[j] = temp;
i++; // post increment i
}
}
// At this stage the pivot is somewhere in the range A[i] to A[right]
// Lets find it and put it in A[i] if it's not already there
if (*(long*)A[i] != *(long*)pivot){
for (j = i+1; j < n; ++j){
if (*(long*)A[j] == *(long*)pivot){
temp = A[i];
A[i] = A[j];
A[j] = temp;
break;
}
}
}
// return the index of the pivot
return i;
}
There is an obvious bug in your code. Your myQuickSort function pushes and pops integers that are indexes into the array A. But "partition" doesn't know about the whole array; the value that it returns is relative to the start of the array that it was given.
Say you sort an array of 200 items, and eventually you pass the range from 100 to 200 to partition. If it partitions right in the middle, it won't return 150 as you expect, but 50.
I wonder if you actually tried debugging your code.
I have a problem in my pretty easy algorithm - quicksort in C.
It is very efficient (about 0.1s with randomize and checking if the list is sorted) but when i want to sort more than 500k elements it crashes.
Unfortunatelly i need to sort more of them because i need to write some kind of summary at the end :(
Here is my code, maybe someone will see a stupid mistake.
Thanks in advance!
int quick (int a[],int begin,int end)
{
int i = begin, j = end, w, q, pivot, k;
q=begin+end;
q=q/2;
pivot=a[q];
while (1)
{
while (a[j] > pivot && j>=0)
j=j-1;
while (a[i] < pivot && i<j)
i=i+1;
if (i < j)
{
k = a[i];
a[i] = a[j];
a[j] = k;
i++;
j--;
}
else
return j;
}
}
void quicks (int a[], int begin, int end)
{
int x;
if (end>begin)
{
x=quick(a,begin,end);
quicks(a,begin,x);
quicks(a,x+1,end);
}
}
It seems that i just need to use malloc and it is working fine. Thanks a lot for Your help!
You are suffering from RAM exhaustion/rollover: As you use an array of int, each of them requires 4 bytes. Your memory mapping is handled using size_t-type indexes. If you are compiling in 32-bit mode (which is probably your case), the maximum number it can get at is 2147483648 (2^31). With 4 bytes per int, you can only handle 536870912 elements (2^31 / 4).
As the system requires some RAM for other purposes (e.g. globals), you can only use a bit more than 500K entries.
Solution: Use a 64-bit compiler and you should be fine.
BR
Here is another and simpler implementation.
void quickSort(int a[], int begin, int end)
{
int left = begin - 1, right = end + 1, tmp;
const int pivot = a[(begin+end)/2];
if (begin >= end)
return;
while(1)
{
do right--; while(a[right] > pivot);
do left++; while(a[left] < pivot);
if(left < right)
{
tmp = a[left];
a[left] = a[right];
a[right] = tmp;
}
else
break;
}
quickSort(a, begin, right);
quickSort(a, right+1, end);
}
You call it like this
int main(void)
{
int tab[5] = {5, 3, 4, 1, 2};
int i;
quickSort(tab, 0, 4); // 4 is index of lest element of tab
for(i = 0; i < 5; i++)
printf("%d ", tab[i]);
printf("\n");
return 0;
}