Sort an array with recursion - c++

To start off this is a homework assignment and I am just looking for some pointers on using recursion.
I have an array of psuedo random integers of size n. I need to sort the array from lowest highest. Below is the recursive sort function that I have created but I know that I am missing a piece but I am not sure what.
template <typename T>
void sort_array_recur(T* random_array,T n)
{
//stop case
if(n = 1 )
{
if(random_array[n] < random_array[ n + 1 ])
{
T temp = random_array[n + 1];
random_array[n] == random_array[n + 1];
random_array[n + 1] == temp;
}
}
else
{
sort_array_recur(random_array, (n - 1));
}
}
I think what I am missing is some sort of insert function that also needs to be called recursively. I have also searched around and nothing seems particular to my situation (or at least I couldn't understand it as such). Thank you for your time in advance.
EDIT:
I guess I forgot to mention the spec says "sort the first n-1 elements of an n-element array. Then place the nth element in its proper position within the n-1 sorted elements". I guess I am not understanding how to sort the first the first n-1 elements of an array?

You are asked to use recursion. Your problem sorts a size n array. The first step is sorting n-1 elements of that array.
Consider m = n-1. Can you apply your problem to a size m array? i.e. sort the first m-1 elements and then place the m'th element in its correct position?
Consider k = m-1. Can you do the same with a size k array?
Do you see how you can use recursion with this problem?
Also consider how you will end the recursion; what will you do with a size 1 array?

Related

How to make a statement unnecessary with replace() in insertion-sort

I hope someone can help me out with this assignment. So we got this C++ algorithm by my professor:
template<class T> //Parameterized by the Type T
void insertion_sort(array<T>& A) //A is an array of Ts
//Permutes the elements of A into ascending sorted order
//The lower index bound of A is assumed to be 1
{ int n = A.size();
for(int k=2; k<=n; k++)
{ T x = A[k]; //x is a a variable of type T
//Insert x in the sorted sequence A[1], ..., A[k-1]
int i = k-1;
while (i>=1&&x<A[i]) //A[i] is evaluated only if i>=1
{ A[i+1]=A[i];
i--;
}
A[i+1]=x;
}
}
Ok. Now I have to use the function A.resize(0, n) between the lines 5 and 6 so that the statement "i>=1" in the while function becomes unnecessary. I understand that when this function is used the lower index bound of A becomes 0 instead of 1. But I do not see any use of that because I would still need that statement in the while. Does anyone have an idea?
I would be very grateful.
Thank you in advance!
To exclude i>=1 condition, you can move the smallest array element into the first position before the main loop.
Now this element becomes "sentinel" and it's presence excludes run out of array range.
If it is strictly needed to use your resize, then just set the smallest possible value (look at lowest) to new element with 0-th index.
We can not know about "magic" routines from some library

Find index of n number of small elements next to each others in array

I am stuck in a simple problem. I need to find index of n numbers of smallest elements next to each others in an array. So if my array is [-1,-3,4,2,-5,-6] and n=3 my answer would be 5,4 and 1(because first 3 smallest elements are -6(index 5),-5(index 4) and -3(index 1)). What would be the best way to do it in C++ without any library function ? This is what i came up with :
int getPos(int* arr,int n,int y)
{
for(int i=0;i<n;i++)
{
if(arr[i]==y)
return i;
}
}
int* sorted=new int[n];
for(int i=0;i<n;i++)
{
sorted[i]=diff[i];
}
sort(sorted,sorted+n);
for(int i=0;i<d;i++)
{
int y=sorted[i];
int k=getPos(diff,n,y);
}
Here diff is the unsorted array and sorted is the sorted array. This function works fine when there is no repeated element. But if my diff array is [-1,-1,2,-2,-2] and sorted array is [-2,-2,-1,-1,2] So in 1st iteration it grabs index for -2. Now in 2nd iteration it will again grab index of index of -2(1st -2 in my array not the 2nd) . So how to make my code work for repeating elements ?
Break down your task to smaller tasks and them achieve each small task in c++. You basically want:
To find the smallest item of an array n times.
For each min item, get it's index as well.
Output the found indexs to screen.
That's not very complicated. Do some research about the basics such as loops (to do something n times), functions (to do the same code of finding the smallest item in an array - with functions you write it once and call it again when you want to use that code) - you can also use known sorting functions, arrays in c++ and output to screen.
First try writing your own code before asking for it here :)

