Insertion sort using pointer to an array - c++

My code is:
#include <iostream>
using namespace std;
void insertion(int*, int);
int main() {
int a[6] = {9, 5, 3, 7, 5, 6};
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
insertion(&a[0], 6);
cout << "now insertion sort \n";
for (int x = 0; x < 6; x++)
cout << a[x] << "\n";
return 0;
}
void insertion(int* l, int m) {
int temp;
for (int i = 0; i < m; i++) {
while (*(l + i) > *(l + 1 + i) && (i > 0)) {
temp = *(l + i);
*(l + i + 1) = *(l + i);
*(l + i) = temp;
i--;
}
}
}
What is wrong with the function sorting?
The output that I'm getting is: 9 5 5 7 7 7
What other details should I add (this is my first doubt in stackoverflow)?

Your logic isn't really correct for an insertion sort. In fact, what you have right now is much closer to a bubble sort (though it's obviously not quite right for that either).
For an insertion sort, the logic goes something like this (assuming 0-based indexing):
for i = 1 to array_length
if array[i] < array[i-1]
temp = array[i]
for j = i downto 1 && temp < array[j-1]
array[j] = array[j-1]
array[j-1] = temp
endif
So the basic idea here is that for each element, we search backwards through the array to find the right place to put that element. As we do so, we shift elements upwards by one spot, so when we got to the right spot, we have a place to put it.
Note, in particular, that this doesn't contain any swap-like code anywhere. We don't normally plan on swapping adjacent elements as you've done. It can/will happen when/if an element happens to be out of place by exactly one position, but it's pretty much incidental when it does.

Related

execution order for cout in C++

c++
When printing to console, if function execution is sequential it would seem logical the ordered array would be printed after calling insertionSort, however order list does not print until next loop. Any help would be appreciated.
#include <stdio.h>
#include <iostream>
#include <array>
using namespace std;
void insertionSort(int* array, int size) {
for (int i = 1; i < size; i++) {
int key = i - 1;
while (i > 0 && array[key] > array[i] ) {
int tmp = array[i];
array[i] = array[key];
array[key] = tmp;
i -= 1;
key -= 1;
}
}
}
const int ARRAY_MAXSIZE = 5;
int main(void) {
int *array = (int*)calloc(ARRAY_MAXSIZE, sizeof(int));
int input;
cout << "Enter 5 digits\n";
for (int size=0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
insertionSort(array, size);
for (int j=0; j <= size; j++) {
cout << array[j];
}
cout << '\n';
}
}
Console Entry
This is a classic off-by-one error. Your insertionSort expects you to pass the number of elements to sort via the parameter size. But your main loop is always holding a value that is one less than the size immediately after adding an element.
I want to say that bugs like this are easily discovered by stepping through your program's execution with a debugger. If you don't know how to use a debugger, start learning now. It is one of the most important tools used by developers.
Anyway, the quick fix is to change your function call to:
insertionSort(array, size + 1);
However, as Paul McKenzie pointed out in comments, it's a bit crazy to do this every time you add a new element because your function sorts an entire unsorted array. Your array is always nearly sorted except for the last element. You only need to call that function once after your input loop is done:
// Read unsorted data
for (int size = 0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
}
// Sort everything
insertionSort(array, ARRAY_MAXSIZE);
// Output
for (int j = 0; j < ARRAY_MAXSIZE; j++) {
cout << array[j];
}
cout << '\n';
But if you want every insertion to result in a sorted array, you can "slide" each new value into place after inserting it. It's similar to a single iteration of your insertion-sort:
// Sort the last element into the correct position
for (int i = size; i >= 1 && array[i] > array[i - 1]; i--)
{
std::swap(array[i], array[i - 1]);
}
Even better, you don't need to swap all those values. You simply read the value, then shuffle the array contents over to make room, then stick it in the right spot:
// Read next value
cin >> input;
// Shuffle elements to make room for new value
int newPos = size;
while (newPos > 0 && array[newPos - 1] > input) {
array[newPos] - array[newPos - 1];
newPos--;
}
// Add the new value
array[newPos] = input;

How do i access specific indexes within an array using pointers in C+?

