insertion sort algorithm using a second array C++ - c++

Trying to understand the insertion sort algorithm..
My algorithm looks like this currently:
void insertionSort(int *array, int N) {
int value;
int hole;
int *array2;
for (int i = 1; i < N - 1; i++) {
value = array[i]; //next item to be inserted in array 2
hole = i;
while (hole > 0 && array[hole - 1] > value) {
array[hole] = array[hole - 1];
hole = hole - 1;
}
array[hole] = value;
}
}
My algorithm works for sorting arrays, however I now need to change it so that I build up a new sorted array (array2) one element at a time, rather than just working with the original array.
Is there a simple way to implement this given my completed algorithm?
Thanks.

You can use the following method:
int *array2 = calloc(N, sizeof(int));
for(var index = 0; index < N; index++)
{
array2[index] = array[index];
}
and after that use array2 instead of array
then just change the prototype of your function to int *insertionSort
All remaining is to return array2 at the end of task
But be aware of memory leak: https://en.wikipedia.org/wiki/Memory_leak

Related

How to use insertion sorting on an array of objects?

I have a Movie class set up and I am trying to create a function to sort an array of movies by release date and then by rating. I have 7 movies in a text document getting stored into my array and getter functions at the ready but I am having trouble converting what little I know about sorting an array of ints into an array where I need to sort strings and then doubles.
Here is my code:
string Movie::getReleaseDate() {
return releaseDate;
}
double Movie::getRating() {
return rating;
}
void sortByDateRating(Movie movies[], int SIZE) {
int i;
int j;
int temp;
for (i = 1; i < SIZE; ++i) {
j = i;
while (j > 0 && movies[j] < movies[j - 1]) {
temp = movies[j];
movies[j] = movies[j - 1];
movies[j - 1] = temp;
--j;
}
}
}
I plan to call this function from a switch case I have in main. Thanks ahead of time.
Unless you really want to implement the sorting yourself, you can use the STL container std::map or the equivalent container from Boost.

How to delete one data line from a structure array ? (with index)

I am trying to make a function, which deletes one line from a structure array, I give function the index of line I want to delete and the structure array. E.g. we have structure array :
Structure
{
string First;
string Second;
string Third;
string Fourth;
string Fifth;
}
Structure array :
Structure A[100];
int n;
So there are five string type elements in this structure array :
A[i].First A[i].Second A[i].Fourth A[i].Fifth // i is the index
Our function is like this :
void Delete(Structure A[], int index, int & n)
{
Structure t;
for (int i = index; i < n-1; i++)
{
t = A[i];
A[i] = A[i + 1];
A[i + 1] = t;
n--;
}
}
So I give function index and I want the function to delete all elements of my structure array with that index ( so how can I take like the whole "line" of those elements, instead of deleting them one by one ?)
A[index].First A[index].Second A[index].Third A[index].Fourth A[index].Fifth
The function however doesn't work. Can you give me some tips/advises/suggestions, please ? Thanks in advance.
At first level, your question is basically: how to remove a line from an array whose used size is stored in an external variable (passed here as n)
The signature of your function is correct, the implementation is not. It should be:
void Delete(Structure A[], int index, int & n)
{
// eventually control index >= 0 and index < n...
n -= 1;
for (int i = index; i < n; i++)
{
A[i] = A[i + 1];
}
}
If you have a recent version of C++ that support move semantics, you could speed up the operation by moving the strings instead of copying them:
n -= 1;
for (int i = index; i < n; i++)
{
A[i] = std::move(A[i + 1]);
}

My program freezes at the end, after it has finished

