#include<iostream>
#include<vector>
#include "Timer.h"
using std::cin;
using std::cout;
using std::vector;
using std::endl;
using std::ostream;
using std::ios;
struct node{
int data;
node* next;
node* prev;
} *head=0;
ostream& operator<<(ostream& out, node* n){
if ( ! n ){
return out;
}
out<<n->data;
if ( n->next ){
out<<", ";
out<<n->next;
}
else{
out<<endl;
}
return out;
}
typedef node*& node_pref_t;
vector<int> data;
/**
* insertion sort, linked list
*/
void i_sort(node_pref_t head){
//empty list?
if ( !head ) return ;
// start looking for out of order element.
node* current = head;
while( current->next ){
// if out of order, current->next will change place.
// rearrange current->next immideately
if ( current->data <= current->next->data ){
// in order, hopefully for performance the default case.
// just move to the next node
current = current->next;
}else{
// out of order
node* extract_this_node = current->next;
// complete chain , current->next might here be 0
current->next = extract_this_node->next;
if( current->next ){
current->next->prev= current;
}
// loop back to correct position
node* insertion_point = extract_this_node->prev;
// important to check insertion_point is valid before checking the
// contents. Short-circuit evaluation FTW!
while( insertion_point &&
insertion_point->data > extract_this_node->data ){
insertion_point = insertion_point->prev;
}
if ( insertion_point ){
// rearrange pointers, order matters here A <-> B
// will become A<->I<->B
extract_this_node->next = insertion_point->next; // I->B
extract_this_node->next->prev = extract_this_node; // I<->B
insertion_point->next = extract_this_node; // A->I
extract_this_node->prev = insertion_point; // A<->I
}else{
// found the beginning of the list, insert at head.
head->prev = extract_this_node;
extract_this_node->next = head;
head = extract_this_node;
head->prev = 0;
}
}
}
}
/**
* insertion sort, vector
*/
void i_sort(vector<int> & data){
for(int i = 0; i < data.size()-1; i++){
// out of order element?
if ( data[i] > data[i+1] ){
// pull data[i+1] to its proper position.
// the value needs to be stored.
int insert_value = data[i+1];
int insert_index = i;
// stop at index 0 or at the correct spot.
while( insert_index && data[insert_index] > insert_value ){
// move up value in list to make room for insertion.
data[insert_index+1] = data[insert_index];
insert_index--;
}
data[insert_index+1] = data[insert_index];
data[insert_index] = insert_value;
}
}
}
int main(){
cout.setf(ios::fixed, ios::floatfield);
cout.precision(6);
node* next;
// fill structures from console
int value;
while(cin>>value){
data.push_back(value);
if ( !head){
head = new node{value, 0, 0};
next = head;
}else{
next->next = new node{value,0, next};
next = next->next;
}
}
// sort
// and time
Timer timer;
timer.start();
i_sort(head);
timer.stop();
// debugging check: cout<<head;
double list_time = timer.get_duration();
// record time linked list
cout<<list_time<<endl;
timer.start();
i_sort(data);
timer.stop();
double vector_time = timer.get_duration();
// record time vector
cout<<vector_time<<endl;
return 0;
}