I have a program I am writing that prints out a Fibonacci Sequence up to 30 numbers. I must do this by traversing the array using pointers, but I don't know how to.
There is not a lot of easy to follow information that I can understand.
When I see the code for c++ answers to this, all I see is this...
I'm a noob and I am having a hard time looking at all of the 'std::' conventions when I have to look at code. I know it's probably good convention, but I am not good with it yet. So I would like a straightforward example, assuming I am using the using namespace std; line of code within my project.
I have tried setting the for..loop up with the pointer variable but I am not sure how to do this.
void fibonacciSequence(){
//initialize the array and users input
const int ARRAY_SIZE = 30;
int numbers[ARRAY_SIZE];
int *pointer;
pointer = numbers;
//Traverse the array and generate the Fibonacci Sequence
for(int i = 0; i < ARRAY_SIZE; i++){
//Set first element to 0
if(i == 0){
numbers[i] = 0;
}
//Set second element to 1
else if (i == 1){
numbers[i] = 1;
}
//Start calculating the sequence after the first 2 elements
//have been established.
else{
numbers[i] = numbers[(i - 1)] + numbers[(i - 2)];
}
}
// Output the Fibonacci Sequence after calculations.
for(int i = 0; i < ARRAY_SIZE; i++){
cout << numbers[i] << endl;
}
}
This code I have works perfectly. But instead of traversing the array using 'i' in the for...loop, i need to use 'pointer.'
It's actually very simple change this
for(int i = 0; i < ARRAY_SIZE; i++){
cout << numbers[i] << endl;
}
to this
for(int* p = numbers; p < numbers + ARRAY_SIZE; p++){
cout << *p << endl;
}
Explanation
int* p = numbers - set p to point to the beginning of the array
p < numbers + ARRAY_SIZE - check p hasn't reached the end of the array
p++ - move p on to the next element of the array
*p - access the element that p is pointing to
Similar changes to your first loop.
This whole topic is pointer arithmetic, maybe you could do some research.
This probably isn't a good project for learning pointers, since indexing is the most natural way of computing a fibanocci sequence. But here goes. Replace that generator loop with this:
int *current = numbers;
*current++ = 0;
*current++ = 1;
while (current != numbers + ARRAY_SIZE) {
*current = *(current - 1) + *(current - 2);
++current;
}
And then for the output:
for (current = numbers; current != numbers + ARRAY_SIZE; ++current)
std::cout << *current << '\n';

Bubble Sort Using Slides instead of swaps

currently I'm being asked to design four sorting algorithms (insertion, shell, selection, and bubble) and I have 3 of the 4 working perfectly; the only one that isn't functioning correctly is the Bubble Sort. Now, I'm well aware of how the normal bubble sort works with using a temp var to swap the two indexes, but the tricky part about this is that it needs to use the array index[0] as a temp instead of a normal temp, which is used in swapping, and slide the lower array variables down to the front of the list and at the end of the pass assign the last index to the temp which is the greatest value.
I've been playing around with this for a while and even tried to look up references but sadly I cannot find anything. I'm hoping that someone else has done this prior and can offer some helpful tips. This is sort of a last resort as I've been modifying and running through the passes with pen and paper to try and find my fatal error. Anyways, my code is as follows...
void BubbleSort(int TheArray[], int size)
{
for (int i = 1; i < size + 1; i++)
{
TheArray[0] = TheArray[i];
for (int j = i + 1; j < size; j++)
{
if (TheArray[j] > TheArray[0])
TheArray[0] = TheArray[j];
else
{
TheArray[j - 1] = TheArray[j];
}
}
TheArray[size- 1] = TheArray[0];
}
}
Thanks for any feedback whatsoever; it's much appreciated.
If I understand the problem statement, I think you're looking for something along these lines :
void BubbleSort(int theArray[], int size)
{
for (int i = 1; i < size + 1; i++)
{
theArray[0] = theArray[1];
for (int j = 1; j <= size + 1 - i; j++)
{
if (theArray[j] > theArray[0])
{
theArray[j-1] = theArray[0];
theArray[0] = theArray[j];
}
else
{
theArray[j - 1] = theArray[j];
}
}
theArray[size-i+1] = theArray[0];
}
}
The piece that you're code was missing, I think, was that once you find a new maximum, you have to put it back in the array before placing the new maximum in theArray[0] storage location (see theArray[j-1] = theArray[0] after the compare). Additionally, the inner loop wants to run one less each time since the last element will be the current max value so you don't want to revisit those array elements. (See for(int j = 1 ; j <= size + 1 - i ; j++))
For completeness, here's the main driver I used to (lightly) test this :
int main()
{
int theArray[] = { 0, 5, 7, 3, 2, 8, 4, 6 };
int size = 7;
BubbleSort(theArray, size);
for (int i = 1; i < size + 1; i++)
cout << theArray[i] << endl;
return 0;
}

a function that takes an array A and index i and rearrange it

