mirror of
https://github.com/tiennm99/HCMUT.git
synced 2026-09-03 20:21:28 +00:00
Update Assignment
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
/* Copyright (C) 2018
|
||||
* Course: CO2003
|
||||
* Author: Rang Nguyen
|
||||
* Ho Chi Minh City University of Technology
|
||||
*/
|
||||
|
||||
#include "Node.h"
|
||||
|
||||
Node::Node(int capacity)
|
||||
{
|
||||
maxElements = capacity;
|
||||
elements = new int[maxElements];
|
||||
numElements = 0;
|
||||
prev = next = nullptr;
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
if (elements != nullptr)
|
||||
delete[] elements;
|
||||
}
|
||||
|
||||
int Node::getHalfNodeSize()
|
||||
{
|
||||
return int(ceil(maxElements / 2.0));
|
||||
}
|
||||
|
||||
bool Node::isUnderHalfFull()
|
||||
{
|
||||
return numElements < getHalfNodeSize();
|
||||
}
|
||||
|
||||
bool Node::isFull()
|
||||
{
|
||||
return numElements >= maxElements;
|
||||
}
|
||||
|
||||
bool Node::isOverflow()
|
||||
{
|
||||
return numElements > maxElements;
|
||||
}
|
||||
|
||||
bool Node::isEmpty()
|
||||
{
|
||||
return numElements == 0;
|
||||
}
|
||||
|
||||
void Node::add(int val)
|
||||
{
|
||||
if (isFull())
|
||||
throw "NodeOverflowExeception";
|
||||
else {
|
||||
elements[numElements] = val;
|
||||
numElements++;
|
||||
}
|
||||
}
|
||||
|
||||
void Node::insertAt(int pos, int val)
|
||||
{
|
||||
if (isFull()) throw "NodeOverflowExeception";
|
||||
else if (pos < 0 || pos > numElements) throw "IndexOutOfBoundsException";
|
||||
else {
|
||||
memmove(elements + pos + 1, elements + pos, (numElements - pos) * sizeof(int));
|
||||
elements[pos] = val;
|
||||
numElements++;
|
||||
}
|
||||
}
|
||||
|
||||
void Node::removeAt(int pos)
|
||||
{
|
||||
if (pos < 0 || pos >= numElements) throw "IndexOutOfBoundsException";
|
||||
else {
|
||||
memmove(elements + pos, elements + pos + 1, (numElements - pos - 1) * sizeof(int));
|
||||
numElements--;
|
||||
}
|
||||
}
|
||||
|
||||
void Node::reverse()
|
||||
{
|
||||
for (int i = 0; i < numElements / 2; i++)
|
||||
std::swap(elements[i], elements[numElements - 1 - i]);
|
||||
}
|
||||
|
||||
void Node::print()
|
||||
{
|
||||
for (int i = 0; i < numElements; i++)
|
||||
printf("%d ", elements[i]);
|
||||
}
|
||||
|
||||
void Node::printDetail()
|
||||
{
|
||||
printf("size: %d ", numElements);
|
||||
printf("| prev(%d) |", prev);
|
||||
for (int i = 0; i < numElements; i++)
|
||||
printf(" %d |", elements[i]);
|
||||
for (int i = numElements; i < maxElements; i++)
|
||||
printf(" X |");
|
||||
printf(" next(%d) |\n", next);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Copyright (C) 2018
|
||||
* Course: CO2003
|
||||
* Author: Rang Nguyen
|
||||
* Ho Chi Minh City University of Technology
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
// Unrolled Linked List Node
|
||||
|
||||
class Node
|
||||
{
|
||||
private:
|
||||
int maxElements;
|
||||
public:
|
||||
int numElements; // number of elements in this node, up to maxElements
|
||||
int *elements; // an array of numElements elements,
|
||||
Node *next; // reference to the next node in the list
|
||||
Node *prev; // reference to the previous node in the list
|
||||
|
||||
Node(int capacity = 5);
|
||||
~Node();
|
||||
int getHalfNodeSize();
|
||||
bool isUnderHalfFull();
|
||||
bool isFull();
|
||||
bool isOverflow();
|
||||
bool isEmpty();
|
||||
void add(int val); // append val element to the end of the node
|
||||
void insertAt(int pos, int val); // insert val to position pos of the node
|
||||
void removeAt(int pos); // remove the position pos from the node
|
||||
void reverse(); // reverse the content of the node
|
||||
void print(); // print the content of the node
|
||||
void printDetail(); // print the detail content of the node
|
||||
};
|
||||
@@ -0,0 +1,223 @@
|
||||
#include "UnrolledLinkedList.h"
|
||||
|
||||
void UnrolledLinkedList::add(int val)
|
||||
{
|
||||
if (tail == nullptr) {
|
||||
tail = new Node(nodeSize);
|
||||
++numOfNodes;
|
||||
head = tail;
|
||||
} else if (tail->isFull()) {
|
||||
Node *newNode = new Node(nodeSize);
|
||||
++numOfNodes;
|
||||
newNode->prev = tail;
|
||||
tail->next = newNode;
|
||||
int hsize = getHalfNodeSize();
|
||||
memmove(newNode->elements, tail->elements + hsize, (nodeSize - hsize) * sizeof(int));
|
||||
tail->numElements = hsize;
|
||||
newNode->numElements = nodeSize - hsize;
|
||||
tail = newNode;
|
||||
}
|
||||
tail->add(val);
|
||||
++size;
|
||||
}
|
||||
|
||||
int UnrolledLinkedList::getAt(int pos)
|
||||
{
|
||||
if (pos < 0 || pos >= size)
|
||||
throw "IndexOutOfBoundsException";
|
||||
int cnt = 0;
|
||||
Node *temp = head;
|
||||
while (cnt + temp->numElements <= pos) {
|
||||
cnt += temp->numElements;
|
||||
temp = temp->next;
|
||||
}
|
||||
return temp->elements[pos - cnt];
|
||||
}
|
||||
|
||||
void UnrolledLinkedList::setAt(int pos, int val)
|
||||
{
|
||||
if (pos < 0 || pos >= size)
|
||||
throw "IndexOutOfBoundsException";
|
||||
int cnt = 0;
|
||||
Node *temp = head;
|
||||
while (cnt + temp->numElements <= pos) {
|
||||
cnt += temp->numElements;
|
||||
temp = temp->next;
|
||||
}
|
||||
temp->elements[pos - cnt] = val;
|
||||
}
|
||||
|
||||
void UnrolledLinkedList::insertAt(int pos, int val)
|
||||
{
|
||||
if (pos < 0 || pos > size)
|
||||
throw "IndexOutOfBoundsException";
|
||||
if (pos == size) {
|
||||
add(val);
|
||||
return;
|
||||
}
|
||||
int cnt = 0;
|
||||
Node *temp = head;
|
||||
while (cnt + temp->numElements <= pos) {
|
||||
cnt += temp->numElements;
|
||||
temp = temp->next;
|
||||
}
|
||||
if (temp->isFull()) {
|
||||
Node *newNode = new Node(nodeSize);
|
||||
++numOfNodes;
|
||||
if (temp == tail)
|
||||
tail = newNode;
|
||||
else
|
||||
temp->next->prev = newNode;
|
||||
newNode->prev = temp;
|
||||
newNode->next = temp->next;
|
||||
temp->next = newNode;
|
||||
int hsize = getHalfNodeSize();
|
||||
if (pos - cnt >= hsize) {
|
||||
memmove(newNode->elements, temp->elements + hsize, (nodeSize - hsize) * sizeof(int));
|
||||
temp->numElements = hsize;
|
||||
newNode->numElements = nodeSize - hsize;
|
||||
newNode->insertAt(pos - cnt - hsize, val);
|
||||
} else {
|
||||
memmove(newNode->elements, temp->elements + hsize - 1, (nodeSize - hsize + 1) * sizeof(int));
|
||||
temp->numElements = hsize - 1;
|
||||
newNode->numElements = nodeSize - hsize + 1;
|
||||
temp->insertAt(pos - cnt, val);
|
||||
}
|
||||
} else {
|
||||
temp->insertAt(pos - cnt, val);
|
||||
}
|
||||
++size;
|
||||
}
|
||||
|
||||
void UnrolledLinkedList::deleteAt(int pos)
|
||||
{
|
||||
if (pos < 0 || pos >= size)
|
||||
throw "IndexOutOfBoundsException";
|
||||
int cnt = 0;
|
||||
Node *temp = head;
|
||||
while (cnt + temp->numElements <= pos) {
|
||||
cnt += temp->numElements;
|
||||
temp = temp->next;
|
||||
}
|
||||
temp->removeAt(pos - cnt);
|
||||
--size;
|
||||
if (size == 0) {
|
||||
delete head;
|
||||
--numOfNodes;
|
||||
head = nullptr;
|
||||
tail = nullptr;
|
||||
return;
|
||||
}
|
||||
if (temp->isUnderHalfFull()) {
|
||||
int hsize = getHalfNodeSize();
|
||||
if (temp == head) {
|
||||
Node *next = temp->next;
|
||||
if (next != nullptr) {
|
||||
if (next->numElements <= hsize) {
|
||||
memmove(temp->elements + temp->numElements, next->elements, next->numElements * sizeof(int));
|
||||
temp->numElements += next->numElements;
|
||||
temp->next = next->next;
|
||||
if (next == tail)
|
||||
tail = temp;
|
||||
else
|
||||
temp->next->prev = temp;
|
||||
delete next;
|
||||
--numOfNodes;
|
||||
} else {
|
||||
temp->add(next->elements[0]);
|
||||
next->removeAt(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Node *prev = temp->prev;
|
||||
if (prev->numElements <= hsize) {
|
||||
memmove(prev->elements + prev->numElements, temp->elements, temp->numElements * sizeof(int));
|
||||
prev->numElements += temp->numElements;
|
||||
prev->next = temp->next;
|
||||
if (temp == tail)
|
||||
tail = prev;
|
||||
else
|
||||
prev->next->prev = prev;
|
||||
delete temp;
|
||||
--numOfNodes;
|
||||
} else {
|
||||
temp->insertAt(0, prev->elements[prev->numElements - 1]);
|
||||
prev->removeAt(prev->numElements - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int UnrolledLinkedList::firstIndexOf(int val)
|
||||
{
|
||||
int cnt = 0;
|
||||
Node *temp = head;
|
||||
while (temp != nullptr) {
|
||||
for (int i = 0; i < temp->numElements; ++i) {
|
||||
if (temp->elements[i] == val)
|
||||
return cnt + i;
|
||||
}
|
||||
cnt += temp->numElements;
|
||||
temp = temp->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int UnrolledLinkedList::lastIndexOf(int val)
|
||||
{
|
||||
int cnt = size;
|
||||
Node *temp = tail;
|
||||
while (temp != nullptr) {
|
||||
cnt -= temp->numElements;
|
||||
for (int i = temp->numElements - 1; i >= 0; --i) {
|
||||
if (temp->elements[i] == val)
|
||||
return cnt + i;
|
||||
}
|
||||
temp = temp->prev;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool UnrolledLinkedList::contains(int val)
|
||||
{
|
||||
Node *temp = head;
|
||||
while (temp != nullptr) {
|
||||
for (int i = 0; i < temp->numElements; ++i) {
|
||||
if (temp->elements[i] == val)
|
||||
return true;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UnrolledLinkedList::reverse()
|
||||
{
|
||||
if (size < 2)
|
||||
return;
|
||||
Node *temp = head;
|
||||
while (temp != nullptr) {
|
||||
Node *prev = temp->prev;
|
||||
Node *next = temp->next;
|
||||
temp->reverse();
|
||||
temp->next = prev;
|
||||
temp->prev = next;
|
||||
temp = next;
|
||||
}
|
||||
temp = head;
|
||||
head = tail;
|
||||
tail = temp;
|
||||
}
|
||||
|
||||
int *UnrolledLinkedList::toArray()
|
||||
{
|
||||
int *arr = new int[size];
|
||||
int cnt = 0;
|
||||
Node *temp = head;
|
||||
while (temp != nullptr) {
|
||||
memcpy(arr + cnt, temp->elements, temp->numElements * sizeof(int));
|
||||
cnt += temp->numElements;
|
||||
temp = temp->next;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/* Copyright (C) 2018
|
||||
* Course: CO2003
|
||||
* Author: Rang Nguyen
|
||||
* Ho Chi Minh City University of Technology
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
|
||||
class UnrolledLinkedList
|
||||
{
|
||||
private:
|
||||
Node *head;
|
||||
Node *tail;
|
||||
int size;
|
||||
int numOfNodes;
|
||||
int nodeSize;
|
||||
public:
|
||||
|
||||
// Your tasks: complete the implementation of the below methods in UnrolledLinkedList.h
|
||||
void add(int val);
|
||||
bool contains(int val);
|
||||
int getAt(int pos);
|
||||
void setAt(int pos, int val);
|
||||
int firstIndexOf(int val);
|
||||
int lastIndexOf(int val);
|
||||
void insertAt(int pos, int val);
|
||||
void deleteAt(int pos);
|
||||
void reverse();
|
||||
int *toArray();
|
||||
|
||||
UnrolledLinkedList(int capacity)
|
||||
{
|
||||
nodeSize = capacity;
|
||||
head = tail = nullptr;
|
||||
size = numOfNodes = 0;
|
||||
}
|
||||
|
||||
~UnrolledLinkedList()
|
||||
{
|
||||
Node *p;
|
||||
while (p = head) {
|
||||
head = head->next;
|
||||
delete p;
|
||||
}
|
||||
size = numOfNodes = 0;
|
||||
head = tail = nullptr;
|
||||
}
|
||||
|
||||
int getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
int getHalfNodeSize()
|
||||
{
|
||||
return int (ceil(nodeSize / 2.0));
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
printf("=================METADATA================\n");
|
||||
printf("Size = %d, nodeSize = %d, halfNodeSize = %d\n", size, nodeSize, getHalfNodeSize());
|
||||
printf("-----------------CONTENTS----------------\n");
|
||||
Node *p = head;
|
||||
if (p == nullptr) {
|
||||
printf("NULL\n");
|
||||
return;
|
||||
}
|
||||
while (p != nullptr) {
|
||||
// check whether your implementation satisfied the requirements
|
||||
if ((p->isUnderHalfFull() && size >= getHalfNodeSize()) ||
|
||||
p->isOverflow()) {
|
||||
throw "Something wrong with your implementation";
|
||||
}
|
||||
p->print();
|
||||
p = p->next;
|
||||
}
|
||||
printf("\n-------------------END-------------------\n");
|
||||
}
|
||||
|
||||
void printDetail()
|
||||
{
|
||||
printf("=================METADATA================\n");
|
||||
printf("Size = %d, numOfNodes = %d, nodeSize = %d\n", size, numOfNodes, nodeSize);
|
||||
printf("-----------------CONTENTS----------------\n");
|
||||
Node *p = head;
|
||||
if (p == nullptr) printf("NULL\n");
|
||||
while (p != nullptr) {
|
||||
p->printDetail();
|
||||
p = p->next;
|
||||
}
|
||||
printf("-------------------END-------------------\n");
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
/* Copyright (C) 2018
|
||||
* Course: CO2003
|
||||
* Author: Rang Nguyen
|
||||
* Ho Chi Minh City University of Technology
|
||||
*/
|
||||
|
||||
#include "UnrolledLinkedList.h"
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
int main()
|
||||
{
|
||||
UnrolledLinkedList *list = nullptr;
|
||||
ifstream ifs;
|
||||
ifs.open("input.txt");
|
||||
char command;
|
||||
int pos, val;
|
||||
try {
|
||||
while (ifs >> command) {
|
||||
switch (command) {
|
||||
case 'u': // create an object of UnrolledLinkedList
|
||||
ifs >> val;
|
||||
if (list != nullptr) delete list;
|
||||
list = new UnrolledLinkedList(val);
|
||||
break;
|
||||
case 'a': // append an element the the end of the list
|
||||
ifs >> val;
|
||||
list->add(val);
|
||||
break;
|
||||
case 'c': // check if an element is in the list or not
|
||||
ifs >> val;
|
||||
printf("The list contains %d: %d\n", val, list->contains(val));
|
||||
break;
|
||||
case 'd': // delete an element at pos position in the list
|
||||
ifs >> pos;
|
||||
list->deleteAt(pos);
|
||||
break;
|
||||
case 'f': // return the index of the first occurence of a specific element in the list
|
||||
ifs >> val;
|
||||
printf("First occurrence of %d is at %d\n", val, list->firstIndexOf(val));
|
||||
break;
|
||||
case 'g': // returns the element at the specified position in this list.
|
||||
ifs >> pos;
|
||||
printf("The element at position %d is %d\n", pos, list->getAt(pos));
|
||||
break;
|
||||
case 'i': // insert a new element to pos position in the list
|
||||
ifs >> pos >> val;
|
||||
list->insertAt(pos, val);
|
||||
break;
|
||||
case 'l': // return the index of the last occurence of a specific element in the list
|
||||
ifs >> val;
|
||||
printf("Last occurrence of %d is at %d\n", val, list->lastIndexOf(val));
|
||||
break;
|
||||
case 'p': // print the content of the list
|
||||
list->print();
|
||||
break;
|
||||
case 'r': // reverse the list
|
||||
list->reverse();
|
||||
break;
|
||||
case 's': // replaces the element at the specified position in this list with the specified element.
|
||||
ifs >> pos >> val;
|
||||
list->setAt(pos, val);
|
||||
break;
|
||||
case 't': { //returns a pointer to an array containing all of the elements in this list in proper sequence(from first to last element).
|
||||
int *arr = list->toArray();
|
||||
int n = list->getSize();
|
||||
printf("The list after converted to array:\n");
|
||||
if (n > 0) {
|
||||
for (int i = 0; i < n; i++)
|
||||
printf("%d ", arr[i]);
|
||||
printf("\n");
|
||||
delete[] arr;
|
||||
} else {
|
||||
printf("NULL\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w': // print the detail content of the list
|
||||
list->printDetail();
|
||||
break;
|
||||
default:
|
||||
throw "Wrong input format!";
|
||||
}
|
||||
}
|
||||
} catch (char const *s) {
|
||||
printf("An exception occurred. Exception type: %s\n", s);
|
||||
}
|
||||
|
||||
if (list != nullptr) delete list;
|
||||
ifs.close();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2018
|
||||
* Course: CO2003
|
||||
* Author: Rang Nguyen
|
||||
* Ho Chi Minh City University of Technology
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
class AVLNode {
|
||||
public:
|
||||
int key; // data
|
||||
AVLNode* left; // left child
|
||||
AVLNode* right; // right child
|
||||
int balance; // balance factor
|
||||
|
||||
AVLNode(int key) {
|
||||
this->key = key;
|
||||
left = right = NULL;
|
||||
balance = 0;
|
||||
}
|
||||
AVLNode(int key, int balance) {
|
||||
this->key = key;
|
||||
this->balance = balance;
|
||||
left = right = NULL;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,273 @@
|
||||
//use "balance" varialbe as "height"
|
||||
|
||||
#include "TreeSet.h"
|
||||
|
||||
static bool isSuccess;
|
||||
|
||||
TreeSet::TreeSet()
|
||||
{
|
||||
root = nullptr;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
TreeSet::~TreeSet()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void TreeSet::clearRec(AVLNode *root)
|
||||
{
|
||||
if (root != nullptr) {
|
||||
clearRec(root->left);
|
||||
clearRec(root->right);
|
||||
delete root;
|
||||
}
|
||||
}
|
||||
|
||||
void TreeSet::clear()
|
||||
{
|
||||
clearRec(root);
|
||||
root = nullptr;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
int TreeSet::add(int val)
|
||||
{
|
||||
isSuccess = false;
|
||||
root = recursiveAdd(root, val);
|
||||
if (isSuccess) {
|
||||
++count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TreeSet::contains(int val)
|
||||
{
|
||||
AVLNode *temp = root;
|
||||
while (temp != nullptr) {
|
||||
if (temp->key > val)
|
||||
temp = temp->left;
|
||||
else if (temp->key < val)
|
||||
temp = temp->right;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TreeSet::copy(const TreeSet &set)
|
||||
{
|
||||
clear();
|
||||
root = recursiveCopy(set.root);
|
||||
count = set.count;
|
||||
}
|
||||
|
||||
int TreeSet::first()
|
||||
{
|
||||
if (root == nullptr) {
|
||||
throw "NoSuchElementException";
|
||||
}
|
||||
AVLNode *temp = root;
|
||||
while (temp->left != nullptr)
|
||||
temp = temp->left;
|
||||
return temp->key;
|
||||
}
|
||||
|
||||
int TreeSet::last()
|
||||
{
|
||||
if (root == nullptr) {
|
||||
throw "NoSuchElementException";
|
||||
}
|
||||
AVLNode *temp = root;
|
||||
while (temp->right != nullptr)
|
||||
temp = temp->right;
|
||||
return temp->key;
|
||||
}
|
||||
|
||||
int TreeSet::higher(int val)
|
||||
{
|
||||
if (root == nullptr)
|
||||
return -1;
|
||||
int higher = last();
|
||||
if (val >= higher)
|
||||
return -1;
|
||||
AVLNode *temp = root;
|
||||
while (temp != nullptr) {
|
||||
if (temp->key > val) {
|
||||
if (temp->key < higher)
|
||||
higher = temp->key;
|
||||
temp = temp->left;
|
||||
} else {
|
||||
temp = temp->right;
|
||||
}
|
||||
}
|
||||
return higher;
|
||||
}
|
||||
|
||||
int TreeSet::lower(int val)
|
||||
{
|
||||
if (root == nullptr)
|
||||
return -1;
|
||||
int lower = first();
|
||||
if (val <= lower)
|
||||
return -1;
|
||||
AVLNode *temp = root;
|
||||
while (temp != nullptr) {
|
||||
if (temp->key < val) {
|
||||
if (temp->key > lower)
|
||||
lower = temp->key;
|
||||
temp = temp->right;
|
||||
} else {
|
||||
temp = temp->left;
|
||||
}
|
||||
}
|
||||
return lower;
|
||||
}
|
||||
|
||||
int TreeSet::remove(int val)
|
||||
{
|
||||
isSuccess = false;
|
||||
root = recursiveRemove(root, val);
|
||||
if (isSuccess) {
|
||||
--count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
TreeSet *TreeSet::subSet(int fromVal, int toVal)
|
||||
{
|
||||
TreeSet *subSet = new TreeSet;
|
||||
recursiveSubSet(subSet, root, fromVal, toVal);
|
||||
return subSet;
|
||||
}
|
||||
|
||||
int TreeSet::size()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
int TreeSet::getHeight(AVLNode *node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return 0;
|
||||
return node->balance;
|
||||
}
|
||||
|
||||
void TreeSet::setHeight(AVLNode *&node)
|
||||
{
|
||||
node->balance = max(getHeight(node->left), getHeight(node->right)) + 1;
|
||||
}
|
||||
|
||||
int TreeSet::getBalance(AVLNode *node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return 0;
|
||||
return getHeight(node->left) - getHeight(node->right);
|
||||
}
|
||||
|
||||
void TreeSet::recursiveSubSet(TreeSet *&subSet, AVLNode *node, int fromVal, int toVal)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return;
|
||||
if (node->key < fromVal) {
|
||||
recursiveSubSet(subSet, node->right, fromVal, toVal);
|
||||
} else if (node->key < toVal) {
|
||||
subSet->add(node->key);
|
||||
recursiveSubSet(subSet, node->left, fromVal, toVal);
|
||||
recursiveSubSet(subSet, node->right, fromVal, toVal);
|
||||
} else {
|
||||
recursiveSubSet(subSet, node->left, fromVal, toVal);
|
||||
}
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::recursiveAdd(AVLNode *&node, int val)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
isSuccess = true;
|
||||
return new AVLNode(val, 1);
|
||||
}
|
||||
if (node->key == val)
|
||||
return node;
|
||||
if (node->key > val)
|
||||
node->left = recursiveAdd(node->left, val);
|
||||
else
|
||||
node->right = recursiveAdd(node->right, val);
|
||||
setHeight(node);
|
||||
return rebalance(node);
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::recursiveRemove(AVLNode *&node, int val)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return node;
|
||||
if (node->key > val) {
|
||||
node->left = recursiveRemove(node->left, val);
|
||||
} else if (node->key < val) {
|
||||
node->right = recursiveRemove(node->right, val);
|
||||
} else {
|
||||
if (node->left == nullptr) {
|
||||
AVLNode *temp = node->right;
|
||||
delete node;
|
||||
isSuccess = true;
|
||||
return temp;
|
||||
}
|
||||
AVLNode *delNode = node->left;
|
||||
while (delNode->right != nullptr)
|
||||
delNode = delNode->right;
|
||||
node->key = delNode->key;
|
||||
node->left = recursiveRemove(node->left, node->key);
|
||||
}
|
||||
return rebalance(node);
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::recursiveCopy(AVLNode *node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return node;
|
||||
AVLNode *temp = new AVLNode(node->key, node->balance);
|
||||
temp->left = recursiveCopy(node->left);
|
||||
temp->right = recursiveCopy(node->right);
|
||||
return temp;
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::rotateLeft(AVLNode *&node)
|
||||
{
|
||||
AVLNode *temp = node->right;
|
||||
AVLNode *tmp = temp->left;
|
||||
node->right = tmp;
|
||||
temp->left = node;
|
||||
setHeight(node);
|
||||
setHeight(temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::rotateRight(AVLNode *&node)
|
||||
{
|
||||
AVLNode *temp = node->left;
|
||||
AVLNode *tmp = temp->right;
|
||||
node->left = tmp;
|
||||
temp->right = node;
|
||||
setHeight(node);
|
||||
setHeight(temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::rebalance(AVLNode *&node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return nullptr;
|
||||
int balance = getBalance(node);
|
||||
if (balance > 1) {
|
||||
if (getBalance(node->left) < -1)
|
||||
node->left = rotateLeft(node->left);
|
||||
node = rotateRight(node);
|
||||
} else if (balance < -1) {
|
||||
if (getBalance(node->right) > 1)
|
||||
node->right = rotateRight(node->right);
|
||||
node = rotateLeft(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include"AVLNode.h"
|
||||
|
||||
class TreeSet
|
||||
{
|
||||
private:
|
||||
AVLNode *root;
|
||||
int count;
|
||||
int getHeight(AVLNode *node);
|
||||
void setHeight(AVLNode *&node);
|
||||
int getBalance(AVLNode *node);
|
||||
void recursiveSubSet(TreeSet *&treeSet, AVLNode *node, int fromVal, int toVal);
|
||||
AVLNode *recursiveAdd(AVLNode *&node, int val);
|
||||
AVLNode *recursiveRemove(AVLNode *&node, int val);
|
||||
AVLNode *recursiveCopy(AVLNode *node);
|
||||
AVLNode *rotateLeft(AVLNode *&node);
|
||||
AVLNode *rotateRight(AVLNode *&node);
|
||||
AVLNode *rebalance(AVLNode *&node);
|
||||
protected:
|
||||
void clearRec(AVLNode *root);
|
||||
public:
|
||||
TreeSet();
|
||||
~TreeSet();
|
||||
void clear();
|
||||
friend ostream &operator<<(ostream &os, const TreeSet &t);
|
||||
int add(int val);
|
||||
bool contains(int val);
|
||||
void copy(const TreeSet &set);
|
||||
int first();
|
||||
int higher(int val);
|
||||
int last();
|
||||
int lower(int val);
|
||||
int remove(int val);
|
||||
TreeSet *subSet(int fromVal, int toVal);
|
||||
int size();
|
||||
};
|
||||
@@ -0,0 +1,103 @@
|
||||
/* Copyright (C) 2018
|
||||
* Course: CO2003
|
||||
* Author: Rang Nguyen
|
||||
* Ho Chi Minh City University of Technology
|
||||
*/
|
||||
|
||||
#include"TreeSet.h"
|
||||
#include<fstream>
|
||||
|
||||
void print(ostream& os, AVLNode* root) {
|
||||
if (root != NULL) {
|
||||
print(os, root->left);
|
||||
os << root->key << " ";
|
||||
print(os, root->right);
|
||||
}
|
||||
}
|
||||
|
||||
// print all elements in the set in ascending order
|
||||
ostream& operator<<(ostream& os, const TreeSet& tree) {
|
||||
if (tree.root == NULL) os << "NULL\n";
|
||||
else print(os, tree.root);
|
||||
return os;
|
||||
}
|
||||
|
||||
int main() {
|
||||
TreeSet set, temp, *subSet;
|
||||
ifstream ifs;
|
||||
ifs.open("input.txt");
|
||||
char command;
|
||||
int val;
|
||||
try
|
||||
{
|
||||
while (ifs >> command) {
|
||||
switch (command) {
|
||||
case 'a': // add an element to the set
|
||||
ifs >> val;
|
||||
set.add(val);
|
||||
break;
|
||||
case 'c': // check if an element is in the set or not
|
||||
ifs >> val;
|
||||
printf("The set contains %d: %d\n", val, set.contains(val));
|
||||
break;
|
||||
case 'd': // copy the set to a new one
|
||||
temp.copy(set);
|
||||
cout << temp << endl;
|
||||
temp.clear();
|
||||
cout << temp.size() << endl;
|
||||
break;
|
||||
case 'f': // return the smallest element in the set
|
||||
printf("The smallest element in the set is: %d\n", set.first());
|
||||
break;
|
||||
case 'h': // returns smallest element greater than val.
|
||||
ifs >> val;
|
||||
printf("The smallest element greater than %d is %d\n", val, set.higher(val));
|
||||
break;
|
||||
case 'l': // return the largest element in the set
|
||||
printf("The largest element in the set is: %d\n", set.last());
|
||||
break;
|
||||
case 'o': // returns largest element smaller than val.
|
||||
ifs >> val;
|
||||
printf("The largest element smaller than %d is %d\n", val, set.lower(val));
|
||||
break;
|
||||
case 'p': // print the content of the set in ascending order
|
||||
cout << set << endl;
|
||||
break;
|
||||
case 'r': // remove an element from the set
|
||||
ifs >> val;
|
||||
set.remove(val);
|
||||
break;
|
||||
case 's': // return the sub set
|
||||
int fromVal, toVal;
|
||||
ifs >> fromVal >> toVal;
|
||||
subSet = set.subSet(fromVal, toVal);
|
||||
cout <<"Subset is: "<< *subSet << endl;
|
||||
if (!subSet) delete subSet;
|
||||
break;
|
||||
case 'z': //returns the size of the set
|
||||
printf("The number of elements in the set is: %d\n", set.size());
|
||||
break;
|
||||
default:
|
||||
throw "Wrong input format!";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (char const* s) {
|
||||
printf("An exception occurred. Exception type: %s\n", s);
|
||||
}
|
||||
|
||||
ifs.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user