Tải bản đầy đủ (.pptx) (87 trang)

Hashmap Và Linkedlist

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (9.03 MB, 87 trang )

<span class="text_page_counter">Trang 1</span><div class="page_container" data-page="1">

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN

SEMINAR LẬP TRÌNH JAVA

HASHMAP VÀ LINKEDLIST TRONG JAVA

Presented Day

Nước Code Dừa 07/03/2024

Presented by

</div><span class="text_page_counter">Trang 2</span><div class="page_container" data-page="2">

<small>TeamNước Code Dừa</small>

<small>22520170Phan Thành Công22520124Trần Vũ Bão</small>

<small>22520423 Phan Thị Thuỷ Hiền</small>

<small>Tools/LanguagesEclipse, IntelliJ, Java IDE online,...</small>

GENERAL INTRODUCTION

</div><span class="text_page_counter">Trang 3</span><div class="page_container" data-page="3">

NƯỚC CODE DỪA

</div><span class="text_page_counter">Trang 4</span><div class="page_container" data-page="4">

1. Hashmap trong java là gì?2. Đặc điểm của Hashmap

3. Cách hoạt động của Hashmap 4. Cấu trúc phân tầng của lớp Hashmap5. Constructor của lớp

8. Hiên thực các phương thức phổ biến của Hashmap

6. Các phương thức của lớp Hashmap

7. Cách tạo Hashmap trong java

</div><span class="text_page_counter">Trang 5</span><div class="page_container" data-page="5">

• Hashmap trong java là gì?

• HashMap là một lớp trong Java Collection Framework.

• HashMap hoạt động dựa trên cơ chế bảng băm

(hashing) để lưu trữ và truy xuất các phần tử dưới hình thức các cặp khóa-giá trị (key-value) khơng theo thứ tự nhất định.

• Trong HashMap, các khóa phải là duy nhất vì khóa được sử dụng để lấy giá trị tương ứng từ map.

</div><span class="text_page_counter">Trang 6</span><div class="page_container" data-page="6">

2. Đặc điểm của Hashmap

• Sử dụng hàm băm (hash function): HashMap sử dụng một hàm băm để gán khóa (key) với một chỉ số trong một mảng (array). Điều này cho phép tìm kiếm các giá trị nhanh chóng dựa trên key.

• Mỗi phần tử trong HashMap được lưu trữ dưới dạng một cặp key-value. Các key được sử dụng để truy xuất value tương ứng.

• Cho phép value trùng lặp: HashMap cho phép value trùng lặp, nhưng không cho phép key trùng lặp. Trường hợp xuất hiện key trùng lặp, value trước đó của key sẽ bị ghi đè.

• Cho phép null: HashMap cho phép sử dụng key null và value null.

</div><span class="text_page_counter">Trang 7</span><div class="page_container" data-page="7">

2. Đặc điểm của Hashmap

• Khơng thứ tự: Các phần tử trong HashMap khơng được sắp xếp theo bất kỳ thứ tự nào, thứ tự này có thể thay đổi khi thêm hoặc xóa.

• Khơng đồng bộ: HashMap khơng đồng bộ, khơng an tồn cho môi trường đa luồng. Nếu cần sử dụng HashMap trong mơi

trường đa luồng, có thể sử dụng ConcurrentHashMap.

• Tự động điều chỉnh kích thước: Khi số lượng phần tử trong HashMap vượt quá ngưỡng tải trọng (load factor) của nó, HashMap sẽ tự động điều chỉnh kích thước.

</div><span class="text_page_counter">Trang 8</span><div class="page_container" data-page="8">

3. Cách hoạt động của Hashmap

HashMap hoạt động trên thuật toán băm (hashing) và sử dụng phương thức hashCode() và equals() trên khóa (key) cho các thao tác get và put.

• Phương thức hashcode(): tính tốn giá trị băm của một khóa (key).• Phương thức equals(): so sánh hai khóa (key) với nhau để xác định

chúng có bằng nhau hay khơng.

• Giá trị băm (hash value): xác định vị trí lưu trữ các phần tử trong các bộ sưu tập này.

• Bucket: nếu hai khóa có cùng giá trị băm, chúng sẽ được lưu trữ trong cùng một vị trí, được gọi là bucket. Trong mỗi bucket, các cặp khóa-

