I am trying to count the number of comparisons done by heap sorting algorithm.
my code is based on priority queue and I want to know where I should put the counter. here is what I have but when I try to print the counter it shows zero counts, what am I doing wrong? Thank you.
here is the heapbuild function:
#include<iostream>
vector<int> pq_keys;
void buildHeap()
{
int size = pq_keys.size();
int midIdx = (size -2)/2;
while (midIdx >= 0)
{
shiftRight(midIdx, size-1);
--midIdx;
}
and this is the function that does the comparison:
int shiftRight(int low, int high)
{
int root = low;
int counter=0;
while ((root*2)+1 <= high)
{
int leftChild = (root * 2) + 1;
int rightChild = leftChild + 1;
int swapIdx = root;
if (pq_keys[swapIdx] < pq_keys[leftChild])
{
counter++;
cout<<counter;
swapIdx = leftChild;
}
/*If right child exists check if it is less than current root*/
if ((rightChild <= high) && (pq_keys[swapIdx] < pq_keys[rightChild]))
{
counter++;
swapIdx = rightChild;
}
/*Make the biggest element of root, left and right child the root*/
if (swapIdx != root)
{
counter++;
int tmp = pq_keys[root];
pq_keys[root] = pq_keys[swapIdx];
pq_keys[swapIdx] = tmp;
root = swapIdx;
}
else
{
break;
}
}
return counter;
}
You want to increment the counter before you do the comparison. Consider this code, from your shiftRight method:
if (pq_keys[swapIdx] < pq_keys[leftChild])
{
counter++;
cout<<counter;
swapIdx = leftChild;
}
That only increments the counter if the conditional is true. If pq_keys[swpIdx] >= pq_keys[leftChild], then you made the comparison without counting it. You need to change your code to be:
counter++;
if (pq_keys[swapIdx] < pq_keys[leftChild])
{
cout<<counter;
swapIdx = leftChild;
}
You need to do the same thing in the other two places where you count comparisons: increment the counter, then do the comparison.
class LessPredicate
{
size_t callCount_ = 0;
temlate<class T>
bool compare(const T& l, conct T& r)
{
return l < r; // or other logic
}
public:
size_t CallTimes() const { return callCount_; }
temlate<class T>
bool operator() (const T& l, conct T& r)
{
++callCount_;
return compare(l, r);
}
};
int main()
{
LessPredicate less;
...// use it like less(a, b) instead a < b;
auto compareCount = less.CallTimes();
}
Related
So I was doing a question on LeetCode...
Question:
Write an efficient algorithm that searches for a target value in an m x n integer matrix. The matrix has the following properties:
Integers in each row are sorted in ascending from left to right.
Integers in each column are sorted in ascending from top to bottom.
Example 1:
Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
Output: true
Example 2:
Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
Output: false
So first I attempted this question by regular brute force method:
Answer-1:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int t) {
int i=0,j,I=matrix.size(),J,mj;
for(;i<I;i++)
{
j=0;J=matrix[i].size()-1;
mj=(j+J)/2;
while(j<=J)
{
if(matrix[i][mj]==t)
return true;
else if(matrix[i][mj]<t)
j=mj+1;
else
J=mj-1;
mj=(j+J)/2;
}
}
return false;
}
};
Then I decided to do it by idk Divide and Conquer ig...
Answer-2:
class Solution {
public:
bool VFinder(vector<vector<int>>& matrix, int hstart, int hend, int vstart, int vend, int ele)
{
if(vstart > vend || hstart > hend)
return false;
int mid = vstart;
int start = vstart;
int end = vend;
while(start<=end)
{
mid = (int)((start + end) / 2);
if (start == end)
{
if (matrix[mid][hstart] == ele)
{
return true;
}
else
{
return HFinder(matrix, hstart + 1, hend, vstart, mid, ele);
}
}
else
{if(matrix[mid][hstart] <ele && matrix[mid+1][hstart] > ele)
return HFinder(matrix, hstart+1, hend, vstart, mid,ele);
else if(matrix[mid][hstart] <ele)
start = mid+1;
else if(matrix[mid][hstart] >ele)
end = mid-1;
else if(matrix[mid][hstart] == ele)
return true;}
}
return false;
}
bool HFinder(vector<vector<int>>& matrix, int hstart, int hend, int vstart, int vend, int ele)
{
if(hstart > hend || vstart > vend)
return false;
int mid = hstart;
int start = hstart;
int end = hend;
while(start<=end)
{
mid = (int)((start + end) / 2);
if (start == end)
{
if (matrix[vstart][mid] == ele)
{
return true;
}
else
{
return VFinder(matrix, hstart, mid, vstart + 1, vend, ele);
}
}
else
{if(matrix[vstart][mid] <ele && matrix[vstart][mid+1] > ele)
return VFinder(matrix, hstart, mid, vstart+1, vend, ele);
else if(matrix[vstart][mid] <ele)
start = mid+1;
else if(matrix[vstart][mid] >ele)
end = mid-1;
else if(matrix[vstart][mid] == ele)
return true;}
}
return false;
}
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int horizontal = matrix[0].size();
int vertical = matrix.size();
return HFinder(matrix, 0, horizontal-1, 0, vertical-1, target);
}
};
So the first code after submission took about : 328 ms
And the second one took about : 488 ms
But in second one, I am after each step reducing the search space, so it should have taken less time as compared to the first code, but it is not happening so.
Can someone please tell me why is it so?
And also what is the time complexity of the second code?
I've been trying to understand what havn't I initialized in this code and I completely(?) understand what is uninitialized but I don't know how to initialize it.
I am getting the error:
==11931== Conditional jump or move depends on uninitialised value(s)
==11931== at 0x804ABA6: Hashtable<int>::put(int, int) (hash_table.h:169)
==11931== by 0x8048F80: test_put() (hash_table_test.cpp:27)
==11931== by 0x804A551: main (hash_table_test.cpp:52)
==11931== Uninitialised value was created by a heap allocation
==11931== at 0x402ADFC: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11931== by 0x804A9AE: Hashtable<int>::Hashtable() (hash_table.h:64)
==11931== by 0x8048F62: test_put() (hash_table_test.cpp:26)
==11931== by 0x804A551: main (hash_table_test.cpp:52)
from the valgrind so apparantly I havn't been initializing correctly the c'tor for Hashtable class:
Hashtable() :
ht_keys(2), ht_size(0), dynamicArray(NULL) {
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i].delete_val = false;
dynamicArray[i].key=0;
dynamicArray[i].default_node = false;
}
}
the dynamic array is of type Node* which it's private fields are:
bool delete_val;
T element;
int key;
bool default_node;
the class Node is inside the class Hashtable.
how can I initialize dynamicArray?
here's the full code:
#include <string>
#include <iostream>
#include "library2.h"
#include <iterator>
using namespace std;
#ifndef HASH_TABLE_HPP_
#define HASH_TABLE_HPP_
#define DIV 2
//type T must have c'tor, operator !=
template<class T>
class Hashtable {
public:
class Node {
public:
Node(const T t) :
delete_val(false), element(t), key(0), default_node(true) {
}
Node(bool v, const Node& n) :
delete_val(v), element(n.element), key(0), default_node(
n.default_node) {
}
Node(const Node& n) :
delete_val(false), element(n.element), key(n.key), default_node(
n.default_node) {
}
Node() :
delete_val(false), key(0), default_node(true) {
}
bool operator==(const Node* n) {
if (n) {
if (element != n->element || default_node != n->default_node) {
return false;
}
return true;
}
return false;
}
bool operator!=(const Node n) {
if (!(*this == n)) {
return false;
}
return true;
}
bool delete_val;
T element;
int key;
bool default_node;
};
Hashtable() :
ht_keys(2), ht_size(0), dynamicArray(NULL) {
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i].delete_val = false;
dynamicArray[i].key=0;
dynamicArray[i].default_node = false;
}
}
//seriously damaged programming...
Hashtable(Node* array, int HT_keys, int HT_size) :
ht_keys(HT_keys), ht_size(HT_size) {
dynamicArray = new Node[ht_keys];
if (array != NULL) {
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i] = array[i];
}
}
}
Hashtable(const Hashtable& ht) {
if (&ht == this) {
return;
}
ht_keys = ht.ht_keys;
ht_size = ht.ht_size;
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht.ht_keys; i++) {
this->dynamicArray[i] = ht.dynamicArray[i];
}
}
~Hashtable() {
delete[] this->dynamicArray;
}
Hashtable operator=(const Hashtable& ht) {
Hashtable<T> newHT = ht;
return newHT;
}
//Returns true if some value equal to value exists within the hash table.
bool contains(Node n, int i) {
if (i < 0 || i > ht_keys || !n) {
return false;
}
if (i == ht_keys) {
return false;
}
//make sure that n.delete_val is not set as true.
if (dynamicArray[i]->element == n.element
&& !dynamicArray[i]->delete_val) {
return true;
}
if (dynamicArray[i]->delete_val) {
return contains(n, i + 1);
}
return false;
return true;
}
//Returns true if some key equal to key exists within the hash table.
bool containsKey(int i) {
if (i < 0 || i > ht_keys) {
return false;
}
if (dynamicArray[i]->element && !dynamicArray[i]->delete_val) {
return true;
}
return false;
}
//Returns true if some value equal to value exists within the hash table.
bool containsValue(T e) {
return true;
}
//Returns an enumeration of the values contained in the hash table.
int enumeration() {
return ht_size;
}
//Returns the object that contains the value associated with key.
//If key is not in the hash table, a null object is returned.
Node get(int i) {
if (i >= 0) {
return dynamicArray[i % ht_keys];
}
Node n;
return n;
}
//Returns true if the hash table is empty;
//returns false if it contains at least one key.
bool isEmpty() {
if (ht_size) {
return false;
}
return true;
}
//Returns an enumeration of the keys contained in the hash table.
int keys();
//Inserts a key and a value into the hash table.
//Returns false if key isn't already in the hash table;
//returns true if key is already in the hash table.
bool put(T e, int i) {
if (e && i > 0) {
Node n;
n.default_node = false;
n.delete_val = false;
n.key = i;
n.element = e;
//line 168
for (int j = (i % ht_keys); j < ht_keys; j = ((j + 1) % ht_keys)) { //line 169
if (!dynamicArray[j % ht_keys].element
|| dynamicArray[j % ht_keys].delete_val) {
dynamicArray[j % ht_keys] = n;
ht_size++;
return true;
}else if (i == (j + 1) % ht_keys) {
rehash();
return put(e, i);
}
}
return false;
}
return false;
}
bool put_aux(Node n, int i, Node* Array, int HT_keys) {
for (int j = (i % HT_keys); j < HT_keys; j = ((j + 1) % HT_keys)) {
if (!Array[j % HT_keys].element || Array[j % HT_keys].delete_val) {
Array[j % HT_keys] = n;
return true;
} else if (Array[j % HT_keys].element == n.element) {
return true;
}
}
return false;
}
//Increases the size of the hash table and rehashes all of its keys.
void rehash() {
int old_ht_keys = ht_keys;
ht_keys = DIV * ht_keys;
Node* newArray = new Node[ht_keys];
if (ht_keys > DIV) {
for (int j = 0; j < old_ht_keys; j++) {
put_aux(dynamicArray[j],dynamicArray[j].key,newArray,ht_keys);
}
}
delete[] dynamicArray;
dynamicArray = newArray;
}
//Removes key and its value.
//Returns the value associated with key.
//If key is not in the hash table, a null objecht_sizet is returned.
T remove(int i) {
if (i >= 0 && i < ht_keys) {
Node deleted_node(true, dynamicArray[i % ht_keys]);
dynamicArray[i % ht_keys] = deleted_node;
ht_size--;
return deleted_node.element;
}
return NULL;
}
//Returns the number of entries in the hash table.
int size() {
return this->ht_size;
}
private:
int ht_keys;
int ht_size;
Node* dynamicArray;
};
#endif /* HASH_TABLE_HPP_ */
It seems to be complaining about the line !dynamicArray[j % ht_keys].element (on line 163 of the code you posted; this would be a lot easier if the code you posted matched the code valgrind was using; right now the code you posted is several lines shorter than the code valgrind is using).
You never initialize the element member when you allocate the memory in the constructor. You then attempt to use it here in a conditional statement. valgrind correctly warns you of the problem.
I'm trying to work with this heap. I'm inserting a few random numbers then removing them to make sure my heap works. The problem is when I'm removing them I get duplicate numbers that shouldn't exist in the Heap. Pretty much I'll insert the following numbers and get back in return: 5 2 10 10 for some reason.
My main looks like this:
#include <iostream>
#include <fstream>
using namespace std;
#include "heap.h"
int main(void)
{
Heap<int> inlist(4);
inlist.insert(5);
inlist.insert(2);
inlist.insert(3);
inlist.insert(10);
int test;
while(inlist.remove(test))
cout << test << endl;
}
And my Heap looks like this:
#ifndef HEAP_H
#define HEAP_H
template<typename TYPE>
class Heap
{
private:
TYPE* heapData;
int currSize;
int capacity;
void _siftUp(int);
void _siftDown(int);
int _leftChildOf(int) const;
int _parentOf(int) const;
public:
Heap(int c = 100);
~Heap();
bool viewMax(TYPE&) const;
int getCapacity() const;
int getCurrSize() const;
bool insert(const TYPE&);
bool remove(TYPE&);
};
template<typename TYPE>
Heap<TYPE>::Heap(int c = 100)
{
capacity = 100;
currSize = 0;
heapData = new TYPE[capacity];
}
template<typename TYPE>
Heap<TYPE>::~Heap()
{
delete[] heapData;
currSize = 0;
capacity = 0;
}
template<typename TYPE>
bool Heap<TYPE>::insert(const TYPE& dataIn)
{
bool success = false;
if(currSize < capacity)
{
heapData[currSize] = dataIn;
_siftUp(currSize);
currSize++;
success = true;
}
return success;
}
template<typename TYPE>
void Heap<TYPE>::_siftUp(int child)
{
TYPE temp;
int parent;
if(child > 0)
{
parent = _parentOf(child);
if(heapData[child] > heapData[parent])
{
temp = heapData[parent];
heapData[parent] = heapData[child];
heapData[child] = temp;
_siftUp(child);
}
}
}
template<typename TYPE>
bool Heap<TYPE>::remove(TYPE& dataOut)
{
bool success = false;
if(currSize > 0)
{
dataOut = heapData[0];
currSize--;
heapData[0] = heapData[currSize];
_siftDown(0);
success = true;
}
return success;
}
template<typename TYPE>
void Heap<TYPE>::_siftDown(int parent)
{
TYPE temp;
int child = _leftChildOf(parent);
if(child < currSize)
{
if((child + 1 < currSize) && (heapData[child] < heapData[child + 1]))
child++;
if(child)
{
temp = heapData[child];
heapData[child] = heapData[child + 1];
heapData[child + 1] = temp;
_siftDown(child);
}
}
}
template<typename TYPE>
int Heap<TYPE>::_leftChildOf(int p) const
{
return(2 * p + 1);
}
template<typename TYPE>
int Heap<TYPE>::_parentOf(int c) const
{
return((c - 1) / 2);
}
//**************************************************************************
template<typename TYPE>
int Heap<TYPE>::getCapacity() const
{
return capacity;
}
template<typename TYPE>
int Heap<TYPE>::getCurrSize() const
{
return currSize;
}
template<typename TYPE>
bool Heap<TYPE>::viewMax(TYPE& max) const
{
return false;
}
#endif
I'm pretty sure the problem isn't when I'm inserting into my Heap but when I'm removing it.
EDIT I changed my _siftDown a bit - now the numbers show up 5 10 3 2
if(child)
{
temp = heapData[child];
heapData[child] = heapData[parent];
heapData[parent] = temp;
_siftDown(child);
}
Your _siftDown is broken,
template<typename TYPE>
void Heap<TYPE>::_siftDown(int parent)
{
TYPE temp;
int child = _leftChildOf(parent);
if(child < currSize)
{
if((child + 1 < currSize) && (heapData[child] < heapData[child + 1]))
child++;
if(child)
What's that meant to check? child is at this point either 2*parent + 1 or 2*parent + 2, without overflow, since parent should always be >= 0, that is always positive ~> condition fulfilled.
You need to check whether you want to swap heapData[parent] and heapData[child], so that condition should be if (heapData[parent] < heapData[child]).
{
temp = heapData[child];
heapData[child] = heapData[child + 1];
heapData[child + 1] = temp;
You are swapping the elements at index child and child+1, that's wrong. You should swap heapData[child] and heapData[parent] here.
_siftDown(child);
}
}
}
You also have an error in _siftUp,
template<typename TYPE>
void Heap<TYPE>::_siftUp(int child)
{
TYPE temp;
int parent;
if(child > 0)
{
parent = _parentOf(child);
if(heapData[child] > heapData[parent])
{
temp = heapData[parent];
heapData[parent] = heapData[child];
heapData[child] = temp;
_siftUp(child);
}
}
}
the recursive call should be _siftUp(parent), otherwise you never sift any item up more than one level.
Your remove method is good while your _siftDown has something wrong.
It's not always true that you siftdown with your left child.
void Heap<TYPE>::_siftDown(int parent)
{
TYPE temp;
int left= _leftChildOf(parent);
int right= _rightChildOf(parent);
int max= parent;
if(left< currSize && heapData[left] > heapData[max])
{
max= left;
}
if(right< currSize && heapData[right] > heapData[max])
{
max= right;
}
if( max!=parent ) //need to sift down
{
temp = heapData[max];
heapData[max] = heapData[parent];
heapData[parent] = temp;
_siftDown(max);
}
}
}
You can use the following functions instead of implementing your own heap:
std::make_heap
std::push_heap
std::pop_heap
You can find them in the algorithm header
heapData[0] = heapData[currSize];
Here you should not use heapData[currSize] otherwise you are copying the last elemnt of the heap to the top.
For example after removing 5 from the heap currSize is 3 and you do
heapData[0] = heapData[3];
which will create a duplicate of 10 at heapData[0].
Without taking a closer look on your code
You realize that test is never initialized?
int test; //initialization should happen here
while(inlist.remove(test))
cout << test << endl;
I also do not understand what the purpose of the parameter at Heap::remove(dataOut) is. Would it differ from Heap::remove(void) ?
I realized I can't post answers to my own questions because of my low rep or whatever so i deleted my old question and am reasking it. i changed some things and still can't get what i'm looking for.
Here is most of the code
I left out some of the simpler implementations such as parts of the pathFinder class because I know for sure they work, which is why you'll see playerVertex and time just randomly there.
In the example they used a decreaseKey function, I'm not sure if THAT'S what I'm missing? I'm a beginner here, so constructive criticism is welcome. (hopefully as polite as possible) lol. My problem is printing the path, I get a looop of the same two values over and over again.
class Heap
{
public: Heap();
~Heap();
void insert(double element);
double deletemin();
void print();
int size(){return heap.size();}
private:
int currentIndex;
int left(int parent);
int right(int parent);
int parent(int child);
void heapifyup(int index);
void heapifydown(int index);
private:
vector<double> heap;
};
Heap::Heap()
{
currentIndex = 0;
}
Heap::~Heap()
{}
void Heap::insert(double element)
{
heap.push_back(element);
currentIndex++;
heapifyup(heap.size() - 1);
}
double Heap::deletemin()
{
double min = heap.front();
heap[0] = heap.at(heap.size()-1);
heap.pop_back();
heapifydown(0);
currentIndex--;
return min;
}
void Heap::print()
{
vector<double>::iterator pos = heap.begin();
cout << "Heap = ";
while ( pos != heap.end() )
{
cout << *pos;
++pos;
cout << endl;
}
}
void Heap::heapifyup(int index)
{
while((index>0) && (parent(index) >=0) && (heap[parent(index)] > heap[index]))
{
double tmp = heap[parent(index)];
heap[parent(index)] = heap[index];
heap[index] = tmp;
index = parent(index);
}
}
void Heap::heapifydown(int index)
{
int child = left(index);
if((child > 0) && (right(index) > 0) && (heap[child]>heap[right(index)]))
{
child = right(index);
}
if(child > 0)
{
double tmp = heap[index];
heap[index] = heap[child];
heap[child] = tmp;
heapifydown(child);
}
}
int Heap::left(int parent)
{
int i = ( parent <<1) + 1;
return(i<heap.size()) ? i : - 1;
}
int Heap::right(int parent)
{
int i = ( parent <<1) + 2;
return(i<heap.size()) ? i : - 1;
}
int Heap::parent(int child)
{
if(child != 0)
{
int i = (child - 1) >>1;
return i;
}
return -1;
}
class pathFinder : public weightedGraph
{
private:
vertex* playerVertex;
double time;
public:
string source;
pathFinder()
{
playerVertex = NULL;
time = 0;
}
void Dijkstra(int s,int t)
{
vertex *verts = findVertex(grid[s][t]);
Heap H;
for each(vertex *v in vertexList)
{
if(v->data == verts->data)
{
verts->distance = 0;
verts->pred = NULL;
}
v->distance = INFINITY;
v->pred = NULL;
H.insert(v->data);
}
while(H.size() != 0)
{
vertex *x = findVertex(H.deletemin());
for each(edge *v in x->adjacencyList)
{
if(v->end->visited != true)
{
relax(x,v->end);
v->end->visited = true;
}
else
break;
}
}
}
void relax(vertex *a, vertex *b)
{
if(a->distance + weightFrom(a,b) > b->distance)
{
b->distance = a->distance + weightFrom(a,b);
b->pred = a;
}
}
void printPath(double dest,double dest1)
{
vertex *verta = findVertex(dest);
while(verta->pred->data != dest1)
{
cout<<verta->data<<endl;
verta = verta->pred;
}
}
and i'm not sure about the print path being that. i just used the print path from the BFS algorithm i've implemented before.
Where in your printPath function are you looking for the end of the list?
You keep going verta = verta->pred until the data is not equal to some value.
By the way, don't compare doubles for equality, as it ain't going to happen. See What Every Computer Scientist Should Know About Floating Point.
What happens when you single step with your debugger?
(Try drawing the links and how you traverse them.)
I want to take this merge_sort I wrote and put it into a class. Because their is some coupling of the variables, particularly - left, right_begin, right...I want to make these class members. The variables that are local to each function I will leave as local function variables.
Also this function will be used for another class I have called dynamic_array which is a bit more efficient than vector. However I want to make it available to the STL vector as well.
How do I do this. Do I use inheritance? Do I make the class a composite class of my dynamic_array...If I do this it will not be available to vector though.
The Question:
How do I make my merge_sort class interface with the STL container Vector and to my own container dynamic_array.
This is for an interview preparation.
Thank you. Dynamic Array code below(remove old merge_sort cold)
Merge Sort Code - to be converted to a class
#include <iostream>
using namespace std;
const int size=8;
int scratch[size],array[size]={6,5,3,1,8,7,2,4};
void print_array(int arr[]){ for (int i = 0; i < size; i++) cout << arr[i] << endl;}
void flip_if_unordered(int &x, int &y)
{
if(array[x]>array[y])
{
int tmp = array[x];
array[x] = array[y];
array[y] = tmp;
}
}
void merge_algo(int &left, int &right_begin, int &right)
{
int iter,iter_left=left,iter_right=right_begin;
for(iter=left;iter<=right;++iter)
{
if( (iter_right>right) || ((iter_left < right_begin) && (array[iter_left]<=array[iter_right])))
{
scratch[iter]=array[iter_left];
++iter_left;
}
else
{
scratch[iter]=array[iter_right];
++iter_right;
}
}
for(iter=left;iter<=right;++iter){array[iter]=scratch[iter];}
}
void merge_recurse(int left,int right)
{
int left_end=(left+((right-left)/2));
int right_begin=left_end+1;
if(((left+1)==right)){flip_if_unordered(left,right);return;}
else if ((left==right)){return;}
else
{
merge_recurse(left,left_end);
merge_recurse(right_begin,right);
merge_algo(left,right_begin,right);
}
}
int main()
{
merge_recurse(0,(size-1));
print_array(array);
return 0;
}
Dynamic Array
#include "c_arclib.cpp"
using namespace std;
template <class T> class dynamic_array
{
private:
T* array;
T* scratch;
void merge_recurse(int left, int right)
{
if(right == left + 1)
{
return;
}
else
{
int i = 0;
int length = right-left;
int midpoint_distance = length/2;
int l = left, r = left + midpoint_distance;
merge_recurse(left, left + midpoint_distance);
merge_recurse(left + midpoint_distance, right);
for(i = 0; i < length; i++)
{
if((l < (left + midpoint_distance)) && (r == right || array[l] > array[r]))
{
scratch[i] = array[l];
l++;
}
else
{
scratch[i] = array[r];
r++;
}
}
for(i = left; i < right; i++)
{
array[i] = scratch[i - left];
}
}
}
void quick_recurse(int left, int right)
{
int l = left, r = right, tmp;
int pivot = array[(left + right) / 2];
while (l <= r)
{
while (array[l] < pivot)l++;
while (array[r] > pivot)r--;
if (l <= r)
{
tmp = array[l];
array[l] = array[r];
array[r] = tmp;
l++;
r--;
}
}
if (left < r)quick_recurse(left, r);
if (l < right)quick_recurse(l, right);
}
public:
int size;
void rorder();
void order();
void randorder();
dynamic_array(int sizein)
{
size=sizein;
array=new T[size]();
}
void print_operator(std::ostream &os = cout) const
{
for (int i = 0; i < size; i++) os << array[i] << endl;
}
int merge_sort()
{
scratch = new T[size]();
if(scratch != NULL)
{
merge_recurse(0, size);return 1;
}
else{return 0;}
}
void quick_sort()
{
quick_recurse(0,size);
}
};
template <class T> void dynamic_array<T>::randorder()
{
srand(time(NULL));
int *ap;
for(ap=array;ap!=array+size;++ap){*ap=rand();}
}
template <class T> void dynamic_array<T>::order()
{
int *ap,i=0;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
++i;
}
}
template <class T> void dynamic_array<T>::rorder()
{
int *ap,i=size;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
--i;
}
}
template<class T> ostream& operator<<(ostream& stream, dynamic_array<T> const& data)
{
data.print_operator(stream);
return stream;
}
int main()
{
dynamic_array<int> d1(10);
d1.order();
cout << d1;
/*
clock_t time_start=clock();
d1.merge_sort();
clock_t time_end=clock();
double result = (double)(time_end - time_start) / CLOCKS_PER_SEC;
cout << result;
cout << d1;
*/
}
Just make it a template. You need 2 template parameter, the type of the elements, and the type of the container.
Tipp: if you want to use the class "like a function" define the operator ()
template<class _Item, class _Container> MergeSort
{
...
operator () (_Container & C);
...
}
now you can use C[] and to access elemets for any class that defines operator [], and you can use the size() function with any class that has it. You only have to add them to your dynamic_array class, and you can use MergeSort<int, vector<int> > with vectors, and MergeSort<int, dynamic_array<int> > with dynamic arrays.