I've been working on a class for an insertion sort thing that I'm playing around with. However, when I run my program, it seems to work just fine for the most part (gets to return 0; in main and then freezes). I don't know why or how it's freezing, and it's gotten me quite confused.
The only method that is called from the insertionSort object is sort, if you don't count generateNums.
Main.cpp:
#include "stdafx.h"
#include "insertionSort.h"
#include <iostream>
int main()
{
int* gotNums;
const int INT_LENGTH = 100;
//Create new insertionSort object
insertionSort insSort(INT_LENGTH); //Length: 100
std::cout << "hey";
return 0;
}
insertionSort.h:
#pragma once
class insertionSort
{
private:
int* _nums; //Sorted and unsorted nums
int _sortedBegins; //Point at which sorted items begin. This minus one is the first unsorted item
int _length;
void shiftUnsorted();
public:
insertionSort(int length);
int* getNums();
void sortNums();
void generateNums();
};
insertionSort.cpp
#include "stdafx.h"
#include "insertionSort.h"
#include <random>
#include <iostream>
//Constructor and destructors
insertionSort::insertionSort(int length)
{
_nums = new int(length + 1); //+1 to accomodate empty space between sorted & unsorted.
std::cout << "made arr ";
_sortedBegins = length + 1;
std::cout << "made sorted ";
_length = length + 1;
std::cout << "made len ";
this->generateNums();
}
/* Custom functions */
//Populate array with new numbers
void insertionSort::generateNums() {
for (int i = 0; i < _length - 1; i++) { //Don't fill the last array; it's an empty place for the sorted items.
_nums[i] = rand() % 100 + 1; //generate number between 1 and 100
}
_nums[_length] = -1; //Create buffer
}
//The main part of it all - sort the array
void insertionSort::sortNums() {
int currPos = _sortedBegins - 1; //Loop backwards through the unsorted items so that there is minimal shifting.
int currInt;
while (currPos > 0) {
currInt = _nums[currPos];
for (int i = _length; i > _sortedBegins; i++) {
if (i < currInt) { //Time to shift the sorted to the left
_nums[_sortedBegins - 1] = 0; //Shift buffer left
for (int i2 = _sortedBegins + 1; i2 <= i; i2++) { //Shift main sorted content left
_nums[i2] = _nums[i2 + 1];
}
_nums[i] = currInt;
break;
}
}
currInt--;
}
}
//Get nums from array
int* insertionSort::getNums() {
return _nums;
}
//Shift unsorted items to the left to make way for new data in sorted. NOTE: does not assign new value to sortedBegins.
void insertionSort::shiftUnsorted() {
for (int i = 0; i < _sortedBegins - 1; i++) {
_nums[i] = _nums[i + 1];
}
_nums[_sortedBegins - 1] = 0;
//And, it's hopefully shifted!
}
Anyone got an idea as to why this isn't working properly?
Thanks,
- Sam
Change:
_nums[_length] = -1; //Create buffer
to:
_nums[_length - 1] = -1; //Create buffer
Valid indexes for _nums are from 0 to length-1. Your code is writing outside the array, which causes undefined behavior.
The for loop in sortNums is also doesn't look right:
for (i = _length; i > _sortedBegins; i++) {
It makes no sense to start at _length, which is after the end of the array. And adding to it goes even farther out of the array. I haven't really analyzed the logic in that loop, so I'm not sure what the correct code is. But you need to start by making sure you stay inside the array.
But since your program doesn't currently call sortNums, it won't cause a problem now.
When shiftUnsorted does
_nums[_sortedBegins - 1] = 0;
you'll write outside the array if _sortedBegins is 0. You don't currently call this, either. When you add the call to it, make sure it can never be called when that's true, or add a check for this into the function.
This code looks suspicious to me:
_nums = new int(length + 1);
I would have expected square brackets instead of round parentheses. Because like this, you are only creating a pointer to a single int that is initialized with the value 101. But instead you wanted to create an array of 101 ints and later fill it with values. So write this:
_nums = new int[length + 1];

How to sort one array and get corresponding second array in C++? [duplicate]

This question already has answers here:
sort one array and other array following?
(3 answers)
Closed 7 years ago.
I have two arrays in same size. And want to sort one of the array normally and then sort the next array elements accordingly.
Let's say we have two arrays
e[] = {4,2,3,7,6,8}
s[] = {2,0,4,3,7,9}
First I want to sort array e normally, Then change the element positions of s array according to the changed element positions of e.
This should be the final result
e[] = {2,3,4,6,7,8}
s[] = {0,4,2,7,3,9}
How should I do this? Should I use a class object with these two as private members and then proceed? If so, how to do that?
Create a single array (or vector) of std::pair objects, where first is from the first array and second from the second. Then just use std::sort with a custom comparator function that uses only second from the pair for comparison. Iterate over the sorted array (or vector) and split up into the original arrays.
Note: If the values in each array are tightly coupled then consider putting them in a structure or class instead of using two (or more) distinct arrays.
What I think is use std::map
Assign array e element as the key
And corresponding array s element as the value.
Then sort the may by key
Go trough the map and get the values one by one
If you do this in a class, you can create an array of indices and sort the indices according to the values in e[]. If not doing this within a class, and for a more general approach, create an array of pointers to e[], then sort the pointers according to e[]. Then reorder e[] and s[] according to the pointers, converting the the sorted pointers to an index by using array_of_pointers[i] - &e[0] (or just array_of_pointers[i]-e). You could write your own sort, or use qsort, std::sort, or std::stable sort to sort the array of pointers, with a compare function that compares using dereferenced pointers (compares the values pointed to). Example C code using qsort and reorder in place logic with O(n) time complexity:
int compare(const void *pp0, const void *pp1)
{
int i0 = **(int **)pp0;
int i1 = **(int **)pp1;
if(i0 > i1)return -1;
if(i0 < i1)return 1;
return 0;
}
int main()
{
int e[...];
int s[...];
int *pe[...];
size_t i, j, k;
int te, ts;
/* ... */
/* create array of pointers to e[] */
for(i = 0; i < sizeof(e)/sizeof(e[0]); i++)
pe[i] = &e[i];
/* sort array of pointers */
qsort(pe, sizeof(e)/sizeof(e[0]), sizeof(pe[0]), compare);
/* reorder e[] and s[] according to the array of pointers */
for(i = 0; i < sizeof(e)/sizeof(e[0]); i++){
if(i != pe[i]-e){
te = e[i];
ts = s[i];
k = i;
while(i != (j = pe[k]-e)){
e[k] = e[j];
s[k] = s[j];
pe[k] = &e[k];
k = j;
}
e[k] = te;
s[k] = ts;
pe[k] = &e[k];
}
}
/* ... */
return 0;
}
If you don't want to use other Data structures and stick with the two different integer arrays..
Following code snippet will help you
int _tmain(int argc, _TCHAR* argv[])
{
int e[] = {4,2,3,7,6,8} ;
int s[] = {2,0,4,3,7,9} ;
int temp ;
int Array_Size = 6 ; // don't use hard coded value here, rather calculate from array size
for(int i = 0 ; i < Array_Size ; i++)
{
for(int j = i+1 ; j < Array_Size ; j++)
{
if(e[i] > e[j])
{
// Swap elements in first array
temp = e[j] ;
e[j] = e[i] ;
e[i] = temp ;
// As you want both arrays in sync
// Swap elements in second array here itself
temp = s[j] ;
s[j] = s[i] ;
s[i] = temp ;
}
}
}
return 0;
}
It is quite simple when we use structure.Your basic task is to sort two arrays. I want to suggest one method regarding it. Use a structure having two variables x and y which are used here for two arrays. Make two array of objects of this structure.
struct Point
{
int x,y;
};
struct Point arr[n];
After providing entries to the array of structure objects, make use of STL function
sort(arr,arr+n,myfun);
where myfun is function to sort according to ur need and it is defined as
bool myfun(struct Point a,struct Point b)
{
if(a.x<b.x)
return true;
else
return false;
}
And here is the complete program in c++
#include <bits/stdc++.h>
using namespace std;
struct Point{
int x,y;
};
bool myfun(struct Point a,struct Point b)
{
if(a.x<b.x)
return true;
else
return false;
}
int main()
{
int n; //n is the number of elements of array
cin>>n;
struct Point arr[n];
//Enter first array
for(int i=0;i<n;i++)
cin>>arr[i].x;
//Enter second array
for(int i=0;i<n;i++)
cin>>arr[i].y;
//sorting with the help of myfun
sort(arr,arr+n,myfun);
//now print the arrays
for(int i=0;i<n;i++)
cout<<arr[i].x<<" ";
cout<<"\n";
for(int i=0;i<n;i++)
cout<<arr[i].y<<" ";
return 0;
}
void bubbleSort(int e[], int s[], int n) {
bool swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < n - j; i++) {
if (e[i] > e[i + 1]) {
tmp = e[i];
e[i] = e[i + 1];
e[i + 1] = tmp;
tmp = s[i];
s[i] = s[i + 1];
s[i + 1] = tmp;
swapped = true;
}
}
}
}