giá trị được lưu trữ dưới dạng các phần tử trong một danh sách liên kết đơn.

MỘT SỐ KHÁI NIỆM

</div><span class="text_page_counter">Trang 9</span><div class="page_container" data-page="9">

3. Cách hoạt động của Hashmap

</div><span class="text_page_counter">Trang 10</span><div class="page_container" data-page="10">

3. Cách hoạt động của Hashmap

• Khi muốn truy xuất một giá trị (value) từ HashMap bằng khoá (key) tương ứng:

⚬ hashCode(): tính tốn giá trị băm của khóa và xác định vị trí của bucket cần tìm.

⚬ equals(): so sánh khóa cần tìm với các khóa bucket.

■ Nếu có phần tử với key tương ứng được tìm thấy trong danh sách liên kết đơn của bucket, value tương ứng với key đó sẽ được trả về.

■ Nếu khơng có, HashMap sẽ trả về giá trị null.• Khi thêm một cặp key-value mới vào HashMap:

⚬ equals(): kiểm tra tính duy nhất của khóa trong một bucket.

■ Nếu equals() trả về false (không trùng lặp), cặp key-value mới sẽ được thêm vào danh sách liên kết đơn trong bucket tương ứng.

■ Nếu equals() trả về true (key bị trùng lặp), value mới sẽ ghi đè lên value cũ.

• Để đảm bảo rằng các phần tử được lưu trữ và truy xuất một cách hiệu quả, người lập trình viên nên cài đặt phương thức hashCode và equals cho lớp khóa.

</div><span class="text_page_counter">Trang 11</span><div class="page_container" data-page="11">

3. Cách hoạt động của Hashmap

</div><span class="text_page_counter">Trang 12</span><div class="page_container" data-page="12">

4. Cấu trúc phân tầng của lớp Hashmap

• Lớp HashMap trong Java được xây dựng trên cơ sở AbstractMap là một lớp trừu tượng cung cấp một số phương thức cơ bản cho các lớp Map.

• HashMap là một lớp con của AbstractMap và triển khai của giao diện Map.

</div><span class="text_page_counter">Trang 13</span><div class="page_container" data-page="13">

4. Cấu trúc phân tầng của lớp Hashmap

</div><span class="text_page_counter">Trang 14</span><div class="page_container" data-page="14">

5. Constructor của lớp Hashmap

• HashMap(): tạo một Hashmap trống với kích thước mặc định là 16 và tỷ lệ tải mặc định là 0.75.

• HashMap(int initialCapacity): tạo một HashMap trống với kích thước ban đầu được chỉ định và tỷ lệ tải mặc định là 0.75.

• HashMap(int initialCapacity, float loadFactor): tạo một

HashMap trống với kích thước ban đầu và tỷ lệ tải được chỉ định.

⚬ initialCapacity: kích thước ban đầu của HashMap (số lượng phần tử mà nó có thể chứa trước khi phải tăng kích thước)

⚬ loadFactor: tỷ lệ tải của HashMap (khi số lượng phần tử trong HashMap vượt qua kích thước * tỷ lệ tải, HashMap sẽ tăng kích thước)

</div><span class="text_page_counter">Trang 15</span><div class="page_container" data-page="15">

5. Constructor của lớp Hashmap

</div><span class="text_page_counter">Trang 16</span><div class="page_container" data-page="16">

5. Constructor của lớp Hashmap

</div><span class="text_page_counter">Trang 17</span><div class="page_container" data-page="17">

5. Constructor của lớp Hashmap

• HashMap(Map<?extends K, ? extends V> m): tạo một

HashMap mới chứa các ánh xạ từ các khoá và giá trị được chỉ định.

⚬ "Map<? extends K, ? extends V> m" là một tham chiếu đến một đối tượng Map, với K và V là hai kiểu dữ liệu bất kỳ.

⚬ "<? extends K, ? extends V>" chỉ định rằng đối tượng Map này có thể chứa các cặp key-value với kiểu dữ liệu không nhất thiết phải trùng với kiểu dữ liệu của HashMap đang tạo.

</div><span class="text_page_counter">Trang 18</span><div class="page_container" data-page="18">

