FinalReport
FinalReport
List of members
Student
Student name Contribution (%)
ID
23110004 Võ Nguyễn Ngọc Bích 100
23110019 Huỳnh Gia Hân 100
Ho Chi Minh City, December 2024
ACKNOWLEDGMENTS
First of all, we would like to express our deepest gratitude and heartfelt thanks to
PhD. Le Van Vinh, who has dedicatedly guided and supported us throughout the final
project of the Data Structures and Algorithms course. Through his invaluable
instruction, we have gained not only a solid foundation in essential concepts but also
the opportunity to explore the practical applications of data structures and algorithms
in solving real-world problems.
Dr. Vinh’s patience and expertise in answering our questions, coupled with his
ability to inspire logical thinking and problem-solving skills, have profoundly
impacted our learning process. His dedication has encouraged us to think critically,
analyze complex scenarios, and apply algorithmic techniques effectively.
Thanks to Dr. Vinh’s exceptional guidance, we were able to complete this project,
gaining newfound knowledge and insights into the subject. While we have done our
utmost to deliver a comprehensive project, we acknowledge that there are inevitably
limitations and areas for improvement. We sincerely hope to receive Dr. Vinh’s
feedback to further refine our understanding and skills, which will undoubtedly benefit
us in future academic and professional endeavors.
Once again, we would like to extend our profound appreciation to Dr. Vinh for
his unwavering support, passion for teaching, and commitment to student
development. We wish him good health, happiness, and continued success in his
career, as he continues to inspire and guide generations of students in their academic
journeys.
Best regard,
Group 06
TABLE OF CONTENTS
ACKNOWLEDGMENTS....................................................................................2
TABLE OF CONTENTS.....................................................................................3
TABLE OF FIGURES..........................................................................................4
A. PROJECT DESCRIPTION.........................................................................5
1. Problem statement....................................................................................5
2. Purpose and requirements.......................................................................5
3. Scope and targets......................................................................................5
3.1. Scope.......................................................................................................5
3.2. Target audience........................................................................................5
4. Overview of exercises................................................................................5
B. CONTENT....................................................................................................7
1. BACKGROUND KNOWLEDGE...........................................................7
1.1. Fundamental knowledge..........................................................................7
1.2. Circular Linked List.................................................................................8
1.3. Queue and its applications.......................................................................9
1.4. Binary Search Tree (BST).......................................................................9
1.5. Development environment....................................................................10
1.5.1. IDE..................................................................................................10
1.5.2. Programming language...................................................................10
1.6. Modules and Frameworks.....................................................................10
1.6.1. .NET Framework.............................................................................10
1.6.2. .NET Libraries.................................................................................10
1.7. Programming technique.........................................................................10
2. SYSTEM DESIGN..................................................................................12
2.1. System Architecture...............................................................................12
2.2. Main Functions......................................................................................13
2.2.1. Circular Linked List Functions........................................................13
2.2.2. Circular Linked List Functions in Music Playlist Management......16
2.2.3. Main Functions in Tetris Game.......................................................17
2.2.4. Main functions in Employee Management System..........................19
3. IMPLEMENTATION, TEST CASES, AND RESULTS......................22
3.1. Implementation......................................................................................22
3.1.1. Circular Linked List Implementation..............................................22
3.1.2. Music Playlist Management Implementation..................................32
3.1.3. Tetris Game Implementation...........................................................36
3.1.4. Employee Management System Implementation.............................48
3.1. Test cases and results.............................................................................56
3.2.1. Circular Linked List.........................................................................56
3.2.2. Music Playlist Management............................................................60
3.2.3. Tetris Game......................................................................................64
3.2.4. Employee Management System.......................................................68
C. CONCLUSION..............................................................................................74
1. EVALUATION.............................................................................................74
1.1. Strengths..................................................................................................74
1.2. Limitations..............................................................................................74
2. FUTURE DEVELOPMENT IDEAS.........................................................75
REFERENCES...................................................................................................77
ROLES AND CONTRIBUTIONS....................................................................78
TABLE OF FIGURES
Figure 1: Features of C Sharp.................................................................................9
Figure 2: Circular Singly Linked List.....................................................................9
Figure 3: Circular Doubly Linked List.................................................................10
A. PROJECT DESCRIPTION
1. Problem statement
The final project for the course "Data Structures and Algorithms" consists of
three exercises designed to apply different data structures in solving practical
problems. Each exercise is targeted at the implementation and application of a certain
data structure, with requirements to show the functionality through user interfaces and
meaningful results.
2. Purpose and requirements
• Develop practical programming skills using the implementation of data
structures like Circular Linked Lists, Queues, and Binary Search Trees.
• Investigate real-life applications for these structures with advanced operations
and user interaction.
• Improve problem-solving skills through designing and testing software
solutions.
3. Scope and targets
3.1. Scope
This project are targeted around three major exercises, as follows:
• Exercise 1: Circular Linked List with basic operations like insertion, deletion,
and search, as well as advanced functionalities such as sorting and merging lists. The
solution is implemented in C#.
• Exercise 2: The Tetris game uses a Queue for handling the storage and the
current state of the tetromino. The user interface is developed using C#.NET.
• Exercise 3: An Employee Management System employing a Binary Search Tree
to efficiently manage and search employee records. This system includes an intuitive
user interface developed in C# with WinForms.
3.2. Target audience
This project is for academic use and thus targets the following:
• Understand the usage of basic data structures in real-world scenarios.
• Instructors seek to assess students' skills in designing and implementing
algorithmic solutions.
4. Overview of exercises
Exercise 1: Circular Linked List
Basic implementations cover insert, delete and find. Advanced operations
include sort and merge.
Implemented with C# with a simplified user interface to better understand how
these operations work in detail.
Exercise 2: Queue in Tetris
The Queue data structure allows smooth delivery of blocks during the game in
runtime.
Implemented using Winforms in C#. The provided UI navigates through this
smoothly.
This form is a
welcome page
displaying BST
MainForm:
implementation
Introduce system
1 details, key features
features and
list
display our team’s
(Add/Search/Delete,
information
BST operations),
and navigation menu
with four tabs
Simple search
FormSearchEmp: interface with
5 Find specific employee ID input
employee field, search button,
information and results display
area
this.btnInsertAtBegin.Font = new
System.Drawing.Font("Microsoft Sans Serif", 13F,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnInsertAtBegin.Location = new System.Drawing.Point(12,
50);
this.btnInsertAtBegin.Name = "btnInsertAtBegin";
this.btnInsertAtBegin.Size = new System.Drawing.Size(177, 39);
this.btnInsertAtBegin.TabIndex = 1;
this.btnInsertAtBegin.Text = "Insert at Begin";
this.btnInsertAtBegin.UseVisualStyleBackColor = true;
this.btnInsertAtBegin.Click += new
System.EventHandler(this.btnInsertAtBegin_Click);
Interface code
this.btnInsertAtEnd.Font = new System.Drawing.Font("Microsoft
Sans Serif", 13F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnInsertAtEnd.Location = new System.Drawing.Point(12,
95);
this.btnInsertAtEnd.Name = "btnInsertAtEnd";
this.btnInsertAtEnd.Size = new System.Drawing.Size(177, 30);
this.btnInsertAtEnd.TabIndex = 2;
this.btnInsertAtEnd.Text = "Insert at End";
this.btnInsertAtEnd.UseVisualStyleBackColor = true;
this.btnInsertAtEnd.Click += new
System.EventHandler(this.btnInsertAtEnd_Click);
if (head.Next == head)
{
head = null;
}
else
{
Node<T> temp = head;
while (temp.Next != head)
{
temp = temp.Next;
}
temp.Next = head.Next;
head = head.Next;
}
}
Interface code
if (head.Next == head)
{
head = null;
}
else {
Node<T> temp = head;
while (temp.Next.Next != head)
{
temp = temp.Next;
}
temp.Next = head;
}
}
Interface code
return null;
}
Interface code
Interface code
if (!Equals(current.Data, min.Data))
{
T swap = current.Data;
current.Data = min.Data;
min.Data = swap;
}
current = current.Next;
} while (current != head);
}
Interface code
if (head->next == head)
{
delete head;
head = nullptr;
}
else
{
Node<T>* temp = head;
while (temp->next != head)
{
temp = temp->next;
}
Node<T>* toDelete = head;
temp->next = head->next;
head = head->next;
delete toDelete;
}
}
Remove Last void removeLast()
{
if (isEmpty())
return;
if (head->next == head)
{
delete head;
head = nullptr;
}
else
{
Node<T>* temp = head;
while (temp->next->next != head)
{
temp = temp->next;
}
Node<T>* toDelete = temp->next;
temp->next = head;
delete toDelete;
}
}
Print List void printList()
{
if (isEmpty())
{
cout << "List is empty.\n";
return;
}
if (current->data != min->data)
{
std::swap(current->data, min->data);
}
current = current->next;
} while (current != head);
}
Merge void merge(CircularLinkedList<T>& otherList)
{
if (isEmpty())
{
head = otherList.head;
return;
}
if (otherList.isEmpty())
return;
temp1->next = otherList.head;
temp2->next = head;
}
Destruction ~CircularLinkedList()
{
if (!isEmpty())
{
Node<T>* temp = head;
do
{
Node<T>* toDelete = temp;
temp = temp->next;
delete toDelete;
} while (temp != head);
}
}
Console.WriteLine("\nPlaylist:");
foreach (var song in songs)
{
Console.WriteLine($"Title: {song.Title}, Artist: {song.Artist},
Duration: {song.Duration} seconds");
}
}
Play Next public void PlayNext()
Song {
if (songs.Count == 0)
{
Console.WriteLine("The playlist is empty.");
return;
}
if (foundSongs.Count > 0)
{
Console.WriteLine($"\nSongs by Artist '{artist}':");
foreach (var song in foundSongs)
{
Console.WriteLine($"Title: {song.Title}, Duration:
{song.Duration} seconds");
}
}
else
{
Console.WriteLine($"No songs by '{artist}' found in the
playlist.");
}
}
Display Total public void DisplayTotalDuration()
Duration {
int totalDuration = 0;
if (choice == 9) break;
switch (choice)
{
case 1:
Console.Write("Enter song title: ");
string title = Console.ReadLine();
Console.Write("Enter artist name: ");
string artist = Console.ReadLine();
Console.Write("Enter song duration (seconds): ");
if (int.TryParse(Console.ReadLine(), out int duration))
{
playlist.AddSong(new Song(title, artist, duration));
}
else
{
Console.WriteLine("Invalid duration entered. Song not
added.");
}
break;
case 2:
Console.Write("Enter the title of the song to remove: ");
string removeTitle = Console.ReadLine();
playlist.RemoveSong(removeTitle);
break;
case 3:
playlist.DisplayPlaylist();
break;
case 4:
playlist.PlayNext();
break;
case 5:
Console.Write("Enter the song title to search: ");
string searchTitle = Console.ReadLine();
playlist.SearchSongByTitle(searchTitle);
break;
case 6:
Console.Write("Enter the artist name to search: ");
string searchArtist = Console.ReadLine();
playlist.SearchSongsByArtist(searchArtist);
break;
case 7:
playlist.DisplayTotalDuration();
break;
case 8:
playlist.ClearPlaylist();
break;
}
}
}
GameGrid Class: Handles grid boundaries, checks for empty spaces, and clears
full rows
Properties:
o Rows and Columns: Dimensions of the grid.
o A 2D array to track the state of each cell (occupied or empty).
Methods:
o IsInside and IsEmpty: Validate cell positions.
o IsRowFull and IsRowEmpty: Check row states.
o ClearFullRows: Clears full rows and shifts above rows down.
namespace TetrisGame
{
public class GameGrid
{
private readonly int[,] grid;
public int Rows { get; }
public int Columns { get; }
}
}
//Dời hàng cột giữ nguyên
private void MoveRowDown(int r, int numRows) {
for (int c = 0; c < Columns; c++) {
grid[r + numRows, c] = grid[r, c];
grid[r,c] = 0;
}
}
public int ClearFullRows()
{
int cleared = 0;
for (int r = Rows -1; r >= 0; r--)
{
if (IsRowFull(r))
{
ClearRow(r);
cleared++;
}
else if (cleared > 0)
{
MoveRowDown(r, cleared);
}
}
return cleared;
}
}
}
GameState Class:
The GameState class manages the game logic:
Handles the current block, score, and held block mechanics.
Implements block movements (left, right, down, rotate) and collision checks.
Detects game-over conditions.
namespace TetrisGame
{
public class GameState
{
private Block currentBlock;
public Block CurrentBlock {
get => currentBlock;
private set
{
currentBlock = value;
currentBlock.Reset();
}
}
public void MoveBlockDown()
{
CurrentBlock.Move(1, 0);
if (!BlockFits())
{
CurrentBlock.Move(-1, 0);
PlaceBlock();
}
}
private int TileDropDistane(Position p)
{
int drop = 0;
while (GameGrid.IsEmpty(p.Row + drop + 1, p.Column))
{
drop++;
}
return drop;
}
public int BlockDropDistance()
{
int drop = GameGrid.Rows;
foreach (Position p in CurrentBlock.TilePosition())
{
drop = System.Math.Min(drop, TileDropDistane(p));
}
return drop;
}
namespace TetrisGame
{
public class IBlock:Block
{
private readonly Position[][] tiles = new Position[][]
{
new Position[] {new(1,0), new (1,1), new(1,2), new(1,3) },
new Position[] {new(0,2), new (1,2), new(2,2), new(3,2) },
new Position[] {new(2,0), new (2,1), new(2,2), new(2,3) },
new Position[] {new(0,1), new (1,1), new(2,1), new(3,1) }
};
public override int Id => 1;
protected override Position StartOffset => new Position(-1, 3);
protected override Position[][] Tiles => tiles;
}
}
namespace TetrisGame
{
public class JBlock : Block
{
private readonly Position[][] tiles = new Position[][]
{
new Position[] {new(0,0), new (1,0), new(1,1), new(1,2) },
new Position[] {new(0,1), new (0,2), new(1,1), new(2,1) },
new Position[] {new(1,0), new (1,1), new(1,2), new(2,2) },
new Position[] {new(0,1), new (1,1), new(2,0), new(2,1) }
};
Delete: Removes an employee node and adjusts the tree structure accordingly.
public void Delete(int employeeId)
{
root = DeleteNode(root, employeeId);
}
node.EmployeeID = FindMinimum(node.Right).EmployeeID;
node.Right = DeleteNode(node.Right, node.EmployeeID);
}
return node;
}
In-Order Traversal: Traverses the tree in sorted order (by Employee ID) and
collects employee records.
public void InOrderTraversal(EmployeeNode node, Action<EmployeeNode>
action)
{
if (node == null) return;
InOrderTraversal(node.Left, action);
action(node);
InOrderTraversal(node.Right, action);
}
try
{
employeeTree.Insert(newEmployee);
MessageBox.Show("Employee added successfully.", "Success",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
FormEditEmployee
This form enables users to update existing employee records. Features include:
Pre-populated fields with the selected employee’s data.
Input validation and checks for logical constraints (e.g., valid date of birth).
private void btnSave_Click(object sender, EventArgs e)
{
if (!ValidateInputs())
return;
try
{
DateTime dateOfBirth = new DateTime(
int.Parse(txtBirthYear.Text),
int.Parse(txtBirthMonth.Text),
int.Parse(txtBirthDay.Text)
);
DialogResult = DialogResult.OK;
Close();
}
catch (ArgumentOutOfRangeException)
{
MessageBox.Show("Invalid date. Please check the day, month, and year
fields.",
"Date Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
FormListEmployees
This form displays a list of all employees in a DataGridView control. Key
features:
Edit and Delete buttons for each record.
Dynamic updates to reflect changes in the tree.
Employee data retrieval via in-order traversal of the BST.
private void DisplayEmployeeList()
{
dgvEmployeeList.Rows.Clear();
dgvEmployeeList.Columns.Clear();
if (employeeToEdit != null)
{
// Open a new form for editing with the employee's details
FormEditEmployee editForm = new FormEditEmployee(employeeToEdit);
if (editForm.ShowDialog() == DialogResult.OK)
{
// Update the employee details in the tree
employeeTree.Update(editForm.UpdatedEmployee);
DisplayEmployeeList(); // Refresh the list
}
}
}
private void DeleteEmployee(int rowIndex)
{
int employeeId =
Convert.ToInt32(dgvEmployeeList.Rows[rowIndex].Cells["ID"].Value);
if (result == DialogResult.Yes)
{
// Implement delete method in EmployeeTree
employeeTree.Delete(employeeId);
DisplayEmployeeList();
}
}
FormSearchEmp
This form facilitates searching for employees ID. Features include:
Case-insensitive search.
Display of results in a DataGridView control.
private void btnSearch_Click(object sender, EventArgs e)
{
if (!int.TryParse(txtSearch.Text.Trim(), out int searchId))
{
MessageBox.Show("Please enter a valid Employee ID.", "Search Error",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (result != null)
{
DisplaySearchResults(new List<EmployeeNode> { result });
}
else
{
MessageBox.Show("No employee found with that ID.", "Search Result",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
Test Cases
Results
Test
Case Screenshots of Actual Output
ID
TC01
TC02
TC03
TC04
TC05
TC06
TC07
Test Cases
Results
Test
Case Screenshots of Actual Output
ID
TC01
TC02
TC03
TC04
TC05
TC06
TC07
TC08
3.2.3. Tetris Game
Test cases
Test Case
Description Input Expected Output
ID
Game initializes with
Test Start Game Click "START GAME"
TC01 empty grid, score at 0,
feature button
first piece appears
Test Exit Game Application closes
TC02 Click "EXIT" button
feature properly
Test block
Use arrow keys to move Block moves according to
TC03 movement and
and place a block input and settles at bottom
placement
Current block moves to
Test hold block Press 'H' with active
TC04 hold box, next block
feature block
becomes active
Line disappears, score
Test line clear Complete a horizontal
TC05 increases, blocks above
and scoring line
move down
"Game Over" screen
Stack blocks to top of
TC06 Test game over appears with final score
grid
and "Play Again" option
Click "Play Again"
Test restart Game resets with empty
TC07 button on game over
feature grid and score at 0
screen
Results
Test
Case Screenshots of Actual Output
ID
TC01
TC02
TC03
TC04
TC05
TC06
TC07
Test Cases
Test Case
Description Input Data Expected Outcome
ID
Add new Employee added
TC01 Valid data inputs
employee successfully
Edit existing
TC02 Valid updates to fields Employee details updated
employee
Search
Employee with
TC03 Partial or full name input Error message displayed
name instead of
ID
Search
List of matching
TC04 employees by Employee ID input
employees
ID
Search with no Employee ID not in the
TC05 No results found message
results nodes
Delete Employee removed
TC06 Employee ID exists
employee successfully
Validate Non-numeric Employee
TC07 Error message displayed
numeric inputs ID
Validate age Date of Birth under 16
TC08 Error message displayed
limits years old
Results
Test
Case Screenshots of Actual Output
ID
TC01
TC02
TC03
TC04
TC05
TC06
TC07
TC08
C. CONCLUSION
1. EVALUATION
1.1. Strengths
Exercise 1: Music Playlist Management
Clear User Interface: The program provides a simple text-based interface that is
easy to understand and navigate, offering clear instructions to the user.
Core Features: It implements essential features such as adding and removing
songs, displaying the playlist, searching by title and artist, playing the next song, and
displaying the total playlist duration.
Playlist Management: The program effectively manages the playlist, keeping
track of the songs and allowing for multiple interactions with the playlist.
Sample Data: The AddSampleSongs method ensures that there are some initial
songs in the playlist for users to interact with when they first run the program,
enhancing the user experience.
Modular Design: The program follows a modular design with separate classes
for Song, Playlist, and Program. This makes the code more organized and easier to
maintain or extend.
Exercise 2: Tetris Game
Modular design: The use of OOP principles ensures high modularity, making
the code easy to maintain and extend.
Random block generation: Apply the queue in Tetris Game throughout
BlockQueue class ensures diverse gameplay by preventing consecutive identical
blocks.
Efficient grid management: The GameGrid class efficiently manages cell states
and clearing of rows.
Game state handling: the GameState class encapsulates game logic, enhancing
code readability.
Friendly and colorful user interface
Having the features "ghost pieces" to preview block positions.
Exercise 3: Employee Management System
Efficient data management: The use of a Binary Search Tree ensures fast and
efficient data operations.
User-friendly interface: Intuitive forms and navigation simplify the use of the
system.
Comprehensive validation: Robust input checks enhance data integrity and user
experience.
Modular design: The system’s architecture allows easy addition of new features
and scalability.
1.2. Limitations
Exercise 1: Music Playlist Management
No Song Persistence: Currently, the playlist and song data are lost once the
program is closed. There's no saving/loading mechanism to preserve the playlist data.
Basic Search Functionality: The search functionality for titles and artists only
works with exact matches (case-insensitive), which may not be ideal for users who
want more flexible search options, such as partial matches or fuzzy search.
Limited Playback Control: The PlayNext method only supports playing the next
song. There is no ability to play, pause, or stop songs, nor is there support for playback
control (such as repeat or shuffle).
Fixed Song Duration: Song duration is entered manually as an integer
(seconds), but no validation is done to ensure the duration is realistic or positive. It
assumes users enter valid input.
Lack of Error Handling: There is limited error handling in some parts of the
code, such as when adding or removing songs. It assumes the input is correct and
doesn’t handle edge cases like invalid input more robustly.
No Playlist Sorting: The playlist is displayed in the order that songs are added,
with no functionality to sort the playlist (by title, artist, or duration).
Exercise 2: Tetris Game
Limited gameplay features: Advanced features like levels, increasing speed, or
sound effects are not implemented.
Exercise 3: Employee Management System
Lack of data persistence: The current version does not include database or file
storage, causing data loss upon application closure.
No user roles: All users have the same level of access, which could be a security
concern in a multi-user environment.
2. FUTURE DEVELOPMENT IDEAS
Exercise 1: Music Playlist Management
Persistent Storage: Implement file handling (e.g., reading and writing to a text
file or using a database) to save and load the playlist data so users can retain their
playlist between sessions.
Enhanced Search: Improve the search functionality to support partial matches
or fuzzy searches, allowing users to find songs even with small typographical errors.
Playback Control: Add the ability to play, pause, skip, stop, shuffle, or repeat
songs. This would provide more control over the playback experience.
Song Editing: Add the ability to edit the properties of an existing song, such as
updating the title, artist, or duration.
Playlist Sorting: Introduce functionality to sort the playlist by title, artist, or
duration, allowing users to better organize their music.
Multiple Playlists: Allow users to create and manage multiple playlists, not just
a single one, and provide options to switch between them.
Graphical User Interface (GUI): Consider adding a GUI using technologies
such as WinForms or WPF for a more user-friendly experience compared to the
command-line interface.
Track Song Play Count: Implement a feature to track the number of times a
song has been played, allowing users to see which songs are their favorites.
Error Handling and Validation: Add more robust error handling for invalid
inputs (e.g., when adding a song with a negative duration or when a user tries to
remove a song that doesn’t exist).
Integration with Music Streaming APIs: For future expansion, integrate the
program with popular music streaming APIs (e.g., Spotify or YouTube) to allow users
to fetch and manage real songs from the web.
Exercise 2: Tetris Game
Advanced gameplay: Introduce levels with increasing difficulty Multiplayer
mode: Allow competitive or cooperative play between two users.
Scoring enhancements: Implement bonus points for clearing multiple rows
simultaneously.
Exercise 3: Employee Management System
Database integration: Implement backup and restore functionality to prevent
data loss by using SQL Server, MySQL, or SQLite.
Role-based access control: Develop a login system with user roles like
Administrator, Manager, and Employee. Restrict access to sensitive features based on
user roles to enhance security.
REFERENCES
1. Geeks for Geeks – Introduction to C#, last updated in 23 Mar, 2023.
https://www.geeksforgeeks.org/introduction-to-c-sharp/
2. Geeks for Geeks – Introduction to Circular Linked List, last updated in 13 Sep,
2024.
https://www.geeksforgeeks.org/circular-linked-list/
3. Gaddis, T. (2021). Starting out with C#: From control structures through
objects (5th ed.). Pearson Education.
4. McMillan, M. E. (2010). Data structures and algorithms using C#. Cambridge
University Press.
5. Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley.
6. Zaharia, M. (2019). Hands-on data structures and algorithms with C#: Level up
your coding skills and solve real-world programming problems with C#. Packt
Publishing.
7. Microsoft. (n.d.). Event-driven programming overview. Microsoft Docs.
Retrieved from https://learn.microsoft.com/en-us/
ROLES AND CONTRIBUTIONS
LIST OF MEMBERS
SEMESTER II ACADEMIC CALENDAR 2024-2025
Group 06 - DASA230179E_02FIE
Student Contribution
Student name Assignment Grade
ID (%)
Implement exercise 1.
23110004 Võ Nguyễn Ngọc Bích 100
Create report of project.
Implement exercise 2, 3.
23110019 Huỳnh Gia Hân 100
Create report of project.
Note:
- (%) = 100%: the percentage of contribution of each member
Lecturer's comments