0% found this document useful (0 votes)
15 views

Assignment Report

Uploaded by

Mạnh Dương
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

Assignment Report

Uploaded by

Mạnh Dương
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

ASSIGNMENT REPORT

-----------
MIXUE MANAGEMENT PROGRAM USING
AVL TREE
By: HE190510-Ngô Tiến Đạt

1
Table of content:
I. Management program overview……………………………………..3
II. ERD model and database overview…………………………………3
III. Code implementation………………………………………….………4
1. Entities…………………………………………………….……..4
2. User interface…………………………………………….……..5
3. Storage…………………………………………………….…….9
IV. Program drawbacks…………………………………………….…….16
V. Conclusion……………………………………………………….…….16

SRC program:
https://drive.google.com/file/d/1AdCv3oAVEYzm0kYlAS7pF1jXzu_0M37L/view?usp=sharing

2
I.Management program overview
- The Mixue management program is meant to demonstrate the use of an
AVL tree to store and manipulate data, it is not meant to be a complete
program and only includes basic functions such as managing employees
by adding and removing them, printing out a log of invoices,...

II.ERD model and database overview

3
- Employee:
+ Is managed via an ID (int) and their name (String)
- Customer
+ Normally customer info is unnecessary, however, in this scenario,
we assume that any customer added to the management system is
part of a membership program. The customer is given an ID (int) and
their name is recorded (String)
- IceCream
+ The attributes of ice creams include their ID (int), name (String) and
price (float)
- Invoice
+ To easily manage invoices, only 3 attributes are present: ID (int),
total (float) and date (from LocalDate class), like a real invoice from
mixue, customer info is unnecessary

III.Code implementation
- Platform Java17
- Data Storage method: AVL tree

1) Entities
- Below is the code of one of the entities, specifically an employee which
includes attributes and setter methods to set attribute values entered from
the keyboard
- The toString() method is unique to each entities and is created to print out
the details about an entity

package Entities;
public class Employee implements Comparable<Employee>{
int EmpID;
String EmpName;

public Employee() {
}

public void setEmpID(int EmpID) {

4
this.EmpID = EmpID;
}

public void setEmpName(String EmpName) {


this.EmpName = EmpName;
}

public int compareTo(Employee that) {


if (this.EmpID > that.EmpID){
return 1;
}
else {
return 0;
}
}

// The compare to method is a method inherited from the abstract class


comparable, the method is used to compare the values of different employee
objects based on their ID number, this allows for the AVL tree structure to
balance itself

@Override
public String toString() {
return "EmployeeID: " + EmpID + ", Employee Name:" + EmpName + '}';
}
}

2) User interface (only class called in main)


- Below is a simple menu for the user to input their choice and choose what
they want to do
- A simple do while loop is implemented to allow the user to continuously
perform tasks
- When an option is inputed, the matching method from the function class is
called to perform the task
- Different AVL trees matching each entities is called to store data

