I was implementing the Quicksort Algorithm, but I have some error and I'm not able to figure out.
I'm using the rand() function to generate random numbers. I'm limiting these numbers in mod(100). mod (100) works well but when I make it mod(10) it doesn't work. The program runs but stops after printing the random unsorted array.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
int a[50];
void quicksort(int l, int r)
{
int s;
if(l<r)
{
s=partition(l, r);
quicksort(l, s-1);
quicksort(s+1, r);
}
}
int partition(int l, int r)
{
int p, i, j, temp;
p = a[l];
i=l;
j=r+1;
while(i<=j)
{
while(a[i]<=p && i<r+1)
i=i+1;
while(a[j]>=p && j>l)
j=j-1;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
temp = a[i];
a[i] = a[j];
a[j] = temp;
temp = a[l];
a[l] = a[j];
a[j] = temp;
return j;
}
int main()
{
int n, i;
printf("Enter number of elements: \n");
scanf("%d", &n);
printf("Random Array: \n");
for(i=0; i<n; i++)
{
a[i] = rand()%100; // The error seems to be here for rand()%10
printf("%d ", a[i]);
}
quicksort(0,n-2);
printf("\n Solution: \n");
for(i=0; i<n; i++)
{
printf("%d ", a[i]);
}
return 0;
}
Any help would be appreciated.
Thanks.
This loop condition inside partition() can end up in an endless loop:
while(i<=j)
To avoid change it to
while(i<j)
It never needs to swap at two identical indexes anyway.
Related
I am implementing the Heapsort program in C language which sorts with the binary tree. When I run this program, it is ok until it meets the heapsort function in the program. I also try to debug this but it still gets wrong as meeting the heapsort function.
As referencing some algorithms on the Internet, I find it similar to my source code but they run correctly, so its really hard for me to find out the errors in my source code
#include <stdio.h>
#define MAX 2100
void downheap(int a[], int n, int k)
{
int i=0;
int temp = a[0];
while (k <= n/2)
{
i = k + k;
if(i<n && a[i] <= a[i+1]) i++;
if(temp < a[i]) break;
a[k] = a[i]; k = i;
}
a[k] = temp;
}
void heapsort(int a[], int n)
{
int i, j;
for(i=0; i<=n; i++) downheap(a, n, i);
while(n>=0)
{
j = a[0]; a[0] = a[n]; a[n] = j;
downheap(a, --n, 0);
}
}
int main()
{
int n, a[MAX], i;
printf("Enter your number of elements: ");
scanf("%d", &n);
for(i=0; i<n; i++) printf("%d: ", i), scanf("%d", &a[i]);
heapsort(a, n-1);
for(i=0; i<n; i++) printf("%d ", a[i]);
return 0;
}
There are multiple problems in your code that I list below:
You should stick to the common convention that n is the number of elements. In your code it is the number of elements minus one which is inconvenient. In this case you would call heapsort(a, n).
In the heapsort function, for(i=0; i<=n; i++) downheap(a, n, i) should be for(i=n/2-1; i>=0; i--) downheap(a, n, i).
Next, since n is the number of elements in a, the loop should be while(--n > 0). The iteration where n=0 is pointless since it will then swap a[0] with a[0]. Finally you call downheap(a, n, 0).
The function downheap, is where you have the biggest problem. The function should compare the element at index i with its two children and store the max of the tree at index i. If a swap with a child occurred, resume donwheap with this child. Your function is completely wrong. Here is a correct implementation.
void downheap(int *a, int n, int k){
int l = 2*k+1, r = 2*k+2, max = k;
if (l < n && a[l] > a[max])
max = l;
if (r < n &d a[r] > a[max])
max = r;
if (max != k) {
int j = a[k]; a[k] = a[max]; a[max] = j;
downheap(a, n, max);
}
}
As you can see, this code is very different from yours which is completely wrong.
For your convenience, here is the code of the heapsort function. That code was not as bad, but still incorrect.
void heapsort(int *a, int n){
int i, j;
for(i=n/2-1; i>=0; i--)
downheap(a, n, i);
while(--n > 0){
j = a[0]; a[0] = a[n]; a[n] = j;
downheap(a, n, 0);
}
}
EDIT
Non recursive implementation of downheap:
void downheap(int *a, int n, int k){
while (1) {
int l = 2*k+1, r = 2*k+2, max = k;
if (l < n && a[l] > a[max])
max = l;
if (r < n &d a[r] > a[max])
max = r;
if (max == k)
break;
int j = a[k]; a[k] = a[max]; a[max] = j;
k = max;
}
}
My C merge code works when I initialize the array globally at the top of the program until the stack overflows. I'm trying to initialize the array with malloc, but when I do, the code will only read in two integers and stop running.
This program pulls random numbers from a file called alg.txt and then sorts them. Again, the code works (up until 500k integers) when defining z at the top of the program to the number of integers to be sorted, and declaring the array globally to be equal to arr[z]. How do I figure out what is going on?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int count = 0;
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
int L[n1], R[n2];
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
count++;
for (j = 0; j < n2; j++)
R[j] = arr[m + 1+ j];
count++;
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
count++;
}
else
{
arr[k] = R[j];
j++;
count++;
}
k++;
count++;
}
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
count++;
}
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
count++;
}
}
void mergeSort(int arr[], int l, int r)
{
if (l < r)
{
int m = l+(r-l)/2;
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
}
void printArray(int A[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}
int main()
{
int i;
FILE *myFile;
myFile = fopen("alg.txt", "r");
int z;
printf("Enter the size of the array: ");
scanf("%d", &z);
int *arr = (int *)malloc(z*sizeof(int));
int n = sizeof(arr)/sizeof(arr[0]);
for(i=0; i < z; i++)
{
fscanf(myFile, "%d,", &arr[i]);
}
mergeSort(arr, 0, n - 1);
printf("\nSorted array is \n");
printArray(arr, n);
printf("count is %d\n", count);
return 0;
}
You are declaring the L and R array's locally (inside the merge function). They consume stack on every function call. You should initialize them globally so that they can be stored on the heap. Also, you should declare just one array (like temp_arr in the below code) as there's no need for two separate arrays like L and R.
See Local vs Global variable storage
You can improve your merge function to this:
int temp_arr[500000]; // Global declaration
void merge(int arr[], int l, int m, int r)
{
int i=l, j=m+1, k=l;
while(i<=m && j<=r)
{
if(arr[i]<arr[j])
temp_arr[++k] = arr[++i];
else temp_arr[++k] = arr[++j];
}
while(i<=m)
temp_arr[++k] = arr[++i];
while(j<=r)
temp_arr[++k] = arr[++j];
i = l;
while(i<=r)
arr[i] = temp_arr[++i]; // Storing stored array in arr
}
This is my first semester learning C and I have trouble with one of my homeworks.
It's a program to receive the lists of homework as sets of (t,d) and to evaluate the urgency of each homework. (t means time left until deadline and d mean difficulty.) The task is to sort the list primarily by the order of remaining time and if the remaining time is equal, to sort it by difficulty.
This code works perfectly well when the input is something like
(1,0), (2, 1), (4,5) ...
But when the input is like
(1,0), (1, 4), (2, 1)...
it won't stop receiving inputs. This happens when the 'time' of the homework is the same (or so I think). I can't figure out why it's doing this.
#include <stdio.h>
#define MAX 1024
void insertionSort(int a[], int b[], int num);
void printArray(int a[], int b[], int num);
int main()
{
int a[MAX] = {0};
int b[MAX] = {0};
int i, num;
scanf("%d", &num);
for(i=0; i<num; i++){
scanf("%d", &a[i]);
scanf("%d", &b[i]);
}
insertionSort(a, b, num);
return 1;
}
void insertionSort(int a[], int b[], int num)
{
int i, j, val, val2;
for(i=1; i<num; i++)
{
val = a[i];
val2 = b[i];
j = i-1;
while((j>=0) && (a[j]>=val))
{
if(a[j] == val){
if(val2 < b[j]){
a[j+1] = a[j];
b[j+1] = b[j];
j--;
}
}
else{
a[j+1] = a[j];
b[j+1] = b[j];
j--;
}
a[j+1] = val;
b[j+1] = val2;
}
}
printArray(a, b, num);
}
void printArray(int a[], int b[], int num)
{
int i;
for(i=0; i<num; i++){
printf("%d ", a[i]);
printf("%d", b[i]);
printf("\n");
}
}
Your code is not continuously receiving inputs, instead it is stuck in an infinite loop inside the insertionSort function
You just need to add an else case and break the loop.
Here is the working code:
#include <stdio.h>
#define MAX 1024
void insertionSort(int a[], int b[], int num);
void printArray(int a[], int b[], int num);
int main()
{
int a[MAX] = {0};
int b[MAX] = {0};
int i, num;
scanf("%d", &num);
for(i=0; i<num; i++)
{
scanf("%d", &a[i]);
scanf("%d", &b[i]);
}
insertionSort(a, b, num);
return 1;
}
void insertionSort(int a[], int b[], int num)
{
int i, j, val, val2;
for(i=1; i<num; i++)
{
val = a[i];
val2 = b[i];
j = i-1;
while((j>=0) && (a[j]>=val))
{
if(a[j] == val)
{
if(val2 < b[j])
{
a[j+1] = a[j];
b[j+1] = b[j];
j--;
}
else
{
break;
}
}
else
{
a[j+1] = a[j];
b[j+1] = b[j];
j--;
}
a[j+1] = val;
b[j+1] = val2;
}
}
printArray(a, b, num);
}
void printArray(int a[], int b[], int num)
{
int i;
for(i=0; i<num; i++)
{
printf("%d ", a[i]);
printf("%d", b[i]);
printf("\n");
}
}
I need to pass and integer array and number of values in the array to the sort(array[], count) function. It should return the number of swaps, not comparisons, made by the bubble sort. This code compiles and runs but I do not get the right output. Sometimes it has me continuously entering values despite the while(i < counter).
#include <stdio.h>
int sort(int array[], int count);
int main(void){
int numArray[100];
int counter, value;
printf("Enter array length \n");
scanf("%d", &counter);
int i = 0;
while(i < counter){
scanf("%d", &numArray[i]);
i++;
}
i = 0;
while(i < counter){
sort(numArray, counter);
i++;
}
i = 0;
while(i < counter){
printf("Values: %d\n", numArray[i]);
i++;
}
return 0;
}
int sort(int array[], int count){
int i, j, temp;
int swaps = 0;
for(i = 0; i < count-1; ++i){
for(j=0; j<count-1-i; ++j){
if(array[j] > array[j+1]){
temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
swaps++;
}
}
}
return swaps;
}
As your code is now, you only need to call sort(numArray, counter) once and "catch" the returned value:
int totalSwaps = sort(numArray, counter);
And print the result once:
printf("the number of swaps in bubblesort is: %d", totalSwaps);
This is a program which attempts to sort an array using the quick sort algorithm.
All seems to be fine, except that the output is not correct.
(Try the program for n=5, and then n=10. It works correctly for the former, but not the latter.)
#include <stdio.h>
//#include <iostream.h>
//#include <conio.h>
int partition(int arr[], int left, int right) {
int i = left, j = right;
int temp;
//Choosing the middle element as the pivot
//int pivot=arr[left];
int pivot = arr[(left+right)/2];
while (i <= j) {
while (arr[i] < pivot) {i++;}
while (arr[j] > pivot) {j--;}
if (i <= j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
return i;
}
void quick_sort(int arr[], int p, int r) {
if (p<r) {
int q=partition(arr, p, r);
quick_sort(arr, p, q-1);
quick_sort(arr, q+1, r);
}
}
int main() {
int values[100], n, i;
//clrscr();
printf("Enter no. of elements ");
scanf("%d", &n);
if (n>100) {
printf("Invalid input. Exiting now");
//getch();
return 0;
}
for (i=0; i<100; i++) values[i]=0;
printf("Enter the numbers\n");
for (i=0; i<n; i++) scanf("%d", &values[i]);
printf("The numbers you entered are\n");
for (i=0; i<n; i++) printf("%d ", values[i]);
printf("\n");
quick_sort(values, 0, n-1);
printf("Numbers after sorting are\n");
printf("(The output might not be the expected one (Be careful).\n");
for (i=0; i<n; i++) printf("%d ", values[i]);
//std::cin.get();
return 0;
}
There are two problems. First, the comparison i <= j is wrong. If i == j, you should not swap an element with itself. This should be changed to i < j in both places. Secondly, you should not move the i and j array indicies along after swapping. If it is the last swap, this pushes i past the actual pivot and causes your error.
int partition(int arr[], int left, int right) {
int i = left, j = right;
int temp;
//Choosing the middle element as the pivot
//int pivot=arr[left];
int pivot = arr[(left+right)/2];
while (i < j) {
while (arr[i] < pivot) {i++;}
while (arr[j] > pivot) {j--;}
if (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
return i;
}
is better to use the std sort from algorithm.h :
http://www.cplusplus.com/reference/algorithm/sort/