You are on page 1of 3

/*

* File: 20161004_CPP_L16.cpp.
* Title: 2016-10-04 C++ Lesson 16
* Author: Renato Montes
* Description: Notes for Albert Wei's C++ class
*/

//in functional programming, functions keep on calling other functions, thus:


f(g(h(i(j(k())))));
//the program is reduced to one line...!
//read from the inside out: k() is called first, then j(), then i()...

//some languages nowadays implement this syntax instead, for readability:


k|j|i|h|g|f

/* Deque */
#include <deque>

//O(1) insertion & deletion at both ends


//extra methods: push_front / pop_front
//provides Random Access Iterator

//essentially the same as a vector, except you can add at the beginning
// and remove from the beginning

//example: non-recursive mergesort

//array to be sorted:
{3,2,7,6,8}
//queue of vectors: merge and push_back
{3,2,7,6,8}
{7,6,8,{2,3}} //merged 2 and 3 pushed them back
{8,{2,3},{6,7}}
//thus this is the non-recursive version of mergesort, as a loop

vector <int> mergesort(const vector<int>& v) {


//precondition: !v.empty()
deque<vector<int>> d;
for (auto x : v)
d.push_back(vector<int>(1,x));
//there's a constructor that takes a number and then some x: 4, x
// exactly the same as the string constructor that takes int and start
// a string is basically a vector of characters
//no name for vector<int>(1,x): a temporary object
while(d.size() >= 2) {
d.push_back(merge(d[0], d[1]));
//we merge, then we me need to remove these d[0] and d[1]
d.pop_front();
d.pop_front();
return d[0];
//reminder: precondition is that v cannot be empty
// must be able to return a thing at d[0]
}

//containers have a clear() method: it clears all content


/* Quicksort */

//first version is how it's done in functional programming


// recursive

//how does Quicksort work?


//choose an element x, and use it as a pivot
//divide rest into 2 groups:
// 1) elements < x
// 2) elements >= x
//recursively sort 1) and 2)
//and put them back together

//the easy non-C++ version


//very high-level language version:
-module(q).
-export([qsort/1]).
qsort([]) -> [];
//sort the empty list, give me the empty list
qsort([H|T]) -> qsort([X || X <- T, X < H]) ++ [H] ++
qsort([X || X <- T, X >= H]).
//H is head, T is tail
//remember math notation for the parameter of qsort
//this language is Erlang
// unfortunately, you cannot use it in this course or the Algorithms course

//C++ cannot do this


//the creators of Java, C++, etc. essentially aim to make your life more,
// more difficult
//they have a lot to answer

//base case: if size <= 1, return original vector

/* * pair */
//to use a pair, include the following:
#include <utility>
//but note <utility> is included in a lot of headers, e.g. Map

//a pair is just a template, something like this:


template<typename A, typename B>
struct pair {
A first;
B second;
//methods: copy ctor, etc.
};
pair<int, double> p(123, 76.5);
cout << p.first << ' ' << p.second << endl;

//now there's a convenient function template, make_pair


make_pair function template
p = make_pair(156, 88.5); //the function template deduces from its arguments
// what the template arguments need to be:
// a pair of int and double
//a lot of the simple classes have a corresponding function template
// that returns an object of that class
// note: vector is not one of such simple classes with a function template

pair<vector<int>, vector<int>>
split(const vector<int>& v) { //precondition: !v.empty()
//we'll use v[0] as a pivot for quicksort:
pair<vector<int>, vector<int>> result;
for (vector<int>::size_type i = 1; i < v.size(); i++)
if (v[i] < v[0]) //use v[0] as pivot
result.first.push_back(v[i]);
else
result.second.push_back(v[i]);
return result;
}
vector<int>
operator+(const vector<int>& v1, const vector<int>& v2) {
vector<int> result(v1); //calls copy ctor
result.insert(result.end(), v2.begin(), v2.end());
//remember: insert takes a position and a range specified by two iterators
return result;

vector<int>
qsort(const vector<int>& v) {
//base case:
if (v.size() <= 1)
return v;
auto p = split(v);
return qsort(p.first) + vector<int>(1, v[0]) + qsort(p.second);
}

//now what if you want to write the REAL qsort()??


/* * How to split the vector without making copies */

//sections (or regions) of array:


// < x
// = x
// (unclassified)
// > x

//[ < x | = x | unclassified | > x ]

//[first, equal): elements < x


//[equal, unclassified): elements == x
//[unclassified, greater): unclassified elements
//[greater, last): elements > x

//what the code will look like


while(unclassified != greater) {
//we go through each unclassified elements and see in which region it goes
...
}
//do a swap if unclassified element is not equal to pivot x
//"THINK ABOUT IT!!!"

You might also like