5. Constructor của lớp Hashmap

</div><span class="text_page_counter">Trang 19</span><div class="page_container" data-page="19">

Từ Java 5, cú pháp của HashMap là HashMap<K,V>, trong đó K đại diện cho Key(Khóa), V đại diện cho Value(Giá trị)

6. Các phương thức của lớp Hashmap

• void clear(): xố tất cả các ánh xạ khỏi HashMap

• boolean containsKey(Object key): kiểm tra xem HashMap có chứa khố được chỉ định hay khơng• boolean containsValue(Object value): kiểm tra xem HashMap có chứa giá trị được chỉ định hay

• Set<Map.Entry<K,V>> entrySet(): trả về một Set chứa tất cả các cặp key-value trong HashMap• V get(Object key): trả về giá trị được liên kết với khố được chỉ định

• boolean isEmpty(): kiểm tra xem HashMap có rỗng khơng

• Set<K> keySet(): trả về một Set chứa tất cả key trong HashMap• V put(K key, V value): thêm một cặp key-value mới vào HashMap

• void putAll(Map<? extends K, ? extends V> m): đặt tất cả các cặp key-value từ Map khác vào HashMap

• V remove(Object key): xố cặp key-value được chỉ định khỏi HashMap• int size(): trả về số lượng cặp key-value có trong HashMap

• Collection<V> values(): trả về một Collection chứa tất cả các giá trị trong HashMap

</div><span class="text_page_counter">Trang 20</span><div class="page_container" data-page="20">

Từ phiên bản Java 8, HashMap trong Java được bổ sung thêm nhiều phương thức mới phục vụ các thao các khác nhau

• V getOrDefault(Object key, v defaultValue): trả về value được liên kết với key được chỉ định. Nếu key không tồn tại, trả về giá trị mặc định

• void forEach(BiCosumer<? super K, ? super V> action): thực hiện một hành động trên mỗi cặp key-value trong HashMap

• V putIfAbsent(K key, V value): đặt một cặp key-value mới vào HashMap nếu key chưa tồn tại• boolean remove(Object key, Object value): xoá một cặp key-value khỏi HashMap nếu key và

value được chỉ định khớp với một cặp có sẵn

• boolean replace(K key, V oldValue, V newValue): thay thế value cũ bằng value mới nếu key và value cũ đã được chỉ định khớp với một cặp có sẵn

• V replace(K key, V value): thay thế value hiện tại của key được chỉ định bằng value mới. Trả về value cũ hoặc null nếu khơng có giá trị nào được liên kết với key đó

6. Các phương thức của lớp Hashmap

</div><span class="text_page_counter">Trang 21</span><div class="page_container" data-page="21">

CÁCH TẠO

HASHMAP TRONG JAVA

</div><span class="text_page_counter">Trang 22</span><div class="page_container" data-page="22">

Import thư viện

<small>import java.util.HashMap;</small>

</div><span class="text_page_counter">Trang 25</span><div class="page_container" data-page="25">

Ví dụ

</div><span class="text_page_counter">Trang 26</span><div class="page_container" data-page="26">

1. Thêm một phần tử

2. Cập nhật giá trị3. Truy suất giá trị

8. Kiểm tra sự tồn tại của khóa

4. Lấy tất cả các khóa

</div><span class="text_page_counter">Trang 27</span><div class="page_container" data-page="27">

Giá trị cũ(nếu có) / nullPhương thức put(key, value) thêm

một cặp key - value vào hashmap và trả về null. Nếu key đã tồn tại, cập nhật giá trị mới cho key và trả về giá trị cũ tương ứng với key.

</div><span class="text_page_counter">Trang 28</span><div class="page_container" data-page="28">

<small>1. Thêm một phần tử</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 29</span><div class="page_container" data-page="29">

<small>2. Cập nhật giá trị</small>

Các thao tác với hash map

<small>Thêm/cập nhật giá trị đều dùng hàm put()</small>

<small>Nếu phần tử chưa tồn tại thì thêm, ngược lại cập nhật</small>

</div><span class="text_page_counter">Trang 30</span><div class="page_container" data-page="30">

Giá trị (nếu có) / null

Phương thức get(key) trả về giá trị tương ứng với key trong hashmap. Nếu key không tồn tại thì trả về null

