opprenskning
This commit is contained in:
parent
56cdc9248b
commit
45e01074bb
@ -2,8 +2,8 @@
|
||||
#define DOUBLY_LINKED_LIST_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include "queue.h"
|
||||
#include "sequence.h"
|
||||
|
||||
namespace seq
|
||||
{
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#include "queue.h"
|
||||
#include "dynamic-array.h"
|
||||
|
||||
using namespace seq;
|
||||
@ -14,7 +16,6 @@ void DynamicArray::clear()
|
||||
this->capacity = 0;
|
||||
}
|
||||
|
||||
// insert an item at index i
|
||||
void DynamicArray::enqueue(int value)
|
||||
{
|
||||
int i = this->logical_size;
|
||||
@ -40,7 +41,7 @@ void DynamicArray::enqueue(int value)
|
||||
|
||||
// copy all of temp_storage into values[i+1] to values[logical_size]
|
||||
std::copy(temp_storage, temp_storage + shifted_elements, &this->values[i+1]);
|
||||
delete temp_storage;
|
||||
delete[] temp_storage;
|
||||
}
|
||||
|
||||
// now we can write the inserted item into values[i]
|
||||
@ -48,29 +49,35 @@ void DynamicArray::enqueue(int value)
|
||||
this->values[i] = value;
|
||||
}
|
||||
|
||||
// remove the item at index i
|
||||
int DynamicArray::dequeue()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// shift all elements from index i+1 onward one to the left
|
||||
// we use a temporary storage and copy() from <algorithm> to do this efficiently
|
||||
size_t shifted_elements = this->logical_size - i - 1;
|
||||
if(shifted_elements > 0)
|
||||
{
|
||||
if (this->size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
int i = 0;
|
||||
// Save the first element wich we want to return:
|
||||
int outgoing = this->values[0];
|
||||
|
||||
// shift all elements from onward one to the left
|
||||
size_t shifted_elements = this->logical_size - 1;
|
||||
|
||||
int* temp_storage = new int[shifted_elements]();
|
||||
|
||||
// copy values[i+1] to values[logical_size-1] into temp_storage
|
||||
std::copy(this->values + i+1, this->values + this->logical_size, temp_storage);
|
||||
std::copy(this->values + 1, this->values + this->logical_size, temp_storage);
|
||||
|
||||
// copy all of temp_storage into values[i] to values[logical_size-2]
|
||||
std::copy(temp_storage, temp_storage + shifted_elements, &this->values[i]);
|
||||
delete temp_storage;
|
||||
}
|
||||
delete[] temp_storage;
|
||||
if (!this->empty()) {
|
||||
this->logical_size--; // with this, we are done with the task
|
||||
|
||||
// now let us see whether we have deleted so many items that we should resize to save memory
|
||||
if(this->capacity/2 >= this->logical_size) this->resize(this->capacity/2);
|
||||
|
||||
}
|
||||
return outgoing;
|
||||
}
|
||||
|
||||
// allocate static array with "new_capacity" elements,
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "queue.h"
|
||||
#include "sequence.h"
|
||||
|
||||
namespace seq
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
|
||||
#include "dynamic-array.h"
|
||||
#include "queue.h"
|
||||
@ -12,11 +13,19 @@ namespace
|
||||
/*
|
||||
* run a simple test
|
||||
*/
|
||||
void test_sequence(seq::Queue* sqn, int n, int m, std::ostream* os)
|
||||
void test_queue(seq::Queue* sqn, int n, int m, std::ostream* os)
|
||||
{
|
||||
assert((m > 0) && (n > m));
|
||||
if(os) *os << "Enqueue even numbers from 0 to " << 2*(n-1) << ".\n";
|
||||
for(int i = 0; i < n; i++) sqn->enqueue(2*i);
|
||||
for(int i = 0; i < n; i++) sqn->dequeue();
|
||||
}
|
||||
void test_queue(std::queue<int>* sqn, int n, int m, std::ostream* os)
|
||||
{
|
||||
assert((m > 0) && (n > m));
|
||||
if(os) *os << "Enqueue even numbers from 0 to " << 2*(n-1) << ".\n";
|
||||
for(int i = 0; i < n; i++) sqn->push(2*i);
|
||||
for(int i = 0; i < n; i++) sqn->pop();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -24,16 +33,38 @@ namespace
|
||||
*/
|
||||
float test_with_time_measurement(seq::Queue* sqn, int iterations)
|
||||
{
|
||||
int sequence_length = 200001;
|
||||
int queue_length = 20001;
|
||||
int deletions = 10;
|
||||
test_sequence(sqn, sequence_length, deletions, &std::cout);
|
||||
test_queue(sqn, queue_length, deletions, &std::cout);
|
||||
|
||||
int log_entries = 10;
|
||||
std::cout << "\nNow repeat the above " << iterations << " times:\n";
|
||||
auto t0 = std::chrono::high_resolution_clock::now();
|
||||
for(int i = 0; i < iterations; i++)
|
||||
{
|
||||
test_sequence(sqn, sequence_length, deletions, nullptr);
|
||||
test_queue(sqn, queue_length, deletions, nullptr);
|
||||
if((i+1) % (iterations/log_entries) == 0)
|
||||
{
|
||||
std::cout << "\t" << i+1 << "\n";
|
||||
std::cout.flush(); // make sure that status output is shown without delay
|
||||
}
|
||||
}
|
||||
auto t1 = std::chrono::high_resolution_clock::now();
|
||||
return 1.0e-06 * std::chrono::duration_cast<std::chrono::microseconds>(t1-t0).count();
|
||||
}
|
||||
|
||||
float test_with_time_measurement(std::queue<int>* sqn, int iterations)
|
||||
{
|
||||
int queue_length = 20001;
|
||||
int deletions = 10;
|
||||
test_queue(sqn, queue_length, deletions, &std::cout);
|
||||
|
||||
int log_entries = 10;
|
||||
std::cout << "\nNow repeat the above " << iterations << " times:\n";
|
||||
auto t0 = std::chrono::high_resolution_clock::now();
|
||||
for(int i = 0; i < iterations; i++)
|
||||
{
|
||||
test_queue(sqn, queue_length, deletions, nullptr);
|
||||
if((i+1) % (iterations/log_entries) == 0)
|
||||
{
|
||||
std::cout << "\t" << i+1 << "\n";
|
||||
@ -61,7 +92,12 @@ int main()
|
||||
seq::DoublyLinkedList dll;
|
||||
float dll_time = test_with_time_measurement(&dll, iterations);
|
||||
|
||||
std::cout << "\n\n*** test with std::queue ***\n";
|
||||
std::queue<int> queue;
|
||||
float queue_time = test_with_time_measurement(&queue, iterations);
|
||||
|
||||
std::cout << "\n\nRuntime for dynamic array:\t" << dyna_time << " s\n";
|
||||
std::cout << "Runtime for singly linked list:\t" << sll_time << " s\n";
|
||||
std::cout << "Runtime for doubly linked list:\t" << dll_time << " s\n";
|
||||
std::cout << "Runtime for std::queue:\t" << queue_time << " s\n";
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
#ifndef SEQUENCE_H
|
||||
#define SEQUENCE_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace seq
|
||||
{
|
||||
class Sequence
|
||||
{
|
||||
public:
|
||||
virtual bool empty() const = 0; // test whether the sequence is empty
|
||||
virtual size_t size() const = 0; // return the size (number of items in the sequence)
|
||||
|
||||
// it is the caller's responsibility to ensure that the sequence is not empty when calling front() or back()!
|
||||
virtual int& front() = 0; // return a reference to the first item
|
||||
virtual int& back() = 0; // return a reference to the final item
|
||||
|
||||
// return a reference to the item at position i of the sequence, counting from 0
|
||||
// it is the caller's responsibility that the index is within range
|
||||
virtual int& at(int i) = 0;
|
||||
|
||||
/*
|
||||
* accepts an additional item into the sequence (front or back);
|
||||
* the pushed item is passed by reference, but a copy of it is stored in the Sequence
|
||||
* the Sequence takes ownership of the copy (but not of the original!)
|
||||
*/
|
||||
virtual void push(const int& pushed_item) = 0; // default push operation (front or back)
|
||||
virtual void push_front(const int& pushed_item) = 0;
|
||||
virtual void push_back(const int& pushed_item) = 0;
|
||||
|
||||
virtual void pop() = 0; // default pop operation (front or back)
|
||||
virtual void pop_front() = 0; // remove the first element
|
||||
virtual void pop_back() = 0; // remove the last element
|
||||
virtual void clear() = 0; // remove all the items from the sequence
|
||||
|
||||
// it is the caller's responsibility that the index is within range
|
||||
virtual void insert_at(int i, const int& inserted_item) = 0; // insert an item at index i
|
||||
virtual void erase_at(int i) = 0; // remove the item at index i
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
#include <cstddef>
|
||||
#include "singly-linked-list.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace seq;
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define SINGLY_LINKED_LIST_H
|
||||
|
||||
#include <cassert>
|
||||
#include "sequence.h"
|
||||
#include "queue.h"
|
||||
|
||||
namespace seq
|
||||
@ -36,7 +35,7 @@ namespace seq
|
||||
bool empty() const { return (this->head == nullptr); } // test whether the singly linked list is empty
|
||||
size_t size() const; // return the size (number of items in the singly linked list)
|
||||
|
||||
void enqueue(int element);
|
||||
void enqueue(int value);
|
||||
int dequeue();
|
||||
|
||||
void clear() { while(!this->empty()) this->dequeue(); } // remove all the items from the list
|
||||
|
Loading…
Reference in New Issue
Block a user