from the main.cpp
assert error is here
if(!((CPU1.peek()).isExecuting())) {
cout << "Running: " << CPU1.peek().running << endl;
(CPU1.peek()).execute();
cout << "Running: " << CPU1.peek().running << endl;
assert((CPU1.peek()).isExecuting());
((PCB)CPU1.peek()).setStart(slice);
((PCB)CPU1.peek()).setWait(slice-((PCB)CPU1.peek()).getArrival());
averageWait1 += ((PCB)CPU1.peek()).getWait();
cpu1PCBTotal++;
length1 = ((PCB)CPU1.peek()).getLength();
}
PCB.h
class PCB
{
private:
/**
* this process ID
*/
int pid;
/**
* the nice (priority) value of this process
*/
int priority;
/**
* running status 0=idle 1=running
*/
int running;
public:
/**
* Creates a simulated job with default values for its parameters.
*/
PCB()
{
priority = 19;
running = 0;
arrived = 0;
length = 0;
}
PCB(int id, int pval, int run, int arr, int len)
{
pid = id;
priority = pval;
running = run;
arrived = arr;
length = len;
}
bool isExecuting() const
{
return (running == 1);
}
void execute()
{
running = 1;
}
heap.cpp
template <typename E>
Heap<E>::Heap()
{
// compiler-generated code .. no need to implement this
}
template <typename E>
Heap<E>::~Heap()
{
while(tree.size() > 0)
tree.pop_back();
}
template <typename E>
bool Heap<E>::isEmpty() const
{
return tree.size() == 0;
}
template<typename E>
void Heap<E>::insert(E item)
{
tree.push_back(item);
int place = size()-1;
int parent = (place-1)/2;
while(parent >= 0 && tree[place] > tree[parent]) {
swap(place, parent);
place = parent;
parent = (place-1)/2;
}
}
template<typename E>
E Heap<E>::remove() throw (HeapException)
{
E root = tree[0];
tree[0] = tree[size()-1];
tree.pop_back();
reheapify(0);
return root;
}
template<typename E>
const E& Heap<E>::peek() const throw (HeapException)
{
return tree[0];
}
template<typename E>
int Heap<E>::size()const
{
return tree.size();
}
template<typename E>
void Heap<E>::swap(int place, int parent)
{
E temp = tree[place];
tree[place] = tree[parent];
tree[parent] = temp;
}
template<typename E>
void Heap<E>::reheapify(int root)
{
int l = root*2+1;
int r = root*2+2;
if(l < size()-1) {
if(r < size()-1)
if(tree[root] < tree[r]) {
swap(root, r);
reheapify(r);
}
if(tree[root] < tree[l]) {
swap(root, l);
reheapify(l);
}
}
}
The assertion is failing, and I have no idea why... Please help, thanks
Top is main function, bottom is PCB.h; CPU class is a Heap
Originally typecasted CPU1.peek() because it gave me the error "passing 'const PCB' as 'this' argument discards qualifiers" So I guess I needs help calling CPU1.peek().execute()
Related
As the title says I am trying to implement Set ADT on a Hashtable with independent lists. The thing is I don't know where I'm wrong.
The code I am about to post is taken from a bigger project and I took just the esential parts of it to show you.
SetADT.h:
#pragma once
#pragma once
#include <stdio.h>
#define CAPACITY 10
using namespace std;
template <typename TElement>
class IteratorSet;
template<typename TElement>
class Set {
class Nod {
public:
TElement element;
Nod* next;
};
public:
Set();
void add(TElement element);
int size();
void sterge(TElement element);
bool cauta(TElement element);
friend class IteratorSet<TElement>;
IteratorSet<TElement> iterator() { return IteratorSet<TElement>(this); }
private:
int dimensiune;
typename Set<TElement>::Nod* prim;
int max;
Nod** table;
int hashFunction(TElement element) { return element.hashCode() % max; }
Nod* set;
};
template<typename TElement>
Set<TElement>::Set()
{
max = CAPACITATE;
table = new Nod*[max];
for (int i = 0; i < max; i++)
table[i] = NULL;
}
template <typename TElement>
void Set<TElement>::add(TElement element)
{
int pozitie = hashFunction(element);
Nod* curent = table[pozitie];
while (curent != NULL && !(element == curent->element))
curent = curent->next;
if (curent != NULL)
return;
else
{
Nod* n = new Nod;
n->element = element;
n->next = table[pozitie];
table[pozitie] = n;
}
dimensiune++;
}
template <typename TElement>
int Set<TElement>::size()
{
return dimensiune;
}
template <typename TElement>
void Set<TElement>::sterge(TElement element)
{
int pozitie = hashFunction(element);
Nod* curent = table[pozitie];
if (table[pozitie] == NULL)
return;
if (table[pozitie]->element == element)
{
Nod* deSters = table[pozitie];
table[pozitie] = table[pozitie]->next;
delete deSters;
dimensiune--;
return;
}
Nod* elem = table[pozitie];
while (elem->next != NULL && (elem->next->element) == element)
elem = elem->next;
if (elem->next != NULL)
{
Nod* deSters = elem->next;
elem->next = elem->next->next;
delete deSters;
dimensiune--;
}
}
template <typename TElement>
bool Set<TElement>::cauta(TElement element)
{
int pozitie = hashFunction(element);
Nod* curent = table[pozitie];
while (curent != NULL && !(element == curent->element))
curent = curent->next;
if (curent != NULL)
{
return true;
}
return false;
}
template<typename TElement>
class IteratorSet {
public:
IteratorSet(Set<TElement>* m);
void next();
bool valid();
TElement element();
private:
Set<TElement>* Set;
typename Set<TElement>::Nod* crt;
};
template<typename TElement>
IteratorSet<TElement>::IteratorSet(Set<TElement>* mul) {
Set = mul;
crt = mul->prim;
}
template<typename TElement>
bool IteratorSet<TElement>::valid() {
return crt != NULL;
}
template<typename TElement>
TElement IteratorSet<TElement>::element() {
return crt->element;
}
template<typename TElement>
void IteratorSet<TElement>::next() {
crt = crt->next;
}
=======================================================
domain.h (names of Pizzas)
#include <string>
using namespace std;
class Pizza {
public:
Pizza(string namePizza) : namePizza(namePizza) {}
Pizza() : namePizza("") {}
string getName() const {
return namePizza;
}
int hashCode()
{
int sum = 0;
for (unsigned i = 0; i < str.length(); i++)
sum += str[i];
return sum;
}
bool operator == (Pizza& other) {
return namePizza == other.getName();
}
private:
string namePizza;
string str;
};
====================================================
main.cpp:
#include "SetADT.h"
#include <string>
#include <iostream>
#include "domain.h"
void show(Set<Pizza>* set) {
IteratorSet<string> it = set->iterator();
while (it.valid()) {
cout << "\t" << it.element().getName() << endl;
it.next();
}
}
int main()
{
Set<Pizza> set;
Pizza pizza1{ "diavola" };
Pizza pizza2{ "prosciuto" };
set.add(pizza1);
set.add(pizza2);
show(set);
return 0;
}
When I try to print the objects added to the Set it pops and error and the program stops.
I don't know anywhere else to look to find the problem.
Anyway, if the code sample isn't enough, here the complete project ( has parts of romanian in it )
http://www20.zippyshare.com/v/qKpEcZhr/file.html
The reason might be, for example, prim variable that you use in the iterator, that is initialized to an undefined value. However, code you posted is not compilable, i.e. there are other problems why your code is not working. Did not download your zip file.
Debug Assertion Failed!
Program: ...nts\Visual Studio 2015\Projects\Project 5\Debug\Project 5.exe
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 892
Expression: is_block_type_valid(header->_block_use)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
The program runs and outputs everything correctly, and throws this error. I haven't been able to find any good explanations of what this means or how to go about finding or fixing it. Here is a complete copy of the (incredibly ugly and badly written) code:
#include <iostream>
using namespace std;
/* a class for storing a Binary Tree */
template <class Type>
class BinaryTree {
protected:
Type parentArray[10];
Type childArray[10];
public:
BinaryTree();
BinaryTree(int& k);
~BinaryTree();
BinaryTree(BinaryTree<Type>& bt);
void operator= (BinaryTree<Type>& bt);
friend ostream& operator<< (ostream& s, BinaryTree<Type> bt) {
s << "[ ";
bt.inorder(bt.getRoot());
s << "]" << endl;
return s;
};
int size();
int height();
int getLeft(int k);
int getRight(int k);
void preorder(int k);
void inorder(int k) {
// do I have a left child?
if ((getLeft(k)) != -1) {
// if yes inorder (left child)
inorder(getLeft(k));
};
// output k
cout << k << " ";
// do I have a right child?
if ((getRight(k)) != -1) {
// if yes inorder (right child)
inorder(getRight(k));
};
};
void postorder(int k);
void setRoot(Type& val);
void setParent(Type* child, Type* parent);
void setLeft(Type& val);
void setRight(Type& val);
int getRoot();
};
/* default constructor */
template <class Type>
BinaryTree<Type>::BinaryTree() {
parentArray = new ArrayClass<Type>();
childArray = new ArrayClass<Type>();
};
/* non-empty constructor */
template <class Type>
BinaryTree<Type>::BinaryTree(int& k) {
// parentArray = new Type[k];
// childArray = new Type[k];
};
template <class Type>
BinaryTree<Type>::~BinaryTree() {
delete[] parentArray;
delete[] childArray;
};
template <class Type>
BinaryTree<Type>::BinaryTree(BinaryTree<Type>& bt) {
for (int i = 0; i < bt.size(); i++) {
parentArray[i] = bt.parentArray[i];
childArray[i] = bt.childArray[i];
};
};
template <class Type>
void BinaryTree<Type>::operator= (BinaryTree<Type>& bt) {
};
/* return the size of the tree using the length of the parent array */
template <class Type>
int BinaryTree<Type>::size() {
return (sizeof(parentArray)/sizeof(*parentArray));
};
template <class Type>
int BinaryTree<Type>::height() {
return 5;
};
template <class Type>
int BinaryTree<Type>::getLeft(int k) {
// if the parent array value of the given number is k and
// the child array value indicates it is a left child
for (int i = 0; i < size(); i++) {
if ((parentArray[i] == k) && (childArray[i] == 0)) {
// return that value
return i;
};
};
return -1;
};
template <class Type>
int BinaryTree<Type>::getRight(int k) {
// if the parent array value of the given number is k and
// the child array value indicates it is a right child
for (int i = 0; i < size(); i++) {
if ((parentArray[i] == k) && (childArray[i] == 1)) {
// return that value
return i;
};
};
return -1;
};
template <class Type>
void BinaryTree<Type>::preorder(int k) {
// output k
cout << k << " ";
// do I have a left child?
if ((getLeft(k)) != -1) {
// if yes preorder left child
preorder(getLeft(k));
};
// do I have a right child?
if ((getRight(k)) != -1) {
// if yes preorder right child
preorder(getRight(k));
};
};
template <class Type>
void BinaryTree<Type>::postorder(int k) {
// do I have a left child?
if ((getLeft(k)) != -1) {
// if yes inorder (left child)
inorder(getLeft(k));
};
// do I have a right child?
if ((getRight(k)) != -1) {
// if yes inorder (right child)
inorder(getRight(k));
};
// output k
cout << k << " ";
};
template <class Type>
void BinaryTree<Type>::setRoot(Type& val) {
// if the given value is the root of the tree then set
// its index in the parent and child arrays to -1
parentArray[val] = -1;
childArray[val] = -1;
};
template <class Type>
void BinaryTree<Type>::setParent(Type* child, Type* parent) {
// set a given value as the parent of a given value
parentArray[(*child)] = *parent;
};
template <class Type>
void BinaryTree<Type>::setLeft(Type& val) {
// set a given value in the child array to indicate a left child
childArray[val] = 0;
};
template <class Type>
void BinaryTree<Type>::setRight(Type& val) {
// set a given value in the child array to indicate a right child
childArray[val] = 1;
};
template <class Type>
int BinaryTree<Type>::getRoot() {
// find the root value of the tree
for (int i = 0; i < size(); i++) {
if (parentArray[i] == -1) {
// and return it
return i;
};
};
};
int main() {
int* val1 = new int;
int* val2 = new int;
int* val3 = new int;
int count;
cin >> count;
BinaryTree<int> bt(count);
for (int i = 0; i < count; i++) {
cin >> *val1;
cin >> *val2;
cin >> *val3;
if (i == 0) {
bt.setRoot(*val1);
};
if (*val2 != -1) {
bt.setParent(val2, val1);
bt.setLeft(*val2);
}
if (*val3 != -1) {
bt.setParent(val3, val1);
bt.setRight(*val3);
}
val1 = new int;
val2 = new int;
val3 = new int;
};
cout << bt.size() << endl;
bt.postorder(bt.getRoot());
cout << endl;
bt.preorder(bt.getRoot());
cout << endl;
delete val1;
delete val2;
delete val3;
};
Some of the functions in the BinaryTree class aren't finished yet and just have filler garbage in them for testing.
Your BinaryTree destructor always makes sure to:
delete[] parentArray;
delete[] childArray;
Unfortunately, one of the class's constructors does not new any of these arrays. As such, the destructor ends up attempting to delete a pair of uninitialized garbage pointers.
It's also possible that this class violates the Rule Of The Three, but I have not analyzed this sufficiently.
EDIT: as it's been pointed out in the comments, these are not pointers; so this is wrong anyway, but for other reasons.
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) ?
This is my first pathetic attempt at C++. I did an array based stack in C++ and the destructor is throwing out some memory dump. I can't figure out what went wrong.
#include <stdio.h>
#include <iostream>
#include <exception>
using namespace std;
class FullStackException : public exception {
virtual const char* what() const throw() {
return "Stack is full.";
}
} fsex;
class EmptyStackException : public exception {
virtual const char* what() const throw() {
return "Stack is empty.";
}
} esex;
template <class D>
class ArrayBasedStack {
private:
int t; //t represents top
D *S;
int arrSize;
public:
ArrayBasedStack(int arraySize = 10);
~ArrayBasedStack();
int size(); /*returns the number of elements stored*/
void push(D&); /*inserts an element*/
D pop(); /*removes and returns the last inserted element*/
D top(); /*returns the last inserted element without removing it*/
int isEmpty(); /*indicates whether no elements are stored*/
};
template <class D>
ArrayBasedStack<D>::ArrayBasedStack(int arraySize) {
/* Elements are added from left to right */
S = new D[arraySize];
arrSize = arraySize;
/* t keeps track of the index of the top element */
t = -1;
}
template <class D>
ArrayBasedStack<D>::~ArrayBasedStack() {
if(S != NULL) {
int i = 0;
for(i = 0; i < size(); i++) {
S[i] = NULL;
}
cout << "about to delete S" << endl;
delete[] S;
}
}
template <class D>
int ArrayBasedStack<D>::size() {
return t;
}
template <class D>
void ArrayBasedStack<D>::push(D& data) {
if(t == arrSize) {
throw fsex;
} else {
S[t] = data;
t++;
}
}
template <class D>
D ArrayBasedStack<D>::pop() {
if(isEmpty()) {
throw esex;
}
D element = S[t];
S[t--] = NULL;
return element;
}
/*
* returns true if the stack is empty, false otherwise
*/
template <class D>
int ArrayBasedStack<D>::isEmpty() {
return (t < 0);
}
int main(int argc, char *argv[]) {
char inputs[][10] = {
"str1"
};
char *i = NULL;
ArrayBasedStack<char *> stack;
i = inputs[0];
stack.push(i);
try {
stack.pop();
}
catch(exception& ex) {
cout << "ERR:" << ex.what() << endl;
}
return 0;
}
The problem line is
t = -1;
Should be
t = 0;
because when you add first element, the following code is excecuted
} else {
S[t] = data; // t == -1
t++;
}
The following is the culprit.
template <class D>
void ArrayBasedStack<D>::push(D& data) {
if(t == arrSize) {
throw fsex;
} else {
S[t] = data; // Should be S[++t] = data;
t++; // Comment out this line
}
}
This implemntation assumes that 't' points to the topmost element on the stack rather than to the next available location for push
Note that operator [] and operator ++ have same precedence. Since they associate left-to-right, [] is evaluated before operator ++.
In your implementation, here is the problem. With t being initialized to -1, you are overwriting beyond the array subscript that is at S[-1] which leads to undefined behavior.
At least on my system the problem surfaces while trying to free the memory in destructor of the stack class. This is a classic example of a syptom being visible much after the goof-up has happened
Also would suggest push to take the parameters as D const &
I have problem in implementing a disjoint set ADT in C++ due to the fact that our teacher only explained the union and find operations. I fully understand the concepts of union and find but I am still confused about how to implement them.
Could someone please give me an idea of the implementation and also explain what the interface of this data structure should look like?
You have way too many requirements, we're not here to do your homework for you.
Have a look at http://en.wikipedia.org/wiki/Disjoint-set_data_structure
#include <iostream>
template<typename T>
class Disjoint_sets
{
public:
int FIND(int pos);
bool in_same_set(T data_element_1, T data_element_2);
void UNION_IF_EQUIVALENT(T data_element_1, T data_element_2);
void UNION(T data_element_1, T data_element_2);
Disjoint_sets(bool (*is_equivalent)(T, T));
Disjoint_sets();
Disjoint_sets(T* data_arr, bool (*is_equivalent)(T, T),int size);
void insert(T data_element);
bool is_root(int pos_number);
int get_pos(T data_element);
void partition();
void print_partition();
private:
T* data;
int* parent_pos;
int* number_of_children;
int size;
bool (*isequivalent)(T D1, T D2);
};
template<typename T>
Disjoint_sets<T>::Disjoint_sets()
{
data = NULL;
parent_pos = NULL;
number_of_children = NULL;
size = 0;
isequivalent = NULL;
}
template<typename T>
Disjoint_sets<T>::Disjoint_sets(bool (*is_equivalent)(T, T))
{
isequivalent = is_equivalent;
data = NULL;
parent_pos = NULL;
number_of_children = NULL;
size = 0;
}
template<typename T>
Disjoint_sets<T>::Disjoint_sets(T* data_arr, bool (*is_equivalent)(T, T), int size)
{
data = new T[size];
parent_pos = new int[size];
number_of_children = new int[size];
this->size = size;
isequivalent = is_equivalent;
for (int i = 0; i < size; i++)
{
data[i] = data_arr[i];
parent_pos[i] = -1;
number_of_children[i] = 0;
}
}
template<typename T>
bool Disjoint_sets<T>::is_root(int pos)
{
if (pos<0 && pos>size - 1)
{
std::cout << "Error, invalid pos supplied to is_root\n";
return false;
}
if (parent_pos[pos] == -1)
{
return true;
}
else
{
return false;
}
}
template <typename T>
int Disjoint_sets<T>::FIND(int pos)
{
while (!is_root(pos))
{
pos = parent_pos[pos];
}
return pos;
}
template<typename T>
bool Disjoint_sets<T>::in_same_set(T data_element_1, T data_element_2)
{
return FIND(get_pos(data_element_1)) == FIND(get_pos(data_element_2));
}
template<typename T>
int Disjoint_sets<T>::get_pos(T data_element)
{
for (int i = 0; i < size; i++)
{
if (data[i] == data_element)
{
return i;
}
}
std::cout << "Could not find element\n";
return -1;
}
template <typename T>
void Disjoint_sets<T>::UNION(T data_element_1, T data_element_2)
{
int data_parent_1_pos = FIND(get_pos(data_element_1));
int data_parent_2_pos = FIND(get_pos(data_element_2));
if ( data_parent_1_pos==data_parent_2_pos )
{
return;
}
if (number_of_children[data_parent_1_pos] >= number_of_children[data_parent_2_pos])
{
parent_pos[data_parent_2_pos] = data_parent_1_pos;
}
else
{
parent_pos[data_parent_1_pos] = data_parent_2_pos;
}
}
template <typename T>
void Disjoint_sets<T>::UNION_IF_EQUIVALENT(T data_element_1, T data_element_2)
{
if (FIND(get_pos(data_element_1)) == FIND(get_pos(data_element_2)))
{
return;
}
if (isequivalent(data_element_1, data_element_2))
{
UNION(data_element_1, data_element_2);
}
}
template<typename T>
void Disjoint_sets<T>::partition()
{
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
UNION_IF_EQUIVALENT(data[i], data[j]);
}
}
}
template <typename T>
void Disjoint_sets<T>::print_partition()
{
for (int i = 0; i < size; i++)
{
if (is_root(i))
{
for (int j = 0; j < size; j++)
{
if (FIND(j) == i)
{
std::cout << data[j] << " ";
}
}
}
std::cout << "\n";
}
}
template <typename T>
bool lol(int a, int b)
{
return a * a == b * b;
}
int main()
{
int arr[6] = { -1,1,2,3,-3,4 };
Disjoint_sets<int> d(arr,lol<int>, 6);
d.partition();
d.print_partition();
}