</div><span class="text_page_counter">Trang 31</span><div class="page_container" data-page="31">

<small>3. Truy xuất phần tử</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 32</span><div class="page_container" data-page="32">

<small>3. Truy xuất phần tửTrường hợp phần tử không tồn tại</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 33</span><div class="page_container" data-page="33">

SetPhương thức keySet() trả về

một set bao gồm các khóa có trong hashmap.

</div><span class="text_page_counter">Trang 34</span><div class="page_container" data-page="34">

<small>4. Lấy tất cả các khóa</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 36</span><div class="page_container" data-page="36">

Danh sách (dạng

Collection)Phương thức values() trả về

một Collection bao gồm tất các giá trị của hashmap

</div><span class="text_page_counter">Trang 37</span><div class="page_container" data-page="37">

<small>5. Lấy tất cả các giá trị</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 39</span><div class="page_container" data-page="39">

6. Lấy tất cả các cặp khóa và giá trị

HashMap<String, Integer> map = new HashMap();map.entrySet();

Tham số

OutputMô tả

SetPhương thức entrySet() trả về

một Set bao gồm tất cả các cặp khóa & giá trị của

hashmap.

</div><span class="text_page_counter">Trang 40</span><div class="page_container" data-page="40">

<small>6. Lấy tất cả các cặp khóa - giá trị</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 41</span><div class="page_container" data-page="41">

<small>6. Lấy tất cả các cặp khóa - giá trị</small>

Các thao tác với hash map

<small>Output</small>

</div><span class="text_page_counter">Trang 42</span><div class="page_container" data-page="42">

<small>7. Duyệt các phần tửSử dụng keySet()</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 43</span><div class="page_container" data-page="43">

<small>7. Duyệt các phần tửSử dụng keySet()</small>

Các thao tác với hash map

<small>Output</small>

</div><span class="text_page_counter">Trang 44</span><div class="page_container" data-page="44">

<small>7. Duyệt các phần </small>

<small>Sử dụng entrySet()</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 45</span><div class="page_container" data-page="45">

<small>7. Duyệt các phần </small>

<small>Sử dụng entrySet()</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 46</span><div class="page_container" data-page="46">

8. Kiểm tra sự tồn tại của khóa

HashMap<String, Integer> map = new HashMap();map.containsKey(_key_);

Tham số

ReturnMô tả

True/false (boolean)Phương thức containsKey(key)

sẽ trả về true nếu HashMap chứa khóa đã cho và false nếu khơng.

</div><span class="text_page_counter">Trang 47</span><div class="page_container" data-page="47">

<small>8. Kiểm tra sự tồn tại của khóa</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 48</span><div class="page_container" data-page="48">

Giá trị của phần tử vừa xóa (nếu có) / null

Phương thức remove(key) sẽ xóa phần tử có khóa key ra khỏi hashmap và trả về giá trị của phần tử vừa xóa nếu có, ngược lại trả về null.

</div><span class="text_page_counter">Trang 49</span><div class="page_container" data-page="49">

<small>09. Xóa phần tử</small>

Các thao tác với hash map

</div><span class="text_page_counter">Trang 50</span><div class="page_container" data-page="50">

01. Đặt ra vấn đề02. Giới thiệu về LinkedList trong Java

05. Constructor của LinkedList

07. So sánh 2 lớp

ArrayList và LinkedList

06. Các phương thức của LinkedList

08. Ví dụ về việc sử dụng LinkedList

LinkedList

</div><span class="text_page_counter">Trang 51</span><div class="page_container" data-page="51">

• Đặt ra vấn đề

Đặt ra vấn đề: sử dụng array hay lớp ArrayList để giải quyết bài tốn thêm/xóa 1 phần tử vào vị trí chính giữa tốn nhiều chi phí.

</div><span class="text_page_counter">Trang 52</span><div class="page_container" data-page="52">

• Đặt ra vấn đề

</div><span class="text_page_counter">Trang 53</span><div class="page_container" data-page="53">

• Đặt ra vấn đề

Giải quyết vấn đề: sử dụng cấu trúc dữ liệu danh sách liên kết (linked list).

</div><span class="text_page_counter">Trang 54</span><div class="page_container" data-page="54">

