Computational tasks and solutions
In sorting, we're trying to sort records in a sequence by keys, with respect to an operator or a functor.
Sorting in the STL is done either using iterators for container structures, or using indices and arrays.
operator< // compare two items
operator[] // access k-th element
swap(): // swap A and B
copmswap() // compare two items, and if B is smaller call swap()
mySort() // algorithm/implementation
main() // testing it out
swap()
implementationCustom implementation:
template <typename T>
void swap(T &a, T &b) {
T tmp = a;
a = b;
b = tmp;
}
Don't do this! Just use #include <utility>
. Usually, in C++11, there are speed improvements for swapping for some data types, and this implementation is the worst case.
template <typename T>
void compswap(T &a, T &b) {
if (b < a) {
swap(a, b);
}
}
Stability: preserve order of duplicate keys. Simple sorts tend to be stable, and complex sorts are not stable.
Non-adaptive sort: The sequence of operations is independent of order of data. The algorithm is going to do the same amount of work on 10 items where there is only 1 unsorted thing, and the same when all are unsorted.
Adaptive sort: If all are mostly sorted, then performs differently when mostly sorted. Worst case complexity is not equal to best case complexity.
void bubble(item a[], int left, int right) {
for (int i = left; i < right; i++)
for (int j = right - 1; j > i; j--)
compswap(a[j - 1], a[j]);
}
Finds maximum item on list on first pass by comparing adjacent items, and moves item all the way to the left.
You just need some more information.
void bubble_adaptive(item a[], int left, int right) {
for (int i = left; i < right; i++) {
bool swapped = false;
for (int j = right - 1; j > 1; j--) {
if (a[j] > a[j - 1]) {
swapped = true;
swap(a[j - 1], a[j]);
}
}
if (!swapped) {
break;
}
}
}
void selection(item a[], int left, int right) {
for (int i = left; i < right; i++) {
int min = i;
for (int j = i + 1; j < right; j++) {
if (a[j] < a[min]) {
min = j;
}
}
swap(a[i], a[min]);
}
}
void selection(item a[], int left, int right) {
for (int i = left; i < right; i++) {
int min = i;
for (int j = i + 1; j < right; j++) {
if (a[j] < a[min]) {
min = j;
}
}
if (i != min) swap(a[i], a[min]); // changed
}
}
Much faster.
void insertion(item a[], int left, int right) {
for (i = left+1; i < right; i++)
for (j = i; j > left; j--)
compswap(a[j-1], a[j]);
}
Faster implementation:
void insertion(Item a[], int left, int right) {
for (int i = left + 1; i < right; i++) {
Item v = a[i]; int j = i;
for (int j = i; j > left; j--) {
compswap(a[j - 1], a[j]);
if (v < a[j - 1])
a[j] = a[j - 1];
else
break;
}
a[j] = v;
}
}
Adaptive:
void insertion(Item a[], int left, int right) {
for (int i = right - 1; i > left; i--) // find min item
compswap(a[i - 1], a[i]); // put in a[left]
// this is sentinel
for (int i = left + 2; i < right; i++) {
Item v = a[i]; int j = i; // v is new item
while (v < a[j - 1] && (j > left)) { // v in wrong spot
a[j] = a[j - 1]; // half swap (move)
j--;
}
a[j] = v;
}
}