123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- #ifndef __TREE_H
- #define __TREE_H
- #include <forward_list>
- // Tree is both a linked list and a binary tree.
- // A linked list is easy to loop through.
- // A binary tree is fast to search through.
- template <typename T>
- class TreeNode
- {
- public:
- T *Item;
- TreeNode<T> *Smaller;
- TreeNode<T> *Bigger;
- TreeNode()
- {
- Item = nullptr;
- Smaller = nullptr;
- Bigger = nullptr;
- }
- TreeNode(T *item)
- {
- Item = item;
- Smaller = nullptr;
- Bigger = nullptr;
- }
- ~TreeNode()
- {
- if (Item != nullptr) {
- delete Item;
- Item = nullptr;
- }
- if (Smaller != nullptr) {
- delete Smaller;
- Smaller = nullptr;
- }
- if (Bigger != nullptr) {
- delete Bigger;
- Bigger = nullptr;
- }
- }
- };
- template <typename T>
- class Tree
- {
- public:
- TreeNode<T> *SortedList; // This is a binary tree.
- std::forward_list<T*> List; // All the items in SortedList are also in List.
-
- void Clear()
- {
- while (!List.empty()) {
- List.pop_front(); // The item is not deleted because it's also being stored in the SortedList tree.
- }
- if (SortedList != nullptr) {
- delete SortedList;
- SortedList = nullptr;
- }
- }
-
- // Find a node or the next place it goes. Returns found status in found.
- TreeNode<T> *Find(T *item,int &found,int (*compareFunction)(T*,T*)) const
- {
- // If the node was found then found = 0 and the node is returned.
- // If the node was not found then found !=0 and the insert point is returned.
- // If found < 0 then add to ->Bigger.
- // If found > 0 then add to ->Smaller.
- // If the list is empty then found = 0 and nullptr is returned.
- // If found = 0 and nullptr is returned then the node was not found.
- TreeNode<T> *loop;
- TreeNode<T> *next;
- int compare;
-
- compare = 0;
- loop = SortedList;
- if (SortedList != nullptr) {
- while (true) {
- compare = compareFunction(loop->Item,item);
- if (compare < 0) {
- next = loop->Bigger;
- if (next == nullptr) {
- break;
- }
- loop = next;
- continue;
- }
- if (compare > 0) {
- next = loop->Smaller;
- if (next == nullptr) {
- break;
- }
- loop = next;
- continue;
- }
- break;
- }
- }
- found = compare;
- return loop;
- }
-
- // Returns all items in this tree that aren't in the other tree.
- // Assumes that the calling function has logic in place to not search empty lists.
- void Subtract(const Tree<T> &other,std::forward_list<T*> &difference,int (*compareFunction)(T*,T*))
- {
- int found;
- TreeNode<T> *search;
- for (auto loop = List.begin(); loop != List.end();++loop) {
- search = other.Find(*loop,found,compareFunction);
- if ((found != 0) && (search != nullptr)) {
- difference.push_front(*loop);
- }
- }
- }
- // Adds an item to this tree. Returns true if successful.
- // Sets *item to nullptr if the item is moved to the tree.
- bool Add(T **item,int (*compareFunction)(T*,T*)) {
- int found;
- TreeNode<T> *search;
- if ((item == nullptr) || (*item == nullptr)) {
- return false;
- }
- if (SortedList == nullptr) {
- SortedList = new TreeNode<T>(*item);
- if (SortedList == nullptr) {
- throw "Out of memory in Tree.Add";
- }
- List.push_front(*item);
- *item = nullptr;
- return true;
- }
- search = Find(*item,found,compareFunction);
- if (found < 0) {
- search->Bigger = new TreeNode<T>(*item);
- if (search->Bigger == nullptr) {
- throw "Out of memory in Tree.Add";
- }
- List.push_front(*item);
- *item = nullptr;
- }
- if (found > 0) {
- search->Smaller = new TreeNode<T>(*item);
- if (search->Smaller == nullptr) {
- throw "Out of memory in Tree.Add";
- }
- List.push_front(*item);
- *item = nullptr;
- }
- return true;
- }
- Tree()
- {
- SortedList = nullptr;
- }
- ~Tree()
- {
- Clear();
- }
- };
- #endif
|