Create a function that checks whether an array has two opposite elements or not for less than n^2 complexity. (C++)

Create a function that checks whether an array has two opposite elements or not for less than n^2 complexity. Let's work with numbers.
Obviously the easiest way would be:
bool opposite(int* arr, int n) // n - array length
{
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
if(arr[i] == - arr[j])
return true;
}
}
return false;
}
I would like to ask if any of you guys can think of an algorithm that has a complexity less than n^2.
My first idea was the following:
1) sort array ( algorithm with worst case complexity: n.log(n) )
2) create two new arrays, filled with negative and positive numbers from the original array
( so far we've got -> n.log(n) + n + n = n.log(n))
3) ... compare somehow the two new arrays to determine if they have opposite numbers
I'm not pretty sure my ideas are correct, but I'm opened to suggestions.
An important alternative solution is as follows. Sort the array. Create two pointers, one initially pointing to the front (smallest), one initially pointing to the back (largest). If the sum of the two pointed-to elements is zero, you're done. If it is larger than zero, then decrement the back pointer. If it is smaller than zero, then increment the front pointer. Continue until the two pointers meet.
This solution is often the one people are looking for; often they'll explicitly rule out hash tables and trees by saying you only have O(1) extra space.
I would use an std::unordered_set and check to see if the opposite of the number already exist in the set. if not insert it into the set and check the next element.
std::vector<int> foo = {-10,12,13,14,10,-20,5,6,7,20,30,1,2,3,4,9,-30};
std::unordered_set<int> res;
for (auto e : foo)
{
if(res.count(-e) > 0)
std::cout << -e << " already exist\n";
else
res.insert(e);
}
Output:
opposite of 10 alrready exist
opposite of 20 alrready exist
opposite of -30 alrready exist
Live Example
Let's see that you can simply add all of elements to the unordered_set and when you are adding x check if you are in this set -x. The complexity of this solution is O(n). (as #Hurkyl said, thanks)
UPDATE: Second idea is: Sort the elements and then for all of the elements check (using binary search algorithm) if the opposite element exists.
You can do this in O(n log n) with a Red Black tree.
t := empty tree
for each e in A[1..n]
if (-e) is in t:
return true
insert e into t
return false
In C++, you wouldn't implement a Red Black tree for this purpose however. You'd use std::set, because it guarantees O(log n) search and insertion.
std::set<int> s;
for (auto e : A) {
if (s.count(-e) > 0) {
return true;
}
s.insert(e);
}
return false;
As Hurkyl mentioned, you could do better by just using std::unordered_set, which is a hashtable. This gives you O(1) search and insertion in the average case, but O(n) for both operations in the worst case. The total complexity of the solution in the average case would be O(n).

Using a hash to find one duplicated and one missing number in an array

