C++ Sorting Array Recursion - c++

I am creating a small program that is supposed to sort integers in an array in ascending order, but I am extremely stuck on the algorithm that I am supposed to use. I cannot iterate through the array, I must instead use a recursion function. I am allowed to have an auxiliary function that can find the smallest index in the array, which I have done successfully, but I am having the hardest time figuring out how to use that function to sort my array in the recursion function. Here is the code that I have so far, I understand that my sortIntegers function is way off.
int main()
{
int numbers[] = {8, 2, 5, 1, 3};
sortingIntegers(numbers, 5);
return 0;
}
void sortingIntegers(int *list, int size) {
if (size == 1) {
for (int i = 0; i < size; i++) {
cout << list[i] << ", ";
}
} else {
for (int z = 0; z < size; z++) {
if (list[size - 1] == smallestIndex(list)) {
for (int y = 0; y < size; y++) {
swap(list[z], list[y]);
}
}
}
sortingIntegers(list, size - 1);
}
}
int smallestIndex(int *array) {
int smallest = array[0];
for (int i = 1; i < sizeof(array); i++) {
if (array[i] < smallest) {
smallest = array[i];
}
}
return smallest;
}

int main()
{
int numbers[] = {8, 2, 5, 1, 0};
sortingIntegers(numbers, 0, 5);
for (int i=0;i<5;i++)
cout << numbers[i] << ' ';
return 0;
}
void sortingIntegers(int *list, int left, int size) {
if (left == size)
return;
int smallest = smallestIndex(list, left, size);
int c = list[smallest];
list[smallest] = list[left];
list[left] = c;
sortingIntegers(list, left+1 ,size);
}
int smallestIndex(int *array, int left, int size) {
int smallest = array[left];
int smIndex = left;
for (int i = left+1; i < size; i++) {
if (array[i] < smallest) {
smallest = array[i];
smIndex = i;
}
}
return smIndex;
}
That's my solution based on yours. First of all sizeof(array) returns the size of pointer. Second I return the index of the smallest item, not it's value, then I swap it with the first element in list. And then I call the sorting for the list starting with another element (the left parameter), because I know that the list up to left-1 is already sorted.

A fully recursive solution:
To sort an array, find the smallest element and swap it to the first position. Then sort the rest of the array, until there is a single element left.
To find the smallest element in an array, take the smallest of -the first element and -the smallest element in the rest of the array, until there is a single element left.
int SmallestIndex(int Array[], int From, int To)
{
if (From == To-1)
return From; // Single element left
// Index of the smallest in the rest
int Index= SmallestIndex(Array, From + 1, To);
// Index of the smallest
return Array[From] < Array[Index] ? From : Index;
}
void Sort(int Array[], int From, int To)
{
if (From == To-1)
return; // Single element left
// Locate the smallest element
int Index= SmallestIndex(Array, From, To);
// Swap it to the first place
int Swap= Array[Index]; Array[Index]= Array[From]; Array[From]= Swap;
// Sort the rest
Sort(Array, From + 1, To);
}
Call Sort with (Array, 0, N).

You can use this snippet to sort an array using recursion. It's not difficult you need to think like this way if your array length is N recursion sort N - 1 length array and you have to sort only one element that is N or you can say the last element. I give you an example it will help you suppose you have to sort this array = [50, 40, 10, 30, 20] if recursion gives you array = [10,30,40,50,20] this array you just need to place 20 in a correct position to sort the array.
private static void sort(int[] array, int length) {
if (length == 1) return;
sort(array, length - 1);
var lastIndex = length - 1;
for (int index = lastIndex; index > 0; index --){
if (array[index] < array[index - 1]){
int temp = array[index];
array[index] = array[index - 1];
array[index - 1] = temp;
}
}
}

Related

Appears K times in an array C++

