Professional Documents
Culture Documents
CTDL09 - Linked List
CTDL09 - Linked List
Linked List
THỰC HÀNH CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
TUẦN 10 - THÁNG 01 NĂM 2024
1
Tham khảo cách dùng con trỏ (Pointer)
trong C tại các slide:
In03 - Con trỏ
In05 - Hàm
2
Table of contents
01 02 03
Linked List Insertion Deletion
A brief introduction to a new Insert a node in a list Delete a node from a list
data structure
06 05 04
Dynamic Memory
Homework Practices
Allocation
Everything, everywhere all Insertion malloc()
at once Deletion
01
Linked List
Single linked list
4
DATA POINTER
Mỗi node trong một danh sách liên kết
đơn chứa 2 thành phần: dữ liệu và con trỏ
8 1x098e72
đến node tiếp theo.
Danh sách liên kết đơn có phần HEAD là
HEAD
nút đầu tiên trong danh sách, TAIL là nút
1x098e72
cuối cùng trong danh sách mà phần con
trỏ của nó mang giá trị NULL.
12 1x011f21
Danh sách liên kết đơn hỗ trợ rất tốt trong
việc cài đặt và quản lý Stack và Queue.
Ngoài ra, danh sách liên kết đơn còn có
thể được dùng để triển khai cây nhị phân 1x011f21
(binary tree), cây tìm kiếm nhị phân
(binary search tree) và đồ thị (graph). 19 NULL
TAIL
5
Để khai báo một node trong danh struct Node{
sách liên kết, ta sử dụng một cấu int data;
trúc struct gồm có 2 thành phần:
struct Node* next;
- Data kèm theo kiểu dữ liệu phù };
hợp (int, float, char,...)
- Con trỏ kiểu struct next và trỏ
đến thành phần data của nút typedef struct NodeType {
tiếp theo. int data;
struct NodeType* next;
Ngoài ra ta có thể định nghĩa thêm } Node;
cấu trúc danh sách liên kết để tiện
cho các thao tác trong tương lai. typedef struct LinkedListType {
Node* head;
Thư viện <stdlib.h> hỗ trợ rất tốt cho } LinkedList;
các khai báo trên.
6
02
Insertion
Insert a node in a list
7
Insert at Head
Để chèn một nút mới vào đầu của danh
sách liên kết, ta làm từng bước sau:
1x012e11
Bước 1: Khởi tạo một nút mang data
cần chèn và con trỏ mang giá trị NULL
bằng cách yêu cầu máy tính cấp phát 8 1x098e72
một vùng nhớ cho nút này.
HEAD
12 1x011f21
1x013e11
7 NULL
19 NULL
TAIL
8
1x013e11
19 NULL
TAIL
9
1x013e11
19 NULL
TAIL
10
Insert at Tail
1x012e11
8 1x098e72
Để chèn một nút mới vào cuối của danh
sách liên kết, ta làm từng bước sau:
Bước 1: Khởi tạo một nút mang data
HEAD
cần chèn và con trỏ mang giá trị NULL
bằng cách yêu cầu máy tính cấp phát 12 1x011f21
một vùng nhớ cho nút này.
19 NULL
1x013e11
TAIL
7 NULL
11
Insert at Tail
1x012e11
8 1x098e72
Để chèn một nút mới vào cuối của danh
sách liên kết, ta làm từng bước sau:
Bước 1: Khởi tạo một nút mang data HEAD
cần chèn và con trỏ mang giá trị NULL
bằng cách yêu cầu máy tính cấp phát 12 1x011f21
một vùng nhớ cho nút này.
Bước 2: Tìm đến node cuối cùng (Tail).
Next của Tail hiện tại trỏ đến node cần
chèn. 19 1x013e11
Bước 3: Tail là node mới.
1x013e11
7 NULL
TAIL
12
Insert at anywhere
Để chèn một nút vào giữa danh sách
8 1x098e72
liên kết, ta làm các bước như sau:
Bước 1: Khởi tạo một nút mang data
cần chèn và con trỏ mang giá trị NULL HEAD
bằng cách yêu cầu máy tính cấp phát 1x098e72
một vùng nhớ cho nút này.
12 1x011f21
1x013e11
7 NULL 1x011f21
19 NULL
TAIL
13
Insert at anywhere 8 1x098e72
1x011f21
19 NULL
TAIL
14
Insert at anywhere 8 1x098e72
19 NULL
TAIL
15
03
Deletion
Delete a node from a list
16
Delete at head
Để xoá một nút ở đầu danh sách liên
8 1x098e72
kết, ta cần:
Bước 1: Gán HEAD cho node thứ hai
bằng cách gán head cho con trỏ next
của chính nó hiện tại (1x098e72). 1x098e72
12 1x011f21
HEAD
1x011f21
19 NULL
TAIL
17
Delete at head
Để xoá một nút ở đầu danh sách liên
8 1x098e72
kết, ta cần:
Bước 1: Gán HEAD cho node thứ hai
bằng cách gán head cho con trỏ next
của chính nó hiện tại (1x098e72). 1x098e72
HEAD
1x011f21
19 NULL
TAIL
18
Delete at tail
Để xoá một nút ở cuối danh sách liên
8 1x098e72
kết, ta cần:
Bước 1: Duyệt đến node trước TAIL.
Gán con trỏ next của node đó cho HEAD
NULL. Gán TAIL cho node này. 1x098e72
12 NULL
TAIL
1x011f21
19 NULL
19
Delete at tail
Để xoá một nút ở cuối danh sách liên
8 1x098e72
kết, ta cần:
Bước 1: Duyệt đến node trước TAIL.
Gán con trỏ next của node đó cho HEAD
NULL. Gán TAIL cho node này. 1x098e72
TAIL
1x011f21
19 NULL
20
Delete at anywhere
Để xoá một nút ở giữa danh sách liên
8 1x098e72
kết, ta cần thực hiện các bước sau:
HEAD
1x098e72
12 1x011f21
1x011f21
19 NULL
TAIL
21
Delete at anywhere
Để xoá một nút ở giữa danh sách liên
8 1x011f21
kết, ta cần thực hiện các bước sau:
Bước 1: Duyệt đến node cần xoá và một
node trước nó. Gán con trỏ next của HEAD
node cần xoá cho con trỏ next của 1x098e72
node trước nó.
12 1x011f21
1x011f21
19 NULL
TAIL
22
Delete at anywhere
Để xoá một nút ở giữa danh sách liên
8 1x011f21
kết, ta cần thực hiện các bước sau:
Bước 1: Duyệt đến node cần xoá và một
node trước nó. Gán con trỏ next của HEAD
node cần xoá cho con trỏ next của 1x098e72
node trước nó.
Bước 2: Giải phóng vùng nhớ lưu trữ 12 1x011f21
node cần xoá.
1x011f21
19 NULL
TAIL
23
04
Dynamic
Memory Allocation
malloc()
24
Malloc là hàm được sử dụng để cấp phát bộ nhớ
động. Tên của hàm malloc viết tắt từ "memory
malloc(size)
allocation" (cấp phát bộ nhớ).
Hàm malloc nhận một tham số là size, đại diện cho số
byte mà bạn muốn cấp phát. Hàm này trả về một con
trỏ (kiểu void*) trỏ đến vùng nhớ mới được cấp phát.
Khi gọi hàm malloc, hệ điều hành sẽ tìm kiếm một
Kiểu: Hàm
vùng nhớ trống trong heap (một khu vực trong bộ
INPUT: kích cỡ byte
nhớ) có đủ kích thước để chứa số byte được yêu cầu.
OUTPUT: địa chỉ vùng nhớ
Nếu tìm thấy, hệ điều hành sẽ cấp phát vùng nhớ đó
được cấp phát hoặc NULL
và trả về con trỏ đến địa chỉ đầu của vùng nhớ. Ngược
nếu không tìm được.
lại, nếu không có đủ vùng nhớ trống, hàm malloc sẽ
Hàm đi kèm: free() dùng để
trả về con trỏ không hợp lệ (NULL).
giải phóng vùng nhớ được
cấp phát. Sau khi nhận được con trỏ từ hàm malloc, ta có thể sử
dụng vùng nhớ đó để lưu trữ dữ liệu theo ý muốn. Khi
không cần thì phải giải phóng vùng nhớ đã cấp phát
bằng cách sử dụng hàm free().
25
05
Practice
Insertion - Deletion
26
Practice 01 #include <stdio.h> //Hàm in linked list
#include <stdlib.h> void printList(LinkedList*
list){
//Định nghĩa node Node* node = list->head;
Cho cấu trúc node và các hàm với typedef struct NodeType { while (node != NULL) {
chức năng như đoạn code bên. int data; printf("Node address:
struct NodeType* next; %p | ", &(node->data));
}Node; printf("data = %d| ",
1. Hãy bổ sung các đoạn code còn //Định nghĩa Linked list
node->data);
printf("next node
thiếu để hoàn thiện chương trình typedef struct address = %p\n ",
LinkedListType{ node->next);
với chức năng tạo một danh sách Node* head; node = node->next;
2 12 9 0 11 3 4 8
1. Tạo danh sách liên kết trên với phần tử HEAD là 2.
2. Hãy chèn:
a. Số 19 vào đầu danh sách (19 2 12 9 0 11 3 4 8)
b. Số -3 vào cuối của danh sách (19 2 12 9 0 11 3 4 -3)
3. Hãy xoá:
a. Số 19 khỏi danh sách liên kết.
b. Số -3 khỏi danh sách liên kết.
28
06
Homeworks
Everything, everywhere all at once
29
Homework 01
1.1 Viết hàm chèn một node vào vị trí thứ k trong một danh
sách liên kết đơn.
Ví dụ: 2 3 4 5 6 7, data cần chèn là 1 và vị trí cần chèn là k = 2 thì ta được
danh sách mới là 2 1 3 4 5 6 7
1.2 Viết hàm xoá một node tại vị trí thứ k trong một danh
sách liên kết đơn.
Ví dụ: 2 3 4 5 6 7, vị trí cần xoá là k = 2 thì ta được danh sách mới là 2 4 5 6 7
30
Homework 02
Cho cấu trúc dữ liệu danh sách liên kết sau với typedef struct NodeType {
Node là cấu trúc của một node trong danh sách, int data;
và LinkedList là cấu trúc của một danh sách liên struct NodeType* next;
} Node;
kết.
typedef struct LinkedListType {
a. Hãy cài đặt hàm Node* head;
void insert(LinkedList* list, int data); } LinkedList;
để chèn dữ liệu data vào một node mới của
danh sách liên kết list, sao cho danh sách có
thứ tự giảm dần.
b. Hãy cài đặt hàm
void delete(LinkedList* list, int value);
để xóa một node nếu có dữ liệu là value của
danh sách liên kết list, có thứ tự tăng dần.
31
Homework 03
3.1 Dùng danh sách liên kết đơn thay cho mảng để cài đặt
một ngăn xếp (Stacks) với các phần tử là số nguyên.
3.2 Dùng danh sách liên kết đơn thay cho mảng để cài đặt
một hàng đợi (Queue) với các phần tử là số nguyên.
Các cài đặt stacks và queue đều bao gồm các phép toán đi
kèm ứng với mỗi câu 3.1 và 3.2.
32
Homework 04
Nếu homework 01 không dùng đệ quy thì cài đặt lại 1.1 và
1.2 sử dụng kỹ thuật đệ quy.
Ta có thể đánh giá được các hàm đệ quy trên theo quy trình
4 bước không?
- Nếu có thì hãy trình bày câu trả lời.
- Nếu không thì hãy giải thích vì sao.
33
Homework 05
Một khách sạn có 17 tầng, mỗi tầng có 12 phòng được gán mã theo cú pháp
Mô tả: Có n đoàn khách, mỗi đoàn gồm m người đến check-in nhận phòng. Vì có những
khách lẻ đã đặt phòng trước đó nên không thể xếp cho cả 1 đoàn khách ở cùng một
tầng, do đó các khách trong đoàn được xếp ngẫu nhiên vào các phòng trống rời rạc sao
cho khi truy cập thông tin vào một phòng, ta có thể biết tên (chữ cái đầu) của khách và
địa chỉ phòng của người tiếp theo trong đoàn khách. Biết rằng phòng của các trưởng
đoàn luôn ở tầng trệt (tầng 0). Giả sử sức chứa của mỗi phòng là 01 người.
Vấn đề 1: Cho trước trạng thái các phòng hiện tại của khách sạn với ký hiệu “0” tương
ứng với “còn trống” và “1” tương ứng với “đã có người”. Hãy xếp n đoàn khách vào các
phòng sao cho không còn phòng nào “còn trống”.
34
Homework 05
Vấn đề 2: Nhân viên tiếp tân muốn xác nhận thông tin của một đoàn ngẫu nhiên thì chỉ
cần biết được vị trí phòng của trưởng đoàn. Hãy viết một hàm cho phép tiếp tân nhập
vào địa chỉ của trưởng đoàn của một đoàn khách bất kỳ, hàm sẽ trả về tất cả thông tin
của một đoàn bao gồm tên và vị trí phòng tương ứng của từng khách chung đoàn.
Vấn đề 3: Biết rằng lúc này có một số khách lẻ check-out nên xuất hiện một số phòng
trống. Đột nhiên một số đoàn khách báo cáo với khách sạn về việc bổ sung một số khách
mới cần check-in. Hãy bổ sung các vị khách này vào các đoàn tương ứng.
Vấn đề 4: Một số khách của một số đoàn có công việc bận đột xuất nên check-out ngay
trong đêm và tiếp tân muốn kiểm tra lại thông tin của các đoàn như ở Vấn đề 2. Hãy
chỉnh sửa thông tin của các đoàn để chuẩn bị cho cuộc kiểm tra của tiếp tân.
Vấn đề 5: Một đoàn khách (đã check-in trước đó) muốn check-out cho cả đoàn. Hãy thực
hiện chỉnh sửa trạng thái của các phòng mà khách đã check-out theo thứ tự và báo cáo
trạng thái các phòng của khách sạn lúc này.
35
Homework 05 1 1 1
Ví dụ
1 1 1 1 1 1
1 1 1 1 1
Cho danh sách các đoàn như sau với tên người 1 1 1 1 1 1 1 1
Đoàn 1: (12) A B S E F J K L S W Q A 1 1 1 1 1
Đoàn 2: (10) T M K L J S A Q C S 1 1 1 1 1
Đoàn 3: (9) H J S S A S M Q D
Đoàn 4: (13) S A Q D A S S A Q D S Q A 1 1 1 1 1
Đoàn 5: (15) Q S A Q E D F S S A S X V B F 1 1 1 1
Đoàn 6: (14) H A V A N T H A O T T H U S
Đoàn 7: (12) P H L A M D S A T T H U
1 1 1 1 1 1
Đoàn 8: (15) P P N H U N G S V E L E V E N 1 1 1 1 1
Đoàn 9: (10) L P T R U O N G D S 1 1 1 1
Đoàn 10: (10) C H G I A O K D L H
1 1 1 1 1 1
36