• Đặt ra vấn đề

Giải quyết vấn đề: đối với bài tốn xóa 1 phần tử ở vị trí chính giữa, khi sử dụng linked list, chúng ta chỉ cần cập nhật lại vị trí tham chiếu của các liên kết.

</div><span class="text_page_counter">Trang 55</span><div class="page_container" data-page="55">

• Đặt ra vấn đề

• Khi học C++, chúng ta sử dụng thư viện STL để thuận tiện trong việc

thao tác với linked list.

• Tương tự với ngôn ngữ Java, chúng ta sẽ sử dụng lớp LinkedList được cung cấp bởi Java Collections

Framework.

</div><span class="text_page_counter">Trang 56</span><div class="page_container" data-page="56">

2. Giới thiệu về LinkedList trong Java

• Là một lớp trong Java Collection Framework.

• Sử dụng danh sách liên kết đôi (Doubly Linked List) để lưu trữ các phần tử.

</div><span class="text_page_counter">Trang 57</span><div class="page_container" data-page="57">

2. Giới thiệu về LinkedList trong Java

• Mỗi phần tử trong danh sách liên kết được gọi là nút (node), gồm 3 trường:

⚬ Prev: Lưu trữ địa chỉ của phần tử trước đó. Null cho phần tử đầu tiên

⚬ Next: Lưu trữ địa chỉ của phần tử tiếp theo. Null cho phần tử cuối cùng.

⚬ Data: Lưu trữ dữ liệu

</div><span class="text_page_counter">Trang 58</span><div class="page_container" data-page="58">

2. Giới thiệu về LinkedList trong Java

• LinkedList hoạt động như một mảng động kích thước của list sẽ tự động tăng/giảm khi chúng ta thực hiện thêm/xóa phần tử.

</div><span class="text_page_counter">Trang 59</span><div class="page_container" data-page="59">

3. Đặc điểm cần nhớ về LinkedList

• Có thể chứa các phần tử trùng lặp.

• Duy trì thứ tự của phần tử được thêm vào.

• Thao tác thêm/xóa nhanh, vì khơng cần phải dịch chuyển nếu có bất kỳ phần tử nào được thêm/xóa khỏi danh sách.

</div><span class="text_page_counter">Trang 61</span><div class="page_container" data-page="61">

3. Đặc điểm của lớp LinkedList

• Có thể được sử dụng như một

List(danh sách), Stack(ngăn xếp) hay Queue(hàng đợi).

</div><span class="text_page_counter">Trang 62</span><div class="page_container" data-page="62">

4. Khai Báo và Khởi tạo

• LinkedList là một lớp thuộc package java.util• Khi muốn sử dụng lớp LinkedList, phải import

Khai Báo

</div><span class="text_page_counter">Trang 63</span><div class="page_container" data-page="63">

4. Khai Báo và Khởi tạo

• Có 2 cách :

⚬ non-generic: LinkedList list = new LinkedList();

⚬ generic: LinkedList<Type> list = new LinkedList<Type>();

Khởi tạo

</div><span class="text_page_counter">Trang 64</span><div class="page_container" data-page="64">

4. Khai Báo và Khởi tạo

Ví dụ

<small>LinkedList<Type> list = new LinkedList<Type>();</small>

</div><span class="text_page_counter">Trang 65</span><div class="page_container" data-page="65">

01. Thêm phần tử

02. Truy cập, sửa Cập nhật giá trị

04. Lấy giá trị index

05. Trả về số lượng phần tử, Tim kiếm phần tử

03. Xóa phần tử<sup>06. Chuyển thành </sup>mảng(Array)

5. Các phương thức của LinkedList

</div><span class="text_page_counter">Trang 66</span><div class="page_container" data-page="66">

01. Thêm phần tử

• Chèn element vào vị trí index. Ném một

IndexOutOfBoundsException nếu index đã cho ở bên ngoài dãy (index < 0 || index > size())

• Nối phần tử vào cuối danh sách• chèn phần tử vào đầu danh sách• chèn phần tử vào cuối danh sách

• thêm tất cả các phần tử của Collection vào cuối danh sách

• void add(int index, Object element)