So I have an algorithm that is suppose to return the int that appears K times in an array. If more than 1 int appears K times, the higher value should be returned. My following algorithm is not working correctly. In the example below, it returns 1 when it should be returning 5.
#include <iostream>
#include <algorithm>
int appearsKTimes (int size, int inputArray[], int k) {
std::sort(inputArray, inputArray + size);
int i = 1, count = 1;
int element = inputArray[0];
int res = -1;
while (i < size) {
if (element == inputArray[i]) {
count++;
} else {
if (count == k) {
res = element;
}
element = inputArray[i];
count = 1;
}
i++;
}
std::cout << res << std::endl;
return res;
}
int main() {
const int size = 7;
int array[size] = {1, 1, 2, 2, 2, 5, 5};
int occurences = 2;
appearsKTimes(size, array, occurences);
}
if (count == k) {
res = element;
}
std::cout << res << std::endl;
check the count of the last element.
I also think it will be better to count from the end.You need to check the all array all the time if you count from the first element.
Your approach with sorting is good and requires only O(NlogN) time complexity, but consider an another one with hash table as well. It requires O(N) in time and O(N) in space. It is shorter and has only a few extra variables, so there is less chance of making mistake:
1) Compute number frequencies with unordered_map (hash table): O(N)
2) Find the largest number with exactly k occurences: O(N)
int appearsKTimes (int size, int inputArray[], int k) {
unordered_map<int, int> freqs;
for (int i = 0; i < size; i++) {
freqs[inputArray[i]]++;
}
int res = - 1;
for (int i = 0; i < size; i++) {
if (freqs[inputArray[i]] == k)
res = max(res, inputArray[i]);
}
return res;
}

Sorting an array of values by shifting to the right

I have to make a method that sorts an array of values going from lowest value to the highest. The way these functions are supposed to work is that it grabs each value, tries to put them in rising order going from left to right by shifting every bigger value to the right.
I have made the following functions:
int findIndex(double *arr, double num, int length)
{
for (int i = 0; i < length; i++)
{
if (arr[i] > num)
return i;
}
return length - 1;
}
void placeOnIndex(double *arr, double num,int index, int length)
{
if (length > 1 && arr[index] != num)
{
for (int i = length - 1; i > 0; i--)
{
arr[i] = arr[i - 1];
}
arr[index] = num;
}
}
void insertSort(double* arr, int length)
{
for (int ix = 0; ix < length; ix++)
{
double num = arr[ix]; //Current value to put as far to the left as possible
int index = findIndex(arr, num, ix+1); //Locates index to put it
placeOnIndex(arr, num, index, ix+1); //Uses the index to put in the right place
}
}
void main()
{
double arr[4] = {1,8,4,5};
insertSort((arr), 4);
}
My problem is that the output with this array becomes:
1,1,5,8
Apparently it sometimes overrides the second element in my array. Sometimes it works and sometimes it doesn't. If the array is longer even more values are overridden.
I'm sorry if it looks confusing, english isn't my native tongue.
This line
for (int i = length - 1; i > 0; i--)
causes all the elements to move right, not just the ones that should move.
You need
for (int i = length - 1; i > index; i--)

c++ recursive quicksort infinite loop