I had this question during an interview and am curious to see how it would be implemented.
Given an unsorted array of integers from 0 to x. One number is missing and one is duplicated. Find those numbers.
Here is what I came up with:
int counts[x+1];
for(int i =0;i<=x; i++){
counts[a[i]]++;
if(counts[a[i]] == 2)
cout<<”Duplicate element: “<<a[i]; //I realized I could find this here
}
for(int j=0; j<=x; j++){
if(counts[j] == 0)
cout<<”Missing element: “<<j;
//if(counts[j] == 2)
// cout<<”Duplicate element: “<<j; //No longer needed here.
}
My initial solution was to create another array of size x+1, loop through the given array and index into my array at the values of the given array and increment. If after the increment any value in my array is two, that is the duplicate. However, I then had to loop through my array again to find any value that was 0 for the missing number.
I pointed out that this might not be the most time efficient solution, but wasn't sure how to speed it up when I was asked. I realized I could move finding the duplicate into the first loop, but that didn't help with the missing number. After waffling for a bit, the interviewer finally gave me the idea that a hash would be a better/faster solution. I have not worked with hashes much, so I wasn't sure how to implement that. Can someone enlighten me? Also, feel free to point out any other glaring errors in my code... Thanks in advance!
If the range of values is the about the same or smaller than the number of values in an array, then using a hash table will not help. In this case, there are x+1 possible values in an array of size x+1 (one missing, one duplicate), so a hash table isn't needed, just a histogram which you've already coded.
If the assignment were changed to be looking for duplicate 32 bit values in an array of size 1 million, then the second array (a histogram) could need to be 2^32 = 4 billion counts long. This is when a hash table would help, since the hash table size is a function of the array size, not the range of values. A hash table of size 1.5 to 2 million would be large enough. In this case, you would have 2^32 - 2^20 = 4293918720 "missing" values, so that part of the assignment would go away.
Wiki article on hash tables:
Hash Table
If x were small enough (such that the sum of 0..x can be represented), you could compute the sum of the unique values in a, and subtract that from the sum of 0..x, to get the missing value, without needing the second loop.
Here is a stab at a solution that uses an index (a true key-value hash doesn't make sense when the array is guaranteed to include only integers). Sorry OP, it's in Ruby:
values = mystery_array.sort.map.with_index { |n,i| n if n != i }.compact
missing_value,duplicate_value = mystery_array.include?(values[0] - 1) ? \
[values[-1] + 1, values[0]] : [values[0] - 1, values[-1]]
The functions used likely employ a non-trivial amount of looping behind the scenes, and this will create a (possibly very large) variable values which contains a range between the missing and/or duplicate value, as well as a second lookup loop, but it works.
Perhaps the interviewer meant to say Set instead of hash?
Sorting allowed?
auto first = std::begin(a);
auto last = std::end(a);
// sort it
std::sort( first, last );
// find duplicates
auto first_duplicate = *std::adjacent_find( first, last );
// find missing value
auto missing = std::adjacent_find(first, last, [](int x, int y) {return x+2 == y;});
int missing_number = 0;
if (missing != last)
{
missing_number = 1+ *missing;
}
else
{
if (counts[0] != 0)
{
missing_number = 0;
}
else
{
missing_number = 9;
}
}
Both could be done in a single hand-written loop, but I wanted to use only stl algorithms. Any better idea for handling the corner cases?
for (i=0 to length) { // first loop
for( j=0 to length ){ // second loop
if (t[i]==j+1) {
if (counter==0){//make sure duplicated number has not been found already
for( k=i+1 to length ) { //search for duplicated number
if(t[k]==j+1){
j+1 is the duplicated number ;
if(missingIsFound)
exit // exit program, missing and dup are found
counter=1 ;
}//end if t[k]..
}//end loop for duplicated number
} // end condition to search
continue ; // continue to first loop
}
else{
j+1 is the missing number ;
if(duplicatedIsFound)
exit // exit program, missing and dup are found
continue ; //continue to first loop
}//end second loop
} //end first loop

Is this a shell sort or an insertion sort?

I'm just starting to learn about sorting algorithms and found one online. At first i thought it was a shell sort but it's missing that distinct interval of "k" and the halving of the array so i'm not sure if it is or not. My second guess is an insertion sort but i'm just here to double check:
for(n = 1; n < num; n++)
{
key = A[n];
k = n;
while((k > 0) && (A[k-1] > key))
{
A[k] = A[k-1];
k = k-1;
}
A[k] = key;
}
Also if you can explain why that'd be helpful as well
Shell Sort consists of many insertion sorts that are performed on sub-arrays of the original array.
The code you have provided is insertion sort.
To get shell sort, it would be roughly having other fors around your code changing h (that gap in shell sort) and starting index of the sub-array and inside, instead of moving from k to k-1, you move from k to k+h (or k-h depending on which direction you do the insertion sort)
I think you're right, that does look a lot like an insertion sort.
This fragment assumes A[0] is already inserted. If n == 0, then the k > 0 check will fail and execution will continue at A[k] = key;, properly storing the first element into the array.
This fragment also assumes that A[0:n-1] is already sorted. It inspects A[n] and starts scanning the array backward, moving forward one place every element that is larger than the original A[n] key.
Once the scanning encounters an element less than or equal to the key, it inserts it in that location.
It's called insertion sort because the line A[k] = key inserts the current value in the correct position in the partially sorted array.