5
package Interface;
import Storage.AVL;
import Entities.Customer;
import Entities.Employee;
import Entities.IceCream;
import Entities.Invoice;
import csdass1.Functions;
import java.util.Scanner;
public class UserInterface {
AVL<Customer> CUStree = new AVL();
AVL<Employee> EMPtree = new AVL();
AVL<IceCream> ICtree = new AVL();
AVL<Invoice> INVtree = new AVL();

public void mainMenu(){


Scanner sc = new Scanner(System.in);
int option;
do{
System.out.println("Choose a directory to work with:");
System.out.println("1. Customer");
System.out.println("2. Ice cream");
System.out.println("3. Staff member");
System.out.println("4. Invoice");
System.out.println("5. Exit");
System.out.print("Your option: ");
option = sc.nextInt();
System.out.println();
switch (option){
case 1:
System.out.println("1. Add customer");
System.out.println("2. Remove customer");
System.out.println("3. Print all customers");
System.out.println("4. Exit");
System.out.print("Your option: ");
int cusOP = sc.nextInt();
this.customerMenu(cusOP);
break;

6
case 2:
System.out.println("1. Add ice cream");
System.out.println("2. Remove ice cream");
System.out.println("3. Print all ice cream");
System.out.println("4. Exit");
System.out.print("Your option: ");
int creamOP = sc.nextInt();
this.creamMenu(creamOP);
break;
case 3:
System.out.println("1. Add employee");
System.out.println("2. Remove employee");
System.out.println("3. Print all customers");
System.out.println("4. Exit");
System.out.print("Your option: ");
int empOP = sc.nextInt();
this.empMenu(empOP);
break;
case 4:
System.out.println("1. Add new order");
System.out.println("2. Print all invoice");
System.out.println("3. Exit");
System.out.print("Your option: ");
int inOP = sc.nextInt();
this.invMenu(inOP);
break;
case 5:
System.out.println("Exiting program");
break;
}
}
while (option!=5);
}

public void customerMenu(int option){


do{
Functions fc = new Functions();

7
switch (option){
case 1:
fc.addCus(CUStree);
break;
case 2:
fc.removeCus(CUStree);
break;
case 3:
fc.displayCus(CUStree);
System.out.println();
break;
case 4:
System.out.println("Exititng directory");
break;
}
}
while (option < 1 || option >4);
}

public void creamMenu(int option){


Functions fc = new Functions();
switch (option){
case 1:
fc.addIC(ICtree);
break;
case 2:
fc.removeIC(ICtree);
break;
case 3:
fc.displayIC(ICtree);
System.out.println();
break;
case 4:
System.out.println("Exititng directory");
break;
}
}

8
public void empMenu(int option){
Functions fc = new Functions();
switch (option){
case 1:
fc.addEmp(EMPtree);
break;
case 2:
fc.removeEmp(EMPtree);
break;
case 3:
fc.displayEmp(EMPtree);
System.out.println();
break;
case 4:
System.out.println("Exiting directory");
break;
}
}

public void invMenu(int option){


Functions fc = new Functions();
switch (option){
case 1:
fc.addInvoice(INVtree);
break;
case 2:
fc.displayInvoice(INVtree);
System.out.println();
break;
case 3:
System.out.println("Exiting directory");
break;
}
}
}

9
3) Storage
- An AVL tree is a binary tree data structure that automatically balances
itself, it is used to store and quickly access data using nodes, the
beginning node is called a root
- Nodes store data as type <T>, each node has a key, each key is an
entity, the node class also define a left, right and parent node which allows
for left, right and previous traversal respectively, however, the parent node
will not be used to avoid violation of tree traversal rules

package Storage;
public class Node <T>{
Node<T> left;
Node<T> right;
Node<T> parent;
T key;

public Node(T key) {


this.left = null;
this.right = null;
this.parent = null;
this.key = key;
}
}

package Storage;
public class AVL <T extends Comparable<T>> {

Node root;
int size;

public AVL() {
this.root = null;
this.size = 0;
}

10
//check if tree is empty
public boolean isEmpty() {
return this.size == 0;
}

//clear tree
public void clear() {
this.root = null;
this.size = 0;
}

//getHeight of tree via a recursion method, height of the tree = max height + 1
public int getHeight(Node<T> root) {
//if the tree is empty height is -1
if (isEmpty()) {
return -1;
}
//if there is a root node but the node value is null, height is 0
if (root == null) {
return 0;
}
int left = getHeight(root.left);
int right = getHeight(root.right);
return Math.max(left, right) + 1;
}

//getBalance using recursion, returns an int value to indicate tree offset


private int getBalance(Node<T> node) {
if (node == null) {
return 0;
}
return getHeight(node.left) - getHeight(node.right);
}

//rotation methods, they are called when the tree is of balance (usually after
inserting or deleting a node)