So I've been having a problem with a c++ program that quicksorts an array of integers. When I have more than six elements in my array, the sort infinitely loops for some reason. I think I've isolated the problem to the choosing of mm pivotal value, but I can't work out for the life of me why it's causing it to break.
#include<iostream>
using namespace std;
int getPivot(int begin,int end){//Takes length of array as input and returns the position of the pivot
int len = end-begin;
if(len < 3){
return end;
}else{
return 2;
}
};
void quickSort(int begin, int end, int arr[]){
int pivot = arr[getPivot(begin,end)];//get Pivotal value - If I replace this with just 0 then there are no problems...
int tempLeft = begin, tempRight = end;
int temp;
while(tempLeft <= tempRight){
while(arr[tempLeft] < pivot){//Find a point where there are 2 elements that need to be swapped
tempLeft++;
}
while(arr[tempRight] > pivot){
tempRight--;
}
if(tempLeft <= tempRight){
temp = arr[tempLeft];//Swap the elements
arr[tempLeft] = arr[tempRight];
arr[tempRight] = temp;
tempLeft++;//Skip these swapped elements in the sort
tempRight--;
}
}
if (begin < tempRight){//Only recurse lower if the new sub array has a length greater than 1
quickSort(begin, tempRight, arr);
}
if (tempLeft < end){
quickSort(tempLeft, end, arr);
}
}
main() {
int array[] = {0,1,2,3,4,5,6};
int length = 7;
quickSort(0,length-1,array);
}
You will probably ask why I have such a weird way of choosing my pivotal value, but lets just say that for this instance the pivotal value has to be the third element in each sublist or if the sub list is smaller than 3 it is the last item in the sublist.
The reason I think the problem is associated with the pivotal value is because when I replace my method of choosing a pivot with just using the first element in the sublist I don't have any problems.
If run, as is now the program, will segfault after looping infinitely but if the array being sorted is one element shorter, it will work fine. That has had me baffled for hours now, and I can't work out what the problem is. If anyone has any tips or suggestions, they would be greatly appreciated.
quickSort(3,6,arr) will always call quickSort(3,6,arr).
I think you miss
int getPivot(int begin,int end)
{
//Takes length of array as input and returns the position of the pivot
int len = end-begin;
if(len < 3){
return end;
}else{
return 2+begin; // Here
}
};
EDIT: Clarification
GetPivot(3,6) will return 2, instead should return an index between 3 and 6.
You could also use the median of three approach for your pivot. It is a little more robust.
#include<iostream>
using namespace std;
void myswap(int* arr, int left, int right)
{
int swap = arr[left];
arr[left] = arr[right];
arr[right] = swap;
}
int getPivotIndex(int* arr, int begin, int end){
int middle = (begin + end) / 2;
if (arr[end] < arr[begin])
{
myswap(arr, begin, end);
}
if (arr[middle] < arr[begin])
{
myswap(arr, middle, begin);
}
if (arr[end] < arr[middle])
{
myswap(arr, end, middle);
}
return middle;
};
void quickSort(int begin, int end, int* arr){
int pivot = arr[getPivotIndex(arr, begin, end)];
int tempLeft = begin, tempRight = end;
while (tempLeft <= tempRight){
while (arr[tempLeft] < pivot){
tempLeft++;
}
while (arr[tempRight] > pivot){
tempRight--;
}
if (tempLeft <= tempRight){
myswap(arr, tempLeft, tempRight);
tempLeft++;
tempRight--;
}
}
if (begin < tempRight){
quickSort(begin, tempRight, arr);
}
if (tempLeft < end){
quickSort(tempLeft, end, arr);
}
}
int main() {
int array[] = { 6, 0, 2, 5, 4, 3, 1 }; // Test we are actually sorting
int length = 7;
quickSort(0, length - 1, array);
for (int i = 0; i < length; i++)
{
std::cout << "array[" << i << "]: " << array[i] << endl;
}
return 0;
}

Inserting value into sorted array without duplicates: C++

