The array doesn't sort properly and bubble sort and quick sort work fine. I have checked many times to find any mistakes but couldn't find one. (feel free to edit the question if it doesn't seem right)....................................
...............................................................................................................................................................................................
#include <iostream>
#include <ctime>
using namespace std;
const int MaxElements = 500;
int compCount = 0; // keeps track of comparisons of elements in array
int moveCount = 0; // keeps track of movement of elements in array
int main()
{
// Declarations
clock_t before; //time before sorting
clock_t after; //time after sorting
double result; //Total time
int n; //size of set
int sample[MaxElements]; //array
// Prompt the user for size of set
cout << "Enter size of set: ";
cin >> n;
cout << "---------------Selection Sort-----------------\n";
// Generate random values into the array
generateSample(sample, n);
cout << "Unsorted array: ";
printElements(sample, n);
before = clock();
selectionSort(sample, n);
after = clock();
result = static_cast<double>(after - before) / CLOCKS_PER_SEC;
cout << "\nSorted: ";
printElements(sample, n);
cout << endl << before << " " << after << "\n";
cout << result << "\n";
cout << "Movement: " << moveCount << endl;
cout << "Comparison: " << compCount << endl;
}
// Swap algorithm
void swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void selectionSort(int arr[], int n)
{
int i,
j,
current;
for (i = 0; i < n - 1; i++)
{
current = i;
for (j = i + 1; j < n; j++)
{
compCount++;
if (arr[j] < arr[current])
{
current = j;
}
if (current != i)
{
swap(arr[current], arr[i]);
moveCount += 3;
}
}
}
}
This if statement
if (current != i)
{
swap(arr[current], arr[i]);
moveCount += 3;
}
must be placed outside the inner loop that is after it.
Hi there i've been tasked with Writing a simple program that is given an array of integers and determines the mode, which is the number that appears most frequently in the array.
The approach i'm trying to adopt is using a bubble sort with a bin search algorithm my level of knowledge is at a beginner stage can someone help point me?
Where i'm going wrong i believe it to be passing the correct search value to find it in the array! But i maybe wrong but some help would be very much appreciated, thanks in advance for those to take time to try help me.
#include <iostream>
using namespace std;
const int arrayLength = 10;
int searchVal;
int numGroup[arrayLength];
bool isSorted(int [], int arrayLength);
int binSearch(int [],int arrayLegth,int searchVal);
int main()
{
// Take in num
for (int index = 0; index < arrayLength; index++)
{
cout << "Enter Number: ";
cin >> numGroup[index];
}
// Sort numbers
//var to hold the val being swaped
int swapHolder = 0;
//bubble sort
for (int iSort = 0; iSort < arrayLength; iSort++)
{
for (int jSort = (iSort + 1); jSort <= arrayLength - 1; jSort++)
{
if (numGroup[iSort] > numGroup[jSort])
{
swapHolder = numGroup[iSort];
numGroup[iSort] = numGroup[jSort];
numGroup[jSort] = swapHolder;
}
}
}
//passes the sorted array and the length to the isSorted
isSorted(numGroup, arrayLength);
return 0;
}
bool isSorted(int numGroup[], int arrayLength){
cout << "Final result" << endl;
for (int index = 0; index < arrayLength - 1 ; index++)
{
if (numGroup[index] > numGroup[index + 1])
{
cout << "it's false";
system("pause");
return false;
}
cout << numGroup[index] << endl;
//cout << arrayLength << endl;
}
cout << numGroup[arrayLength - 1] << endl;
//trying to make searchVal
for (int i = 0; i < numGroup[arrayLength - 1]; i++)
{
if (numGroup[i] == numGroup[i])
{
int searchVal = numGroup[i];
}
}
binSearch(numGroup, arrayLength, searchVal);
cout << "It's true ";
system("pause");
return true;
}
int binSearch(int numGroup[], int arrayLength,int searchVal){
int low = 0;
int high = arrayLength - 1;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
//search through the array
if (searchVal == numGroup[mid])
{
return mid;
}
else if (searchVal > numGroup[mid])
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
cout << "In bin search " << mid;
return mid;
}
You don't need to sort the array. You can have another array (freq) which will count the numbers appearances. So, a mini code for that:
int myArray[10];
int freq[1000]; //we assume that the numbers are smaller than 1000
void count()
{
for(int i = 0; i < 10; ++i)
{
++freq[v[i]];
}
}
int ReturnModeElement()
{
int maxFreq = -1;
int element = -1;
for(int i = 0 ; i < 10; ++i)
{
if(freq[v[i]] > maxFreq)
{
maxFreq = freq[v[i]];
element = v[i];
}
}
return element;
}
I hope you got the idea :)
Im trying to implement the Quick Select Algorithm on a Array that has randomly generated numbers. Now after writing the algorithm in code, it does not sort the array from lowest to highest nor am i able to find the kth smallest element. I would appreciate the help i get. Thank you.
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
void printArray(int *myArray, int n){
for(int i = 0; i < n; i++){
cout << myArray[i] << " ";
}
}
int Partition(int *myArray, int startingIndex, int endingIndex){
int pivot = myArray[endingIndex];
int partitionIndex = startingIndex;
for(int i = startingIndex; i<endingIndex; i++){
if(myArray[i]<= pivot){
swap(myArray[i],myArray[partitionIndex]);
partitionIndex++;
}
}
swap(myArray[partitionIndex],myArray[endingIndex]);
return partitionIndex;
}
int QuickSelect(int *myArray, int startingIndex, int endingIndex, int KthElement){
/*if(startingIndex < endingIndex){
int partitionIndex = Partition(myArray, startingIndex,endingIndex);
QuickSelect(myArray,startingIndex,partitionIndex-1);
QuickSelect(myArray,partitionIndex+1,endingIndex);
}*/1
if (startingIndex < endingIndex){
int partitionIndex = Partition(myArray, startingIndex, endingIndex);
if(KthElement == partitionIndex)
return KthElement;
if(KthElement < partitionIndex)
QuickSelect(myArray, startingIndex, partitionIndex - 1, KthElement);
else
QuickSelect(myArray, partitionIndex + 1, endingIndex, KthElement);
}
}
int main(){
int numOfElements;
int KthElement;
srand(time(NULL));
cout<<"Enter The Amount Of Numbers You Wish To Use: ";
cin >> numOfElements;
int myArray[numOfElements];
cout << "Array Before Sorting: ";
for(int i = 0; i< numOfElements; i++){
myArray[i] = rand() %10;
}
printArray(myArray, numOfElements);
cout << endl;
cout << endl;
cout <<"Enter The Index Of The Kth Element You Wish To Retrieve: ";
cin >> KthElement;
QuickSelect(myArray, 0,numOfElements,KthElement);
cout << "Array After Sorting: ";
printArray(myArray, numOfElements);
cout << endl;
cout <<"The " <<KthElement<<" Smallest Element Is: " << QuickSelect(myArray,0,numOfElements,KthElement);
}
For numOfElements as 5, array extends from 0 to 4.
Your endingIndex assumes that its the last index of the array.
Fix:
QuickSelect(myArray, 0,numOfElements-1,KthElement);
Problems with your code:
Your program accesses out of bound array locations in
int pivot = myArray[endingIndex];
Have a check for k<1 and k>(num_of_elements).
Check your code for num_of_elements = 1 as well.
Check what k means for the array, i.e For k=1 , arr[0] should be returned not arr[1];
For this program I have to fill an array with 20 random numbers (1-100), sort the array (descending) and then search for a random key value and output the position of that value if it is in the array. I am having 2 problems. First the while loop I have to exit the program is not working and I can not figure out why. Second my binary search is not returning a position value and I don't know why. This code will compile.
#include <iostream>
#include <ctime>
using namespace std;
int printArray(int *arr, int arraySize);
int fillArrayWithRandomNumbers(int *arr, int arraySize);
int bubbleSortDesc(int *arr, int arraySize);
int binarySearch(int *arr, int arraySize, int key);
int main()
{
int const arraySize = 20;
int arr[arraySize];
cout << "CMPSC 201-Extra Credit\n" << "This program fills an array, and then searches for a random key value." << endl <<endl;
char stopTheProgram = 'n';
do {
int key, result;
cout << "Unordered array:" << endl;
fillArrayWithRandomNumbers(arr, arraySize);
printArray(arr, arraySize);
cout << endl << "Array after a bubble sort : " <<endl;
bubbleSortDesc(arr, arraySize);
printArray(arr, arraySize);
key = rand()%100;
cout << endl <<"Searching for " << key << endl;
result = binarySearch(arr, key, arraySize);
if (result == -1)
{
cout << "Key " << key << " not found in the array" << endl;
}
else
{
cout << "Key " << key << " found at position " << result << endl;
}
cout << "Stop the program? (y/n) ";
cin >> stopTheProgram;
cout << endl;
} while (!(stopTheProgram == 'Y' || stopTheProgram == 'y'));
return 0;
}
int fillArrayWithRandomNumbers(int *arr, int arraySize)
{
srand((unsigned)time(NULL));
for (int i = 0; i<arraySize; i++)
{
arr[i] = (rand() % 100) + 1;
}
return *arr;
}
int printArray(int *arr, int arraySize)
{
for (int i = 0; i<arraySize; i++)
{
cout << arr[i] << " ";
}
return *arr;
}
int bubbleSortDesc(int *arr, int arraySize){
int i, j;
int temp = 0;
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize - 1; j++)
{
if (arr[j] < arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return *arr;
}
int binarySearch(int arr[], int key, int arraySize)
{
int i, j;
int temp = 0;
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize - 1; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
int position, lowerBound = 0;
position = (lowerBound + arraySize) / 2;
while ((arr[position] != key) && (lowerBound <= arraySize))
{
if (arr[position] > key)
{
arraySize = position - 1;
}
else
{
lowerBound = position + 1;
}
position = (lowerBound + arraySize) / 2;
}
if (lowerBound <= arraySize)
{
position = 19 - position;
return position;
}
else {
return -1;
}
}
Solved: I now have fixed my problems with my binary search, and exiting my while loop. I am going to leave this here just in case anyone has my prof after me. So just to recap, this program fills an array with 20 random numbers (ranging 1-100), sorts the array in descending order and then creates a random key value (between 1-100). It then bubble sorts the array so it is in ascending order, uses a binary search to find the key value in the array and finally output the position of that key value if it is in the array.
I can see two issues with your code. First, you are shadowing the stopTheProgram variable. You define it once just before the do/while loop and initialize it to 'n'; Then once inside the do/while you define another stopTheProgram. This is a problem because of scoping. Inside the do/while loop the input from the user is assigned to the local stopTheProgram (defined in the do/while) but that ceases to exits outside the loop. So the while loop expression is always evaluated using the globally scoped stopTheProgram, which is set to 'n'. So remove the second definition. Second is an issue with the expression that controls the while loop. It always evaluates true. Draw a truth table if you can't visualize it. If stopTheProgram = 'Y' then the stopTheProgram != "Y" || stopTheProgram != 'y' is 0 || 1 which is always true. If stopTheProgram = 'y' then stopTheProgram != "Y" || stopTheProgram != 'y' is 1 || 0 which is always true. This works: while(!(stopTheProgram == 'Y' || stopTheProgram == 'y'))
I am trying to write a code for merge sort. I am not getting the correct output. I am following this pseudocode link Following is my code. I pass my unsorted array into merge_sort function and call merge function recursively to sort and combine the sub arrays.I know there are more simpler and efficient ways to write code for merge sort but I want to try on my own otherwise I won't learn. Thanks in advance.
int* merge_sort(int* a,int size)
{
//cout<<size;
//cout<<"hi";
if(size == 1)
{
//cout<<"less";
//cout<<a[0];
return a;
}
int* left;
int* right;
int middle = ceil(size/2);
left = new int(middle);
right = new int(middle);
for(int i=0;i<middle;i++)
{
left[i]=a[i];
//cout<<left[i];
}
cout<<"\t";
for(int j=middle;j<size;j++)
{
right[j]=a[j];
//cout<<right[j];
}
cout<<"\t";
left = merge_sort(left,middle);
//if(size==2)
//cout<<left[0];
right = merge_sort(right,middle);
//if(size==2)
//cout<<right[0];
return merge(left,right,middle);
}
int* merge(int* l,int* r,int m)
{
int* result;
result = new int(2*m); //to store the output
int lsize=m; // to keep track of left sub list
int rsize=m; // to keep track of right sub list
int counter = 0; // will use to index result
//cout<<m;
while(lsize>0 || rsize>0)
{
if(lsize>0 && rsize>0)
{
if(l[0]<=r[0])
{
result[counter]=l[0];
counter++; //to store next value in result
lsize--;
l=&l[1]; //decrementing the size of left array
}
else
{
result[counter]=r[0];
counter++;
rsize--;
r=&r[1]; //dec. size of right array
}
}
else if(lsize>0)
{
result[counter]=l[0];
counter++;
lsize--;
l=&l[1];
}
else if(rsize>0)
{
result[counter]=l[0];
counter++;
lsize--;
l=&l[1];
}
}
return result;
}
Your code:
int *left = new int(middle);
allocates a single integer initialized to middle. You need:
int *left = new int [middle];
which allocates an array of middle integers. Rinse and repeat for int *right. Actually, you need to use:
int *right = new int [size - middle];
This gets the correct size for the right array. You then have to modify the recursive call to merge_sort() for the right sub-array:
merge_sort(right, size - middle);
Finally, you have to rewrite merge() to take the size of the left array and the size of the right array independently, because they may be of different sizes. For example, if you sort 10 elements,
you then end up with a call to merge two arrays of 5 (which is fine), but at the next level you need to merge an array of 2 and an array of 3 elements (and you're hosed).
The allocation of result also has the () vs [] allocation problem. And there are some other as yet unresolved problems. But these are important steps in the right direction.
As mentioned in a comment to the question, you have a monumental memory leakage problem, too. What's more, it is not trivial to fix because merge_sort() does an early exit without allocating new memory, so it isn't as simple as 'delete the memory returned by merge_sort()'.
Copy and paste is wonderful until you forget to edit the pasted copy correctly:
else if (lsize > 0)
{
result[counter] = l[0];
counter++;
lsize--;
l = &l[1];
}
else if (rsize > 0)
{
result[counter] = l[0];
counter++;
lsize--;
l = &l[1];
}
Methinks you should be using r and rsize in the second of these blocks.
This still isn't the whole story...
And the residual problem (apart from memory management, which is still 100% leaky and problematic) is:
for(int j=middle;j<size;j++)
{
right[j]=a[j];
//cout<<right[j];
}
You're copying into parts of right that you've not allocated. You need something more like:
for(int j = 0; j < size - middle; j++)
{
right[j] = a[j + middle];
//cout<<right[j];
}
This code works as long as you always sort at least two items at the top level (you crash freeing unallocated space if you sort 1 item — that's part of the memory management problem).
#include <iostream>
using namespace std;
namespace {
int *merge(int *l, int m, int *r, int n);
void dump_array(int *a, int size)
{
int i;
cout << size << ": ";
for (i = 0; i < size; i++)
{
cout << ' ' << a[i];
if (i % 10 == 9)
cout << '\n';
}
if (i % 10 != 0)
cout << '\n';
}
};
int *merge_sort(int *a, int size)
{
cout << "-->> merge_sort:\n";
dump_array(a, size);
if (size <= 1)
{
cout << "<<-- merge_sort: early return\n";
return a;
}
int middle = size/2;
int *left = new int[middle];
int *right = new int[size - middle];
cout << middle << ": ";
for (int i = 0; i < middle; i++)
{
left[i] = a[i];
cout << ' ' << left[i];
}
cout << "\n";
cout << (size - middle) << ": ";
for (int j = 0; j < size - middle; j++)
{
right[j] = a[j + middle];
cout << ' ' << right[j];
}
cout << "\n";
cout << "MSL:\n";
int *nleft = merge_sort(left, middle);
cout << "NL: ";
dump_array(nleft, middle);
cout << "OL: ";
dump_array(left, middle);
cout << "OR: ";
dump_array(right, size - middle);
cout << "MSR:\n";
int *nright = merge_sort(right, size - middle);
cout << "NR: ";
dump_array(nright, size - middle);
cout << "NL: ";
dump_array(nleft, middle);
cout << "OL: ";
dump_array(left, middle);
cout << "OR: ";
dump_array(right, size - middle);
int *result = merge(nleft, middle, nright, size - middle);
cout << "<<-- merge_sort:\n";
dump_array(result, size);
return result;
}
namespace {
int *merge(int *l, int m, int *r, int n)
{
int *result = new int[m + n];
int lsize = m;
int rsize = n;
int counter = 0;
cout << "-->> merge: (" << m << "," << n << ")\n";
dump_array(l, m);
dump_array(r, n);
while (lsize > 0 || rsize > 0)
{
if (lsize > 0 && rsize > 0)
{
if (l[0] <= r[0])
{
result[counter] = l[0];
cout << "C: " << counter << "; L = " << l[0] << "; LS = " << lsize << '\n';
counter++;
lsize--;
l++;
}
else
{
result[counter] = r[0];
cout << "C: " << counter << "; R = " << r[0] << "; RS = " << rsize << '\n';
counter++;
rsize--;
r++;
}
}
else if (lsize > 0)
{
result[counter] = l[0];
cout << "C: " << counter << "; L = " << l[0] << "; LS = " << lsize << '\n';
counter++;
lsize--;
l++;
}
else if (rsize > 0)
{
result[counter] = r[0];
cout << "C: " << counter << "; R = " << r[0] << "; RS = " << rsize << '\n';
counter++;
rsize--;
r++;
}
}
cout << "<<-- merge:\n";
dump_array(result, m+n);
return result;
}
};
int main()
{
for (int i = 2; i <= 10; i++)
{
int array1[] = { 9, 3, 5, 7, 1, 8, 0, 6, 2, 4 };
cout << "\nMerge array of size " << i << "\n\n";
int *result = merge_sort(array1, i);
delete[] result;
}
return 0;
}
This is the debug-laden code. It's the level to which I went to get the result. I could perhaps have used a debugger. Were I on a machine where valgrind works, it might have helped too (but it does not work on Mac OS X 10.8.x, sadly).
There are still many, many ways to improve the code — including the memory management. You'd probably find it easiest to pass the input array to merge() for use as the result array (avoiding the memory allocation in that code). This would reduce the memory management burden.
When you remove the debug code, you'll need to call the dump_array() function in the main() program to get the before and after sorting array images.
Code converted to template functions and leak-free
I've simplified the code a fair bit, especially in the merge() function. Also, more as a matter of curiosity than anything else, converted it to a set of template functions, and then used them with 4 different array types (int, double, std::string, char). The amount of debugging has been dramatically reduced, and the main debugging is conditional on being compiled with -DTRACE_ENABLED now.
The code is now leak-free; valgrind on a Linux box (virtual machine) gives it a clean bill of health when there are no exceptions. It is not guaranteed exception-safe, though. In fact, given the naked uses of new and delete, it is pretty much guaranteed not to be exception-safe. I've left the namespace control in place, but I'm far from convinced it is really correct — indeed, I'd lay odds on it not being good. (I'm also curious if anyone has any views on how to layout code within a namespace { … }; block; it seems odd not indenting everything inside a set of braces, but …)
#include <iostream>
using namespace std;
namespace {
#if !defined(TRACE_ENABLED)
#define TRACE_ENABLED 0
#endif
enum { ENABLE_TRACE = TRACE_ENABLED };
template <typename T>
void merge(T *l, int m, T *r, int n, T *result);
template <typename T>
void dump_array(const char *tag, T *a, int size)
{
int i;
cout << tag << ": (" << size << ") ";
for (i = 0; i < size; i++)
{
cout << " " << a[i];
if (i % 10 == 9)
cout << '\n';
}
if (i % 10 != 0)
cout << '\n';
}
};
template <typename T>
void merge_sort(T *a, int size)
{
if (size <= 1)
return;
if (ENABLE_TRACE)
dump_array("-->> merge_sort", a, size);
int middle = size/2;
T *left = new T[middle];
T *right = new T[size - middle];
for (int i = 0; i < middle; i++)
left[i] = a[i];
for (int j = 0; j < size - middle; j++)
right[j] = a[j + middle];
merge_sort(left, middle);
merge_sort(right, size - middle);
merge(left, middle, right, size - middle, a);
delete [] left;
delete [] right;
if (ENABLE_TRACE)
dump_array("<<-- merge_sort", a, size);
}
namespace {
template <typename T>
void merge(T *l, int m, T *r, int n, T *result)
{
T *l_end = l + m;
T *r_end = r + n;
T *out = result;
if (ENABLE_TRACE)
{
cout << "-->> merge: (" << m << "," << n << ")\n";
dump_array("L", l, m);
dump_array("R", r, n);
}
while (l < l_end && r < r_end)
{
if (*l <= *r)
*out++ = *l++;
else
*out++ = *r++;
}
while (l < l_end)
*out++ = *l++;
while (r < r_end)
*out++ = *r++;
if (ENABLE_TRACE)
dump_array("<<-- merge", result, m+n);
}
};
#include <string>
int main()
{
for (size_t i = 1; i <= 10; i++)
{
int array1[] = { 9, 3, 5, 7, 1, 8, 0, 6, 2, 4 };
if (i <= sizeof(array1)/sizeof(array1[0]))
{
cout << "\nMerge array of type int of size " << i << "\n\n";
dump_array("Original", array1, i);
merge_sort(array1, i);
dump_array("PostSort", array1, i);
}
}
for (size_t i = 1; i <= 10; i++)
{
double array2[] = { 9.9, 3.1, 5.2, 7.3, 1.4, 8.5, 0.6, 6.7, 2.8, 4.9 };
if (i <= sizeof(array2)/sizeof(array2[0]))
{
cout << "\nMerge array of type double of size " << i << "\n\n";
dump_array("Original", array2, i);
merge_sort(array2, i);
dump_array("PostSort", array2, i);
}
}
for (size_t i = 1; i <= 10; i++)
{
std::string array3[] = { "nine", "three", "five", "seven", "one", "eight", "zero", "six", "two", "four" };
if (i <= sizeof(array3)/sizeof(array3[0]))
{
cout << "\nMerge array type std::string of size " << i << "\n\n";
dump_array("Original", array3, i);
merge_sort(array3, i);
dump_array("PostSort", array3, i);
}
}
for (size_t i = 1; i <= 10; i++)
{
char array4[] = "jdfhbiagce";
if (i <= sizeof(array4)/sizeof(array4[0]))
{
cout << "\nMerge array type char of size " << i << "\n\n";
dump_array("Original", array4, i);
merge_sort(array4, i);
dump_array("PostSort", array4, i);
}
}
return 0;
}