-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
show an element by name or number from periodic table.
- Loading branch information
1 parent
0d03d75
commit 40d13a2
Showing
4 changed files
with
400 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
// AVL Tree Class | ||
#ifndef AVLTREE | ||
#define AVLTREE | ||
|
||
#include <cmath> | ||
using namespace std; | ||
|
||
template <class T> | ||
class AVLNode { | ||
public: | ||
T data; | ||
AVLNode<T>* left; | ||
AVLNode<T>* right; | ||
int height; | ||
|
||
AVLNode(T value) : data(value), left(nullptr), right(nullptr), height(1) {} | ||
}; | ||
|
||
|
||
template <class T> | ||
class AVLTree { | ||
private: | ||
AVLNode<T>* root; | ||
|
||
// Helper functions | ||
int height(AVLNode<T>* node); | ||
int balanceFactor(AVLNode<T>* node); // Corrected name | ||
void updateHeight(AVLNode<T>* node); | ||
AVLNode<T>* rotateRight(AVLNode<T>* node); | ||
AVLNode<T>* rotateLeft(AVLNode<T>* node); | ||
AVLNode<T>* balance(AVLNode<T>* node); | ||
AVLNode<T>* insert(AVLNode<T>* node, T value); | ||
AVLNode<T>* minValueNode(AVLNode<T>* node); | ||
AVLNode<T>* deleteNode(AVLNode<T>* root, T value); | ||
|
||
public: | ||
AVLTree() : root(nullptr) {} | ||
void insert(T value); | ||
void remove(T value); | ||
T search(int key); | ||
AVLNode<T>* getRoot() const { return root; } | ||
}; | ||
|
||
template <class T> | ||
int AVLTree<T>::height(AVLNode<T>* node) { | ||
if (node == nullptr) | ||
return 0; | ||
return node->height; | ||
} | ||
|
||
template <class T> | ||
int AVLTree<T>::balanceFactor(AVLNode<T>* node) { // Corrected name | ||
if (node == nullptr) | ||
return 0; | ||
return height(node->left) - height(node->right); | ||
} | ||
|
||
template <class T> | ||
void AVLTree<T>::updateHeight(AVLNode<T>* node) { | ||
if (node != nullptr) | ||
node->height = 1 + max(height(node->left), height(node->right)); | ||
} | ||
|
||
template <class T> | ||
AVLNode<T>* AVLTree<T>::rotateRight(AVLNode<T>* node) { | ||
AVLNode<T>* newRoot = node->left; | ||
node->left = newRoot->right; | ||
newRoot->right = node; | ||
updateHeight(node); | ||
updateHeight(newRoot); | ||
return newRoot; | ||
} | ||
|
||
template <class T> | ||
AVLNode<T>* AVLTree<T>::rotateLeft(AVLNode<T>* node) { | ||
AVLNode<T>* newRoot = node->right; | ||
node->right = newRoot->left; | ||
newRoot->left = node; | ||
updateHeight(node); | ||
updateHeight(newRoot); | ||
return newRoot; | ||
} | ||
|
||
template <class T> | ||
AVLNode<T>* AVLTree<T>::balance(AVLNode<T>* node) { | ||
updateHeight(node); | ||
int bfValue = balanceFactor(node); // Corrected to use balanceFactor instead of bf | ||
if (bfValue > 1) { | ||
if (balanceFactor(node->left) < 0) { | ||
node->left = rotateLeft(node->left); | ||
} | ||
return rotateRight(node); | ||
} | ||
if (bfValue < -1) { | ||
if (balanceFactor(node->right) > 0) { | ||
node->right = rotateRight(node->right); | ||
} | ||
return rotateLeft(node); | ||
} | ||
return node; | ||
} | ||
|
||
|
||
template <class T> | ||
AVLNode<T>* AVLTree<T>::insert(AVLNode<T>* node, T value) { | ||
if (node == nullptr) | ||
return new AVLNode<T>(value); | ||
if (value < node->data) | ||
node->left = insert(node->left, value); | ||
else | ||
node->right = insert(node->right, value); | ||
return balance(node); | ||
} | ||
|
||
template <class T> | ||
AVLNode<T>* AVLTree<T>::minValueNode(AVLNode<T>* node) { | ||
AVLNode<T>* current = node; | ||
while (current->left != nullptr) | ||
current = current->left; | ||
return current; | ||
} | ||
|
||
template <class T> | ||
AVLNode<T>* AVLTree<T>::deleteNode(AVLNode<T>* root, T value) { | ||
if (root == nullptr) | ||
return root; | ||
if (value < root->data) | ||
root->left = deleteNode(root->left, value); | ||
else if (value > root->data) | ||
root->right = deleteNode(root->right, value); | ||
else { | ||
if (root->left == nullptr || root->right == nullptr) { | ||
AVLNode<T>* temp = root->left ? root->left : root->right; | ||
if (temp == nullptr) { | ||
temp = root; | ||
root = nullptr; | ||
} else | ||
*root = *temp; | ||
delete temp; | ||
} else { | ||
AVLNode<T>* temp = minValueNode(root->right); | ||
root->data = temp->data; | ||
root->right = deleteNode(root->right, temp->data); | ||
} | ||
} | ||
if (root == nullptr) | ||
return root; | ||
return balance(root); | ||
} | ||
|
||
template <class T> | ||
void AVLTree<T>::insert(T value) { | ||
root = insert(root, value); | ||
} | ||
|
||
template <class T> | ||
void AVLTree<T>::remove(T value) { | ||
root = deleteNode(root, value); | ||
} | ||
|
||
template <class T> | ||
T AVLTree<T>::search(int key) { | ||
AVLNode<T>* current = root; | ||
while (current != nullptr) { | ||
if (current->data.atomicNumber == key) | ||
return current->data; | ||
else if (key < current->data.atomicNumber) | ||
current = current->left; | ||
else | ||
current = current->right; | ||
} | ||
throw "Element not found"; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#ifndef ELEMENT_LOOKUP_H | ||
#define ELEMENT_LOOKUP_H | ||
|
||
#include "AVLTree.h" | ||
#include <fstream> | ||
#include <iostream> | ||
#include <sstream> | ||
#include <string> | ||
#include <functional> | ||
using namespace std; | ||
|
||
class ElementInfo { | ||
public: | ||
string name; | ||
string symbol; | ||
int atomicNumber; | ||
double atomicWeight; | ||
|
||
ElementInfo(string n, string s, int num, double weight) : name(n), symbol(s), atomicNumber(num), atomicWeight(weight) {} | ||
|
||
// Define operator< to compare ElementInfo objects by atomicNumber | ||
bool operator<(const ElementInfo& other) const { | ||
return atomicNumber < other.atomicNumber; | ||
} | ||
}; | ||
|
||
// Element Lookup Class | ||
class ElementLookup { | ||
private: | ||
AVLTree<ElementInfo> elements; | ||
|
||
public: | ||
ElementLookup(string filename); | ||
void lookupByNumber(int atomicNumber); | ||
void lookupByName(string name); | ||
}; | ||
|
||
ElementLookup::ElementLookup(string filename) { | ||
ifstream file(filename); | ||
if (!file.is_open()) { | ||
cerr << "Error opening file " << filename << endl; | ||
return; | ||
} | ||
|
||
string line; | ||
getline(file, line); // skip header line | ||
while (getline(file, line)) { | ||
stringstream ss(line); | ||
string name, symbol; | ||
int atomicNumber; | ||
double atomicWeight; | ||
|
||
getline(ss, name, ','); | ||
getline(ss, symbol, ','); | ||
ss >> atomicNumber; | ||
ss.ignore(); // ignore comma | ||
ss >> atomicWeight; | ||
|
||
ElementInfo element(name, symbol, atomicNumber, atomicWeight); | ||
elements.insert(element); | ||
} | ||
file.close(); | ||
} | ||
|
||
void ElementLookup::lookupByNumber(int atomicNumber) { | ||
try { | ||
ElementInfo element = elements.search(atomicNumber); | ||
cout << "Atomic Number: " << element.atomicNumber << ", Name: " << element.name << ", Symbol: " << element.symbol | ||
<< ", Atomic Weight: " << element.atomicWeight << endl; | ||
} catch (...) { | ||
cerr << "Element not found" << endl; | ||
} | ||
} | ||
|
||
void ElementLookup::lookupByName(string name) { | ||
// Perform an in-order traversal of the AVL tree | ||
function<void(AVLNode<ElementInfo>*)> inOrderTraversal = [&](AVLNode<ElementInfo>* node) { | ||
if (node == nullptr) | ||
return; | ||
inOrderTraversal(node->left); | ||
if (node->data.name == name) { | ||
cout << "Atomic Number: " << node->data.atomicNumber << ", Name: " << node->data.name << ", Symbol: " << node->data.symbol | ||
<< ", Atomic Weight: " << node->data.atomicWeight << endl; | ||
return; | ||
} | ||
inOrderTraversal(node->right); | ||
}; | ||
|
||
// Start the traversal from the root of the AVL tree | ||
inOrderTraversal(elements.getRoot()); | ||
} | ||
|
||
#endif // ELEMENT_LOOKUP_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#include <iostream> | ||
#include "ElementLookup.h" | ||
|
||
using namespace std; | ||
int main() { | ||
ElementLookup lookup("periodicTable.csv"); | ||
|
||
int choice; | ||
|
||
cout << "Lookup Element By\n1. Number\n2. Name\nPlease Select input: "; | ||
cin >> choice; | ||
|
||
if (choice == 1) { | ||
int atomicNumber; | ||
cout << "Please enter the Atomic Number: "; | ||
cin >> atomicNumber; | ||
lookup.lookupByNumber(atomicNumber); | ||
} else if (choice == 2) { | ||
string name; | ||
cout << "Please enter the Element Name: "; | ||
cin >> name; | ||
lookup.lookupByName(name); | ||
} else { | ||
cout << "Invalid choice" << endl; | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.