For this program I have three data files. The first has a list of numbers, the second is a list of numbers with an add (A) or delete (D) command. I have to put the numbers from the first file into the third file, then update the final file based on the commands and numbers in the second file. The third file cant have duplicates and must be sorted while values are being inserted. Here are the functions I have, I'm having difficulty getting the items stored into the array without duplicates. The array must be statically sized, I did a #define of max size 2000 which is more than enough to handle the numbers I need. Thanks so much! If I should upload the main let me know, but I'm fairly certain the problem lies in one of these functions.
int search(int value, int list[], int n) // returns index, n is logical size of array
{
int index = -1;
for(int i = 0; i < n; i++)
{
if(value == list[i])
{
index = i;
return index;
}
}
return index;
}
void storeValue(int value, int list[], int& n)
{
int i = n;
for(; i > 0 && list[i - 1] < value; i--)
{
list[i] = list[i - 1];
}
list[i] = value;
n++;
}
void deleteValue(int loc, int list[], int n)
{
if(loc >= 0 && loc < n)
{
for(int i = loc; i < n - 1; i++)
list[i] = list[i +1];
n--;
}
}
UPDATE: Now duplicates are being stored, but only for some numbers.
For example: my 3rd file is: 1,2,8,8,9,101,101,104,etc.
The output should be: 1,2,8,9,101,104,etc
value: value to be inserted
list[]: array being modified (must be static)
n: logical size of array
I can't figure out why some numbers are duplicated and others aren't
In my main, I run the search function and if a -1 is returned (the value isn't already found) then I run the storeValue function.
Here are my updated functions:
int search(int value, int list[], int n) // returns index
{
int index = -1;
for(int i = 0; i < n; i++)
{
if(value == list[i])
{
index = i;
return index;
}
}
return index;
}
void storeValue(int value, int list[], int& n)
{
int i = n;
for(; i > 0 && list[i - 1] > value; i--)
{
list[i] = list[i - 1];
}
list[i] = value;
n++;
}
void deleteValue(int loc, int list[], int& n)
{
if(loc >= 0 && loc < n)
{
for(int i = loc; i < n; i++)
{
if (i == loc)
{
list[i] = list[i + 1];
i++;
}
}
n--;
}
}
In your deleteValue function, you are deleting the value, but will end up with a duplicate because you are just reassigning the current index to the next value. For example, if you have the array:
char array[3] = [1, 2, 3];
and you wanted to delete the second integer, your function currently would output this:
[1, 3, 3]
What you want to do is make a new array and loop through your entire list, making sure to leave out the last element like so:
char* deleteValue(int loc, int list[], int n)
{
char* newArray[n - 1];
if (loc >= 0 && loc < n)
{
for (int i = 0; i < n - 1; i++)
{
if (i == loc) // You have arrived at the element that needs to be deleted
{
newArray[i] = list[i + 1];
i++; // So we skip over the deleted element
}
else
newArray[i] = list[i];
}
}
return newArray;
}
And this should take care of the case where the last value is duplicated.

How does one rank an array (sort) by value? *With a twist*

I would like to sort an array in ascending order using C/C++. The outcome is an array containing element indexes. Each index is corespondent to the element location in the sorted array.
Example
Input: 1, 3, 4, 9, 6
Output: 1, 2, 3, 5, 4
Edit: I am using shell sort procedure. The duplicate value indexes are arbitrarily chosen based on which duplicate values are first in the original array.
Update:
Despite my best efforts, I haven't been able to implement a sorting algorithm for an array of pointers. The current example won't compile.
Could someone please tell me what's wrong?
I'd very much appreciate some help!
void SortArray(int ** pArray, int ArrayLength)
{
int i, j, flag = 1; // set flag to 1 to begin initial pass
int * temp; // holding variable orig with no *
for (i = 1; (i <= ArrayLength) && flag; i++)
{
flag = 0;
for (j = 0; j < (ArrayLength - 1); j++)
{
if (*pArray[j + 1] > *pArray[j]) // ascending order simply changes to <
{
&temp = &pArray[j]; // swap elements
&pArray[j] = &pArray[j + 1]; //the problem lies somewhere in here
&pArray[j + 1] = &temp;
flag = 1; // indicates that a swap occurred.
}
}
}
};
Since you're using C++, I would do it something like this. The SortIntPointers function can be any sort algorithm, the important part is that it sorts the array of pointers based on the int that they are pointing to. Once that is done, you can go through the array of pointers and assign their sorted index which will end up in the original position in the original array.
int* intArray; // set somewhere else
int arrayLen; // set somewhere else
int** pintArray = new int*[arrayLen];
for(int i = 0; i < arrayLen; ++i)
{
pintArray[i] = &intArray[i];
}
// This function sorts the pointers according to the values they
// point to. In effect, it sorts intArray without losing the positional
// information.
SortIntPointers(pintArray, arrayLen);
// Dereference the pointers and assign their sorted position.
for(int i = 0; i < arrayLen; ++i)
{
*pintArray[i] = i;
}
Hopefully that's clear enough.
Ok, here is my atempt in C++
#include <iostream>
#include <algorithm>
struct mycomparison
{
bool operator() (int* lhs, int* rhs) {return (*lhs) < (*rhs);}
};
int main(int argc, char* argv[])
{
int myarray[] = {1, 3, 6, 2, 4, 9, 5, 12, 10};
const size_t size = sizeof(myarray) / sizeof(myarray[0]);
int *arrayofpointers[size];
for(int i = 0; i < size; ++i)
{
arrayofpointers[i] = myarray + i;
}
std::sort(arrayofpointers, arrayofpointers + size, mycomparison());
for(int i = 0; i < size; ++i)
{
*arrayofpointers[i] = i + 1;
}
for(int i = 0; i < size; ++i)
{
std::cout << myarray[i] << " ";
}
std::cout << std::endl;
return 0;
}
create a new array with increasing values from 0 to n-1 (where n is the length of the array you want to sort). Then sort the new array based on the values in the old array indexed by the values in the new array.
For example, if you use bubble sort (easy to explain), then instead of comparing the values in the new array, you compare the values in the old array at the position indexed by a value in the new array:
function bubbleRank(A){
var B = new Array();
for(var i=0; i<A.length; i++){
B[i] = i;
}
do{
swapped = false;
for(var i=0; i<A.length; i++){
if(A[B[i]] > A[B[i+1]]){
var temp = B[i];
B[i] = B[i+1];
B[i+1] = temp;
swapped = true;
}
}
}while(swapped);
return B;
}
create a new Array and use bubble sort to rank the elements
int arr[n];
int rank[n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(arr[i]>arr[j])
rank[i]++;
The rank of each element will be rank[i]+1 to be in the order of 1,2,....n
Well, there's a trival n^2 solution.
In python:
newArray = sorted(oldArray)
blankArray = [0] * len(oldArray)
for i in xrange(len(newArray)):
dex = oldArray.index(newArray[i])
blankArray[dex] = i
Depending on how large your list is, this may work. If your list is very long, you'll need to do some strange parallel array sorting, which doesn't look like much fun and is a quick way to introduce extra bugs in your code.
Also note that the above code assumes unique values in oldArray. If that's not the case, you'll need to do some post processing to solve tied values.
Parallel sorting of vector using boost::lambda...
std::vector<int> intVector;
std::vector<int> rank;
// set up values according to your example...
intVector.push_back( 1 );
intVector.push_back( 3 );
intVector.push_back( 4 );
intVector.push_back( 9 );
intVector.push_back( 6 );
for( int i = 0; i < intVector.size(); ++i )
{
rank.push_back( i );
}
using namespace boost::lambda;
std::sort(
rank.begin(), rank.end(),
var( intVector )[ _1 ] < var( intVector )[ _2 ]
);
//... and because you wanted to replace the values of the original with
// their rank
intVector = rank;
Note: I used vectorS instead of arrays because it is clearer/easier, also, I used C-style indexing which starts counting from 0, not 1.
This is a solution in c language
#include <stdio.h>
void swap(int *xp, int *yp) {
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(int arr[], int n) {
int i, j;
for (i = 0; i < n - 1; i++)
// Last i elements are already in place
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(&arr[j], &arr[j + 1]);
}
/* Function to print an array */
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 98};
int arr_original[] = {64, 34, 25, 12, 22, 11, 98};
int rank[7];
int n = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
//PLACE RANK
//look for location of number in original array
//place the location in rank array
int counter = 1;
for (int k = 0; k < n; k++){
for (int i = 0; i < n; i++){
printf("Checking..%d\n", i);
if (arr_original[i] == arr[k]){
rank[i] = counter;
counter++;
printf("Found..%d\n", i);
}
}
}
printf("Original array: \n");
printArray(arr_original, n);
printf("Rank array: \n");
printArray(rank, n);
return 0;
}