Question is: write a function that takes an array A of length n and an index i into A, and rearrange the elments such that all elements less than A[i] appear first, followed by elements equal to A[i], followed by elements greater than A[i].
explanation for my code:
Ask user for n numbers, which is 11. And ask him what the index that he wants to rearrange the elements with. It takes it to function1, and creates a for loop and does an if else statement. if A[i] < A{index} , place it in the begining, else if it's less, place it at the end, or place it in the middle:
Here is my code
#include <iostream>
using namespace std;
void function1(int a[], int ind);
int main()
{
int a[11];
int index;
cout << " enter the numbers: " << endl;
for(int i=0; i < 11; i++)
cin >> a[i];
cout << "what is the index ? " << endl;
cin >> index;
function1(a,index);
}
void function1(int a[], int ind)
{
int x = a[ind];
int newArray[11];
for(int i=0; i < 11; i++)
{
if(a[i] < x)
{
newArray[i] = a[i];
}
else if(a[i] > x)
{
newArray[10-i] = a[i];
}
else
{
newArray[10/2] = a[i];
}
}
for(int i=0; i<11; i++)
cout << newArray[i] << " ";
}
The output that I am expecting to get is the rearrangement of the new array which will probably look similar to this:
a[0....x....n-1], where x is the index that represents a[i]
however I am getting incorrect output with numbers randomly scattered across
what is wrong with my logic ?
The problem is that (like Olaf Dietsche pointed out) you take just one index where two are necessary. Further you can't know if the element that is neither smaller not bigger than a[ind] (means equal to a[ind]) is to be inserted in the middle of the new array. (Imagine 3 2 1 and index 3 results in 2 1 3 but 3 isn't in the middle!)
Updated Version (allows for multiple elements with same value as pivot element)
void rearange(int* data, int size, int pivot)
{
int* temp_data = new int[size];
int start_index = 0, end_index = size - 1;
for (int i = 0; i < size; i++)
{
if (data[i] < data[pivot]) // -> insert 'before' pivot element
{
temp_data[start_index] = data[i];
start_index++;
}
else if (data[i] > data[pivot]) // -> insert 'behind' pivot element
{
temp_data[end_index] = data[i];
endIndex--;
}
// else: skip pivot(s)
}
// insert pivot element(s)
for (int i = start_index; i <= end_index; i++)
{
temp_data[i] = data[pivot];
}
for (int i = 0; i < size; i++)
{
std::cout << temp_data[i] << " ";
}
delete[] temp_data;
}
Input:
11 10 9 8 7 7 7 6 5 4 3
5
Output
6 5 4 3 7 7 7 8 9 10 11
As you see, all elements smaller than element 5 (with value of 7) are before, all elements greater are behind the pivot element. All other elements with same value as pivot are wrapped around position 5, wherever there's free space. However the rearranged elements are not yet sorted (apart from being positioned relative to pivot element)!
You use the same index i for the smaller and larger values. This means, if only the last value a[10] is larger than x, you will write it in the first location newArray[10 - 10], even though you already filled all places up to the 10th. Another problem is, when you have multiple middle values. They will all be stored into newArray[5].
What you want to achieve is called partitioning, as used in the quicksort algorithm.
You need to maintain two indexes (pointers), one for the smaller (left) and one for the larger (right) values.
You have to determine the size of your array at the beginning and pass the fixed size of the array to the function as a parameter.

Bubble Sort Optimization C++

I was just practising a little bit and tried to sort an array with the bubble sort algorithm.
Compiler didn't give me any warnings nor errors and it worked well! First you type 10 times a number and then the program sorts them + prints them.
Code:
#include <iostream>
using namespace std;
void arr_sort(int* array, const int arr_size){
int temp = 0; //Temporary integer to store (if necessary) the current element
int end = 0; //Run time condition
while(end++ != arr_size){ // Will loop max. 10 times
for(int i = 0; i < arr_size; i++){
if(array[i] > array[i + 1]){ //If the current element
temp = array[i]; //is bigger than the next
array[i] = array[i + 1];//Change the positions
array[i + 1] = temp;
}
}
}
}
int main(){
int arr_input[10];
for(int i = 0; i < 10;i++) //The user has to type 10 numbers
cin >> arr_input[i]; //which will be stored in this array
arr_sort(arr_input, 10); //sorts the array
cout << endl << endl;
for(int i = 0; i < 10; i++) //Print out the array!
cout << arr_input[i] << ", ";
cout << endl;
return 0;
}
My only problem is the while-loop in the arr_sort function. I mean it sorts the array until end has the same value as arr_size. But often it doesn't need that long. My question now... How can I improve this function? How can I test if the array is completely sorted so the while-loop can stop without running another time and another time ...?
Before your for loop, assume it's sorted:
bool sorted = true;
In your if statement`, record that it's not sorted:
sorted = false;
After your for loop`, return if there was no evidence that it's not sorted:
if ( sorted ) return;
Just outside of the for loop, place a bool and set it to false. Inside the swap block, set the bool to true. After the for loop, check the value of the boolean, and if it's still false, no swaps were made so the array is sorted, so break out of the while loop.
while(end++ != arr_size){ // Will loop max. 10 times
bool swapped = false;
for(int i = 0; i < arr_size; i++){
if(array[i] > array[i + 1]){ //If the current element
temp = array[i]; //is bigger than the next
array[i] = array[i + 1];//Change the positions
array[i + 1] = temp;
swapped = true;
}
}
if (!swapped) break;
}