Inserting an element into an array

How can I make an inset method that will add a number into the array in the correct order?
void addElement(int table[], int element, int length) {
int x = 0;
int temporary=0;
cout<<length<<endl;
if(length == 1) {
table[0] = element;
}
else {
if(length == 2) {
if (table[0] > element) {
int temp = table[0];
table[0] = element;
table[1] = temp;
}
else {
table[1] = element;
}
}
else {
for(int i = 0; i< length && x == 0; i++) {
if(element<table[i] && element>=table[i-1]) {
for(int y = i; y<length; y++) {
temporary = table[y+2];
int temp = table[y];
table[y] = element;
table[y+1] = table
}
}
}
}
}
}
This is as far as I have gotten. In my main class I have worked it out so that array is increased by 1. So there is one open space at the end of the array for everything to be pushed back by 1.
You can scan the array from back to front, moving values up until you find the correct insertion point.
void addElement(int *table, int element, int length)
{
int i = length - 1;
for (; i > 0 && table[i-1] > element; --i)
{
table[i] = table[i-1];
}
table[i] = element;
}
Write a shiftElements function, write a findIndexOfFirstGreaterThan function, then in addElement - find the index, if -1 then put in last slot, else shift elements using index, then a[index]=elem;
Draw yourself an example, then work out a list of very simple steps required to do what you want.
Then write code that does those steps.
Im not sure if this is what your looking for, but I think you want something that adds an element depending on its integer value. Also, I do not have access to a compiler at this moment so there might be a couple of errors. The code below is just written to give you a brief idea of what you could do, but probably not a perfect solution to your problem.
int addElement (int element, int array [], int length)
{
vector <int> vectorOfInts; //vector to store current order of ints
vector <int> vectorOfArrangedInts; //vector to store arranged order
for (int counter = 0; counter < length; counter ++) //loop to fill the array with values
{
vectorOfInts.push_back (array [counter]);
}
for (int counter = 0; counter < vectorOfInts.length(); counter ++) //loop through all elements
{
int temp = 0; //stores temp value of biggest number found at a specific moment
int elementIndex; //stores indexes
for (int counterTwo = 0; counterTwo < vectorOfInts.length(); counterTwo ++) //loop through all elements to find the biggest array
{
if (vectorOfInts.at (counterTwo) >= temp) //if value is bigger than current biggest number
{
temp = vectorOfInts.at (counterTwo); //change temp value
elementIndex = counterTwo; //remember index
}
}
vectorOfArrangedInts.push_back (vectorOfInts.at(elementIndex)); //add the biggest number to the arranged values
vectorOfInts.erase (vectorOfInts.begin() + elementIndex); //remove the biggest element
}