• boolean add(Object element)• void addFirst(Object element)• void addLast(Object element)• boolean addAll(Collection c)

</div><span class="text_page_counter">Trang 69</span><div class="page_container" data-page="69">

02. Truy cập, sửa giá trị phần tử

• Object set(int index, Object element)

</div><span class="text_page_counter">Trang 72</span><div class="page_container" data-page="72">

03. Xóa phần tử

• Xóa phần tử đầu tiên trong danh sách

• Xóa phần tử được chỉ định đầu tiên trong danh sách

• Xóa phần tử tại vị trí index được chỉ định• Xóa phần tử cuối cùng trong danh sách

• Xóa phần tử xuất hiện cuối cùng được chỉ định trong danh sách

• Object remove()

• boolean remove(Object element)

• Object remove(int index)• Object removeLast()

• boolean removeLastOccurrence (Object element)

</div><span class="text_page_counter">Trang 75</span><div class="page_container" data-page="75">

04. Lấy giá trị index

• int indexOf(Object element)

• int lastIndexOf(Object element)

</div><span class="text_page_counter">Trang 79</span><div class="page_container" data-page="79">

06. Chuyển linked list thành mảng (array)

</div><span class="text_page_counter">Trang 81</span><div class="page_container" data-page="81">

Khác nhau

Sử dụng mảng động để lưu trữ các phần tử

Mỗi phần tử có 1 vị trí index

Sử dụng danh sách liên kết để lưu trữ các phần tử

Mỗi phần tử được gọi là node, lưu trữ 3 thơng tin: • tham chiếu phần tử

</div><span class="text_page_counter">Trang 82</span><div class="page_container" data-page="82">

Khác nhau

Chậm hơn, vì sau khi thao tác thêm hoặc xóa cần sắp xếp lại vị trí các phần tử

Độ phức tạp: O(n)

Nhanh hơn, vì khơng cần sắp xếp lại vị trí các phần tử sau khi thêm hoặc xóa

Độ phức tạp: O(1)Thao tác

thêm, xố

Sử dụng bộ nhớ

u cầu ít bộ nhớ hơn, vì chỉ lưu trữ data và index

Yêu cầu nhiều bộ nhớ hơn, vì LinkedList lưu trữ data và tham chiếu tới phần tử trước và sau nó

</div><span class="text_page_counter">Trang 83</span><div class="page_container" data-page="83">

Khác nhau

Nhanh hơn vì các phần tử trong ArrayList được lưu dựa trên index

Có thể truy xuất ngẫu nhiên

Độ Phức tạp: O(1)

Chậm hơn vì phải duyệt qua lần lượt các phần tử từ đầu tiên cho đến cuối cùng

Không thể truy xuất ngẫu nhiên

Độ Phức tạp: O(1)Thao tác

truy xuất

Khi nào sử dụng

Tốt hơn trong việc lưu trữ và truy xuất dữ liệu

Tốt hơn trong việc thao tác dữ liệu (thêm / xóa)

</div><span class="text_page_counter">Trang 84</span><div class="page_container" data-page="84">

Khác nhau

Chỉ hoạt động như 1 list vì nó chỉ triển khai giao tiếp List

Có thể hoạt động như 1 ArrayList, stack, queue, Singly Linked List và Doubly Linked List vì nó triển khai các giao tiếp List và Deque

Trường hợp sử dụng

</div><span class="text_page_counter">Trang 85</span><div class="page_container" data-page="85">

07. Ví dụ về việc sử dụng LinkedList trong đồ án

• Chương trình thêm id và tên sinh viên và chương trình sẽ tạo email

cho sinh viên và sẽ lưu trữ tất cả dữ liệu này trong Danh sách liên kết để ta quản lý

• Chúng ta sử dụng Danh sách liên kết để lưu trữ thông tin các mặt hàng mà người dùng đã mua

</div><span class="text_page_counter">Trang 86</span><div class="page_container" data-page="86">

THANK YOU!Q&A

<small>Nguồn tụi mình tham khảo đã có mặt trên Slide:</small>

<small>• LinkedList</small>

<small>• linkedlist</small>

<small> HashMap</small>

<small>• class="text_page_counter">Trang 87</span><div class="page_container" data-page="87">

THANKS FOR WATCHING

</div>

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×