3

Instead of The ELEMENTS being 25 is there a way to randomly generate a large array of elements....10000, 100000, or even 1000000 elements and then use my insertion sort algorithms. I am trying to have a large array of elements and use insertion sort to put them in order and then also in reverse order. Next I used clock() in the time.h file to figure out the run time of each algorithm. I am trying to test with a large amount of numbers.

#define ELEMENTS 25

void insertion_sort(int x[],int length);
void insertion_sort_reverse(int x[],int length);

int main()
{
  clock_t tStart = clock();
  int B[ELEMENTS]={4,2,5,6,1,3,17,14,67,45,32,66,88,
               78,69,92,93,21,25,23,71,61,59,60,30};
  int x;

  cout<<"Not Sorted: "<<endl;
  for(x=0;x<ELEMENTS;x++)
       cout<<B[x]<<endl;

   insertion_sort(B,ELEMENTS);
   cout <<"Sorted Normal: "<<endl;
  for(x=0;x<ELEMENTS;x++)
       cout<< B[x] <<endl;

  insertion_sort_reverse(B,ELEMENTS);
  cout <<"Sorted Reverse: "<<endl;
  for(x=0;x<ELEMENTS;x++)
       cout<< B[x] <<endl;

  double seconds = clock() / double(CLK_TCK);
  cout << "This program has been running for " << seconds << " seconds." << endl;
  system("pause");
  return 0;
}
0

3 Answers 3

19
#include <random>     // mt19937 and uniform_int_distribution
#include <algorithm>  // generate
#include <vector>     // vector
#include <iterator>   // begin, end, and ostream_iterator
#include <functional> // bind
#include <iostream>   // cout

std::vector<int> create_random_data(int n) {
  std::random_device r;
  std::seed_seq      seed{r(), r(), r(), r(), r(), r(), r(), r()};
  std::mt19937       eng(seed); // a source of random data

  std::uniform_int_distribution<int> dist;
  std::vector<int> v(n);

  generate(begin(v), end(v), bind(dist, eng));
  return v;
}

int main() {
  auto random_data = create_random_data(100000);

  std::cout << "unsorted: ";
  copy(begin(random_data), end(random_data),
       std::ostream_iterator<int>(std::cout, "\n"));
}

generate is a generic algorithm that fills a range with values generated by a functor. In this case we provide it with a functor that uses our source of random data to produce random numbers, and we provide a range corresponding to a container, which we can use after generate fills it with data.

We're using std::mt19937 and std::uniform_int_distribution, standard C++ facilities as of C++11 (and available in VS2010), to create random numbers instead of the older std::rand() and std::srand() because the newer method is easier to use correctly, higher quality and more flexible.


If you're using VS2012 or higher then the C++11 time library is available.

#include <chrono>

int main() {
  using std::chrono::high_resolution_clock;
  using std::chrono::duration_cast;
  using std::chrono::nanoseconds;

  auto start = high_resolution_clock::now();

  // ...

  auto end = high_resolution_clock::now();

  std::cout << duration_cast<nanoseconds>(end - start).count() << "ns\n";
}
Sign up to request clarification or add additional context in comments.

3 Comments

std::mt19937, std::uniform_int_distribution<> never heard of them. Wonder what is the significance of 19937 ? +1 Anyways :)
@Mahesh, It has a very long period of 2^19937 − 1. - From Wikipedia's article on Mersenne Twister ;)
@Mehesh 19937 is a prime number that is a common parameter for a certain random number algorithm, Mersenne Twister (mt)
4

Instead of

void insertion_sort(int x[],int length);
void insertion_sort_reverse(int x[],int length);

 int B[ELEMENTS]={4,2,5,6,1,3,17,14,67,45,32,66,88,
           78,69,92,93,21,25,23,71,61,59,60,30};

try

void insertion_sort(std::vector<int>& x);
void insertion_sort_reverse(std::vector<int>& x);

 srand(NULL);
 std::vector<int> B(num_elements); //num_elements can be a variable
 std::generate(B.begin(), B.end(), rand);

As relates to the task and not the question:
You'll want to run each sort twice in a row, the first without timing, the second with timing.
Your tests aren't fair since one starts from a randomized position, and the other from a sorted position.
You're including IO in your timings, and IO is always slow (cout)
std::endl forces the program to give all the output to the OS immediately, use '\n'.
You're displaying a completely unrelated number of seconds.

int main()
{
  srand(NULL);
  std::vector<int> B(num_elements); //num_elements can be a variable
  std::generate(B.begin(), B.end(), rand);
  std::vector<int> C(B); //make a copy of the data

  std::cout << "Not Sorted:" << '\n';
  for(int i=0;i<B.size();i++)
       cout<<B[i]<<'\n';

  clock_t tStart0 = clock();        
  insertion_sort(B,ELEMENTS);
  clock_t tStop0 = clock();     

  cout <<"Sorted Normal: "<<'\n';
  for(int i=0;i<B.size();i++)
       cout<< B[i] <<'\n';

  clock_t tStart1 = clock();        
  insertion_sort_reverse(C);
  clock_t tStop1 = clock();  

  cout <<"Sorted Reverse: "<<'\n';
  for(int i=0;i<C.size();i++)
       cout<< C[i] <<'\n';

  double seconds = (tStop1-tStart1 + tStop0-tStart0) / double(CLK_TCK);
  cout << "This program has been running for " << seconds << " seconds." << endl;
  system("pause");
  return 0;
}

Comments

2

For C++11, I used the time value as initial random seed to generate any number of random data.

See the following sample code

#include <iostream>
#include <random>
#include <chrono>
#include <functional>
#include <iterator>

constexpr auto MAX = 20;

int main(int argc, char* argv[]) {

    std::default_random_engine re(std::chrono::system_clock::now().time_since_epoch().count());
    std::uniform_int_distribution<int> uid(0, MAX);
    int nums[MAX] {};
    std::generate(nums, nums+MAX, std::bind(uid, re));

    // apply sort algorithm

    std::copy(nums, nums+MAX, std::ostream_iterator<int>(std::cout, ","));
    std::cout << std::endl;
    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.