PCLP2/lab04/01.cpp

193 lines
3.6 KiB
C++
Raw Permalink Normal View History

2020-03-28 13:04:49 +00:00
#include <iostream>
#include <vector>
#include <cstdlib>
#include <chrono>
using namespace std;
#define SIZE 300
void benchmark(void(*f)(vector<int>* v), vector<int>* v);
void sort_insert(vector<int>* v);
void sort_bininsert(vector<int>* v);
void sort_select(vector<int>* v);
void sort_bubble(vector<int>* v);
void sort_shake(vector<int>* v);
int main(){
ios::sync_with_stdio(false);
cout<<"----- Testing sort algorithms -----\n\n\n";
cout<<"Usage: e[X]it, [C]reate vector, print [V]ector, [R]eset vector, [I]nsertion sort, [B]inary insertion sort, [S]elect sort, bubble sor[T], s[H]ake sort\n\n";
srand(time(NULL));
vector<int> v;
vector<int> work;
while(true){
char command;
cout<<"> ";
cin>>command;
switch(command){
case 'X':
case 'x':
cout<<"Exiting..."<<endl;
return 0;
case 'C':
case 'c':
cout<<"Initializing vector...\n";
v.clear();
for(int i=0; i<SIZE; i++){
v.push_back(rand()%1000);
}
work = v;
cout<<"Done\n";
break;
case 'V':
case 'v':
cout<<"The vector:\n";
for(vector<int>::iterator it = work.begin(); it < work.end(); it++){
cout<<*it<<" ";
}
cout<<"\n";
break;
case 'R':
case 'r':
cout<<"Reinitializing working copy...\n";
work = v;
cout<<"Done\n";
break;
case 'I':
case 'i':
cout<<"# Insertion sort\n";
benchmark(sort_insert, &work);
break;
case 'B':
case 'b':
cout<<"# Binary insertion sort\n";
benchmark(sort_bininsert, &work);
break;
case 'S':
case 's':
cout<<"# Select sort\n";
benchmark(sort_select, &work);
break;
case 'T':
case 't':
cout<<"# Bubble sort\n";
benchmark(sort_bubble, &work);
break;
case 'H':
case 'h':
cout<<"# Shake sort\n";
benchmark(sort_shake, &work);
break;
}
}
return 0;
}
void benchmark(void(*f)(vector<int>* v), vector<int>* v){
auto t1 = chrono::high_resolution_clock::now();
(*f)(v);
auto t2 = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::nanoseconds>(t2 - t1).count();
cout<<"Execution time: "<<duration<<" ns\n";
}
void sort_insert(vector<int>* v){
for(int i=2; i<v->size(); i++){
int x = v->at(i);
int j = i-1;
while(j>=0 && v->at(j)>x){
v->at(j+1) = v->at(j);
j--;
}
v->at(j+1) = x;
}
}
void sort_bininsert(vector<int>* v){
for(int i=1; i<v->size(); i++){
int x = v->at(i);
int start = 0;
int dest = i-1;
while(start <= dest){
int middle = (start + dest) / 2;
if(v->at(middle) > x){
dest = middle-1;
}
else{
start = middle+1;
}
for(int j=i-1; j>=start; j--){
v->at(j+1) = v->at(j);
}
v->at(start) = x;
}
}
}
void sort_select(vector<int>* v){
for(int i=0; i<v->size()-1; i++){
int minpos = i;
int minval = v->at(i);
for(int j=i; j<v->size(); j++){
if(v->at(j) < minval){
minval = v->at(j);
minpos = j;
}
}
v->at(minpos) = v->at(i);
v->at(i) = minval;
}
}
void sort_bubble(vector<int>* v){
bool done = false;
while(!done){
done = true;
for(vector<int>::iterator it = v->begin(); it < v->end()-1; it++){
if(*it > *(it+1)){
int tmp = *it;
*it = *(it+1);
*(it+1) = tmp;
done = false;
}
}
}
}
void sort_shake(vector<int>* v){
int left = 2;
int right = v->size() - 1;
int k = v->size() - 1;
do{
for(int j=right; j>=left; j--){
if(v->at(j-1) > v->at(j)){
int tmp = v->at(j-1);
v->at(j-1) = v->at(j);
v->at(j) = tmp;
k = j;
}
}
left = k+1;
for(int j=1; j<=right; j++){
if(v->at(j-1) > v->at(j)){
int tmp = v->at(j-1);
v->at(j-1) = v->at(j);
v->at(j) = tmp;
k = j;
}
}
right = k-1;
}while(left <= right);
}