11
private Node rotateRight(Node root) {
Node temp = root.left;
Node temp2 = temp.right;
temp.right = root;
root.left = temp2;
temp.parent = root.parent;
root.parent = temp;
if (temp2 != null) {
temp2.parent = root;
}
return temp;
}

private Node rotateLeft(Node root) {


Node temp = root.right;
Node temp2 = temp.left;
temp.left = root;
root.right = temp2;
temp.parent = root.parent;
root.parent = temp;
if (temp2 != null) {
temp2.parent = root;
}
return temp;
}

//recursive insertion method


public void insert(T key) {
this.root = insert(this.root, key);
size++;
}

//insert method
public Node<T> insert(Node<T> root, T key) {
//create a new root node in case of no node
if (root == null) {
return new Node<T>(key);

12
}
//left insert
if (key.compareTo(root.key) <0) {
root.left = insert(root.left, key);
root.left.parent = root;
//right insert
} else if (key.compareTo(root.key) > 0) {
root.right = insert(root.right, key);
root.right.parent = root;
} else {
return root;
}

int balance = getBalance(root);


// Left Left
if (balance > 1 && key.compareTo(root.left.key) < 0) {
return rotateRight(root);
}
// Left Right
if (balance > 1 && key.compareTo(root.left.key) > 0) {
root.left = rotateLeft(root.left);
return rotateRight(root);
}
// Right Right
if (balance < -1 && key.compareTo(root.right.key) > 0) {
return rotateLeft(root);
}
// Right Left
if (balance < -1 && key.compareTo(root.right.key) < 0) {
root.right = rotateRight(root.right);
return rotateLeft(root);
}
return root;
}

//recursive deletion method


public void delete(T key) {

13
this.root = delete(this.root, key);
size--;
}
//delete method
private Node<T> delete(Node<T> node, T key) {
if (node == null) {
return null;
}
if (key.compareTo(node.key) < 0) {
node.left = delete(node.left, key);
} else if (key.compareTo(node.key) > 0) {
node.right = delete(node.right, key);
} else {
// Node with only one child or no child
Node<T> tempParent = node.parent;
if (node.left == null || node.right == null) {
if (node.left != null) {
node = node.left;
node.parent = tempParent;
} else if (node.right != null) {
node = node.right;
node.parent = tempParent;
} else {
return null;
}
} else {
// Node with two children
Node<T> temp = findMin(node.right);
node.key = temp.key;
node.right = delete(node.right, temp.key);
}
}

//check tree balance


int balance = getBalance(node);
//balance case
if (balance > 1 && getBalance(node.left) >= 0) {

14
return rotateRight(node);
}
if (balance > 1 && getBalance(node.left) < 0) {
node.left = rotateLeft(node.left);
return rotateRight(node);
}
if (balance < -1 && getBalance(node.right) <= 0) {
return rotateLeft(node);
}
if (balance < -1 && getBalance(node.right) > 0) {
node.right = rotateRight(node.right);
return rotateLeft(node);
}

return node;
}

//DFS, inorder traversal using recursion


public void inorder() {
inorder(this.root);
}

private void inorder(Node<T> root) {


if (this.root == null) {
System.out.println("Empty directory!");
return;
}
if (root != null) {
inorder(root.left);
String ent = root.key.toString();
System.out.println(ent + " ");
inorder(root.right);
}
}

private Node<T> findMin(Node<T> node) {


Node<T> current = node;

15
while (current.left != null) {
current = current.left;
}
return current;
}
}

IV.Program drawbacks
- Invoices lack order details
- When searching for an entity to delete, user must input all matching
attributes in order to search for the entity which is inconvenient

V.Conclusion
- In conclusion, the Mixue management program can provide basic
functionalities as well as demonstrate effective use of the AVL tree data
structure but lacks some functionalities, it is only used as a demonstration
of the data structure and it is not a commercially viable program

16

You might also like