Initial commit with cleaned history
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
|
||||
/*
|
||||
(a) hat eine Zeitkomplexität von O(n), wobei n die Anzahl der Elemente in vec ist.
|
||||
Das liegt daran, dass jede Operation in der for-Schleife in konstanter Zeit ausgeführt wird
|
||||
und die Schleife genau n-Mal durchlaufen wird.
|
||||
*/
|
||||
|
||||
int vector_summe(vector<int>& vec){
|
||||
int sum = 0;
|
||||
for (unsigned i =0; i < vec.size(); i++){
|
||||
sum +=vec[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
(b) hat eine Zeitkomplexität von O(n^2), da es zwei verschachtelte Schleifen gibt,
|
||||
die jeweils bis zur Größe des Vektors laufen.
|
||||
Dies bedeutet, dass für jedes Element in vec alle Elemente innerhalb des Elementes einmal betrachtet werden,
|
||||
was zu n*n Operationen führt.
|
||||
*/
|
||||
|
||||
vector<pair<int, int>> pairs(vector<int>& vec){
|
||||
vector<pair<int, int>> returnpairs;
|
||||
pair<int, int> p;
|
||||
for(unsigned i = 0; i<vec.size(); i++){
|
||||
for(unsigned j=0; j<vec.size(); j++){
|
||||
p = {vec[i], vec[j]};
|
||||
returnpairs.push_back(p);
|
||||
}
|
||||
}
|
||||
return returnpairs;
|
||||
}
|
||||
|
||||
/*
|
||||
(c) Die Eingabegröße n ist die Größe von vec1 und m ist die Größe von vec2.
|
||||
Zuerst werden die separate Listen, vec1 und vec2, separat sortiert.
|
||||
Die Zeitkomplexität für das Sortieren von vec1 ist O(n log n) und O(m log m) für das Sortieren von vec2,
|
||||
da das die Zeitkomplexität von mergesort ist.
|
||||
Die anschließenden verschachtelten Schleifen, die über die beiden Vektoren iterieren, haben eine Zeitkomplexität von O(n*m),
|
||||
da jede Kombination aus Elementen von vec1 und vec2 einmal betrachtet wird.
|
||||
Daher ist die gesamte Zeitkomplexität O(n log n + m log m + n*m).
|
||||
Die Anzahl der Operationen entspricht im Wesentlichen der Zeitkomplexität.
|
||||
*/
|
||||
|
||||
vector<pair<int, int>> sorted_pairs(vector<int> vec1, vector<int> vec2){
|
||||
vector<pair<int, int>> returnpairs;
|
||||
pair<int, int> p;
|
||||
mergeSort(vec1);
|
||||
mergeSort(vec2);
|
||||
for(unsigned i = 0; i < vec1.size(); i++){
|
||||
for(unsigned j = 0; j < vec2.size(); j++){
|
||||
p = {vec1[i], vec2[j]};
|
||||
returnpairs.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 12.05.2023
|
||||
Katharina Klost
|
||||
|
||||
Hilfsfunktionen zum Sortieren, nur zusammen mit der sorting.cpp zu compilieren
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "hilfsfunktionen.hpp"
|
||||
|
||||
|
||||
namespace hf{
|
||||
|
||||
void gebe_aus(std::vector<int>& vec, unsigned start, unsigned end){
|
||||
if(end>vec.size()){
|
||||
std::cout << vec.size() << " " << end << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << vec[start];
|
||||
for(unsigned k=start+1; k<end; k++){
|
||||
std::cout << ", " << vec[k];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void swap(std::vector<int>& elems, unsigned i, unsigned j){
|
||||
if (i>=elems.size() || j >= elems.size()){
|
||||
return;
|
||||
}
|
||||
int tmp = elems[i];
|
||||
elems[i] = elems[j];
|
||||
elems[j] = tmp;
|
||||
}
|
||||
|
||||
unsigned minimumIndex(std::vector<int>& elems, unsigned start, unsigned end){
|
||||
unsigned min = start;
|
||||
for(unsigned i = start; i<end; i++){
|
||||
if(elems[i] < elems[min]){
|
||||
min = i;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
std::vector<int> copy(std::vector<int>& elems, unsigned start, unsigned end){
|
||||
std::vector<int> returnVec;
|
||||
for(unsigned i= start; i<end; i++){
|
||||
returnVec.push_back(elems[i]);
|
||||
}
|
||||
return returnVec;
|
||||
}
|
||||
|
||||
bool generator_started = false;
|
||||
int zufall(int left, int right) {
|
||||
// Vor der ersten Zufallszahl muss der Zufallsgenerator gestartet werden.
|
||||
if (!generator_started) {
|
||||
srandom(time(NULL));
|
||||
generator_started = true;
|
||||
}
|
||||
return left + random() % (right-left);
|
||||
}
|
||||
|
||||
std::vector<int> sortiertes_array(unsigned size, bool aufsteigend) {
|
||||
std::vector<int> array(size);
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
array[i] = aufsteigend * i + (!aufsteigend) * (size - i - 1);
|
||||
return array;
|
||||
}
|
||||
|
||||
std::vector<int> zufalls_array(unsigned size) {
|
||||
std::vector<int> array(size);
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
array[i] = zufall(0, size);
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 12.05.2023
|
||||
Katharina Klost
|
||||
|
||||
Headerdatei zu den Hilfsfunktionen zum Sortieren
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
// #include "telefonbuch.hpp"
|
||||
|
||||
namespace hf{
|
||||
/*
|
||||
Voraussetzung: 0 <= start <= end < vec.elems()
|
||||
Ergebnis: Keins
|
||||
Effekt: Gibt die Elemente des Vektors im Intervall [start,end) aus
|
||||
*/
|
||||
void gebe_aus(std::vector<int>& elems, unsigned start, unsigned end);
|
||||
|
||||
/*
|
||||
Voraussetzung: 0<=start<=end < vec.elems()
|
||||
Ergebnis: Ein vector, mit alle Elemente im Intervall [start, end)
|
||||
Effekt: Keiner
|
||||
*/
|
||||
std::vector<int> copy(std::vector<int>& elems, unsigned start, unsigned end);
|
||||
|
||||
/*
|
||||
Voraussetzung: 0 <= i,j <= elems.size()
|
||||
Ergebnis: Keins
|
||||
Effekt: Tauscht die Einträge and Position i und j
|
||||
*/
|
||||
void swap(std::vector<int>& elems, unsigned i, unsigned j);
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Voraussetzung: Es gilt 0 <= start <= end < elems.size()
|
||||
Effekt: Keiner
|
||||
Ergebni: Index des kleinesten Elements zwischen start und end
|
||||
*/
|
||||
unsigned minimumIndex(std::vector<int>& elems, unsigned start, unsigned end);
|
||||
|
||||
|
||||
/*
|
||||
Voraussetzung: left < right
|
||||
Ergebnis: Eine Zufallszahl zwischen left(inklusive) und right (exklusive)
|
||||
Effekt: Keiner
|
||||
*/
|
||||
int zufall(int left, int right);
|
||||
|
||||
/*
|
||||
Voraussetzung: Keine
|
||||
Effekt: Keiner
|
||||
Ergebnis: Ein sortierter vector ist geliefert. Wenn aufsteigend=true ist der vector aufsteigend sortiert, sonst absteigends
|
||||
*/
|
||||
std::vector<int> sortiertes_array(unsigned size, bool aufsteigend);
|
||||
|
||||
/*
|
||||
Voraussetzung: Keine
|
||||
Effekt: Keiner
|
||||
Ergebnis: Ein vector mit zufälligen Werten ist geliefert. Hierbei wird jede Zahl gleichverteilt
|
||||
zufällig zwischen 0 und size gewählt. Doppelte Zahlen sind möglich.
|
||||
*/
|
||||
std::vector<int> zufalls_array(unsigned size);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w5/min.cpp -o ./bin/min && ./bin/min
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int min(const std::vector<int>& vec);
|
||||
|
||||
int main() {
|
||||
std::vector<int> testVec = {10, 20, 2, 0, 30};
|
||||
std::cout << "The minimum value in the vector is: " << min(testVec) << std::endl;
|
||||
}
|
||||
|
||||
int min(const std::vector<int>& vec) {
|
||||
int minVal = vec[0];
|
||||
for (unsigned i = 1; i < vec.size(); ++i) {
|
||||
if (vec[i] < minVal) {
|
||||
minVal = vec[i];
|
||||
}
|
||||
}
|
||||
return minVal;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
clear && g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w5/turn_min.cpp -o ./bin/turn_min && ./bin/turn_min
|
||||
|
||||
Bei jedem Durchlauf halbieren wir die Größe der Eingabe (also n/2),
|
||||
und wir müssen alle Elemente betrachten, um das Minimum zu finden (also O(n))
|
||||
Daraus folgt die Rekursionsgleichung: T(n) = T(n/2) + O(n)
|
||||
|
||||
Da wir log(n) Runden benötigen und in jeder Runde O(n) Operationen durchführen
|
||||
beträgt die Gesamtlaufzeit des Algorithmus O(n log n)
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
std::pair<int, int> TurnMin(std::vector<int>& vec);
|
||||
|
||||
int main() {
|
||||
std::vector<int> vec = {7, 3, 2, 5, 10, -5, 4, 6,2,2,3,4,4,5,6,76,7,78};
|
||||
auto ergebnis = TurnMin(vec);
|
||||
std::cout << "Die Gewinnerzahl, nach " << ergebnis.first << " Runden, ist: " << ergebnis.second << std::endl;
|
||||
}
|
||||
|
||||
std::pair<int, int> TurnMin(std::vector<int>& vec) {
|
||||
int runde = 0;
|
||||
while (vec.size() > 1) {
|
||||
std::vector<int> gewinner;
|
||||
for (unsigned i = 0; i < vec.size(); i += 2) {
|
||||
if (vec[i] < vec[i + 1]) {
|
||||
gewinner.push_back(vec[i]);
|
||||
}
|
||||
else {
|
||||
gewinner.push_back(vec[i + 1]);
|
||||
}
|
||||
}
|
||||
vec = gewinner;
|
||||
runde++;
|
||||
}
|
||||
return {runde, vec[0]};
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
// clear && g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w5/hilfsfunktionen.cpp ./w5/ultrasort.cpp -o ./bin/ultrasort && ./bin/ultrasort
|
||||
|
||||
#include "hilfsfunktionen.hpp"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
bool isSorted(const std::vector<int>& vec);
|
||||
void insertionSort(std::vector<int>& elems);
|
||||
void merge(std::vector<int>& first_part, std::vector<int>& second_part, std::vector<int>& elems);
|
||||
void ultraSort(std::vector<int>& elems);
|
||||
void ultraSortParam(std::vector<int>& elems, double k);
|
||||
|
||||
int main() {
|
||||
|
||||
srand(time(NULL));
|
||||
double time;
|
||||
std::vector<int> array;
|
||||
|
||||
// Runtime (a)
|
||||
std::cout << "############ RUNTIME (ultraSort) ############ \n";
|
||||
for (int size = 10000; size <= 100000; size *= 10) {
|
||||
std::cout << " " << size << " Elemente:" << std::endl;
|
||||
|
||||
array = hf::zufalls_array(size);
|
||||
|
||||
time = clock();
|
||||
ultraSort(array);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Zufällig: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
array = hf::sortiertes_array(size, true);
|
||||
|
||||
time = clock();
|
||||
ultraSort(array);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Aufsteigend: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
array = hf::sortiertes_array(size, false);
|
||||
|
||||
time = clock();
|
||||
ultraSort(array);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Absteigend: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
if (isSorted(array)) {
|
||||
std::cout << " Array is sorted.\n";
|
||||
} else {
|
||||
std::cout << " Array is not sorted.\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Optimal k
|
||||
std::cout << "############ OPTIMAL K ############ \n";
|
||||
std::vector<double> k_values = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9};
|
||||
double optimal_k = 0;
|
||||
double shortest_time = std::numeric_limits<double>::max();
|
||||
for (double k : k_values) {
|
||||
|
||||
array = hf::zufalls_array(10000);
|
||||
time = clock();
|
||||
ultraSortParam(array, k);
|
||||
time = clock() - time;
|
||||
|
||||
if (time < shortest_time) {
|
||||
shortest_time = time;
|
||||
optimal_k = k;
|
||||
}
|
||||
}
|
||||
std::cout << " Optimal k is " << optimal_k << std::endl;
|
||||
|
||||
// Runtime (b)
|
||||
std::cout << "############ RUNTIME (ultraSortParam) ############ \n";
|
||||
for (int size = 10000; size <= 100000; size *= 10) {
|
||||
std::cout << " " << size << " Elemente:" << std::endl;
|
||||
|
||||
array = hf::zufalls_array(size);
|
||||
|
||||
time = clock();
|
||||
ultraSortParam(array, optimal_k);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Zufällig: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
array = hf::sortiertes_array(size, true);
|
||||
|
||||
time = clock();
|
||||
ultraSortParam(array, optimal_k);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Aufsteigend: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
array = hf::sortiertes_array(size, false);
|
||||
|
||||
time = clock();
|
||||
ultraSortParam(array, optimal_k);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Absteigend: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
if (isSorted(array)) {
|
||||
std::cout << " Array is sorted.\n";
|
||||
} else {
|
||||
std::cout << " Array is not sorted.\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isSorted(const std::vector<int>& vec) {
|
||||
for (size_t i = 0; i < vec.size() - 1; ++i) {
|
||||
if (vec[i] > vec[i + 1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void insertionSort(std::vector<int>& elems){
|
||||
int key=elems[0];
|
||||
unsigned shiftindex;
|
||||
for(unsigned i = 1; i<elems.size();i++){
|
||||
key=elems[i];
|
||||
for(shiftindex=i; shiftindex>0&&elems[shiftindex-1]>=key;shiftindex--){
|
||||
elems[shiftindex] = elems[shiftindex-1];
|
||||
}
|
||||
elems[shiftindex] = key;
|
||||
}
|
||||
}
|
||||
|
||||
void merge(std::vector<int>& first_part, std::vector<int>& second_part, std::vector<int>& elems){
|
||||
unsigned i = 0;
|
||||
unsigned j = 0;
|
||||
unsigned begin = 0;
|
||||
unsigned end = elems.size();
|
||||
|
||||
while(begin + i + j < end){
|
||||
if ( j >= second_part.size() || ((i<first_part.size()) && (first_part[i]<second_part[j]))){
|
||||
elems[begin+i+j] = first_part[i];
|
||||
i++;
|
||||
}
|
||||
else{
|
||||
elems[begin+i+j] = second_part[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ultraSort(std::vector<int>& elems){
|
||||
if (elems.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
if (elems.size() < 10) {
|
||||
insertionSort(elems);
|
||||
return;
|
||||
}
|
||||
int groesse_erster_teil = elems.size() / 3;
|
||||
std::vector<int> erster_teil(elems.begin(), elems.begin() + groesse_erster_teil);
|
||||
std::vector<int> zweiter_teil(elems.begin() + groesse_erster_teil, elems.end());
|
||||
insertionSort(erster_teil);
|
||||
ultraSort(zweiter_teil);
|
||||
merge(erster_teil, zweiter_teil, elems);
|
||||
}
|
||||
|
||||
void ultraSortParam(std::vector<int>& elems, double k){
|
||||
if (elems.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
if (elems.size() < 10) {
|
||||
insertionSort(elems);
|
||||
return;
|
||||
}
|
||||
int groesse_erster_teil = static_cast<int>(k * elems.size());
|
||||
std::vector<int> erster_teil(elems.begin(), elems.begin() + groesse_erster_teil);
|
||||
std::vector<int> zweiter_teil(elems.begin() + groesse_erster_teil, elems.end());
|
||||
insertionSort(erster_teil);
|
||||
ultraSortParam(zweiter_teil, k);
|
||||
merge(erster_teil, zweiter_teil, elems);
|
||||
}
|
||||
Reference in New Issue
Block a user