CHAPTER 6: LINKED
LISTS
Cấu trúc dữ liệu động
3
Mục
Mục
tiêu
tiêu
Giới
Giới
thiệu
thiệu
khái
khái
niệm
niệm
cấu
cấu
trúc
trúc
dữ
dữ
liệu
liệu
động
động
.
.
Giới
Giới
thiệu
thiệu
danh
danh
sách
sách
liên
liên
kết
kết
:
:
Các
Các
kiểu
kiểu
tổ
tổ
chức
chức
dữ
dữ
liệu
liệu
theo
theo
DSLK
DSLK
.
.
Danh
Danh
sách
sách
liên
liên
kết
kết
đơn
đơn
:
:
tổ
tổ
chức
chức
,
,
các
các
thuật
thuật
toán
toán
,
,
ứng
ứng
dụng
dụng
.
.
4
Kiểu
Kiểu
dữ
dữ
liệu
liệu
tĩnh
tĩnh
Khái niệm : Một số đối tượng dữ liệu không thay thay đổi
Khái niệm : Một số đối tượng dữ liệu không thay thay đổi
được kích thước, cấu trúc, … trong suốt quá trình sống.
được kích thước, cấu trúc, … trong suốt quá trình sống.
Các đối tượng dữ liệu thuộc những kiểu dữ liệu gọi là kiểu
Các đối tượng dữ liệu thuộc những kiểu dữ liệu gọi là kiểu
dữ liệu tĩnh.
dữ liệu tĩnh.
Một số kiểu dữ liệu tĩnh : các cấu trúc dữ liệu được xây
Một số kiểu dữ liệu tĩnh : các cấu trúc dữ liệu được xây
dựng từ các kiểu cơ sở như: kiểu thực, kiểu nguyên, kiểu
dựng từ các kiểu cơ sở như: kiểu thực, kiểu nguyên, kiểu
ký tự hoặc từ các cấu trúc đơn giản như mẩu tin, tập
ký tự hoặc từ các cấu trúc đơn giản như mẩu tin, tập
hợp, mảng
hợp, mảng
Các đối tượng dữ liệu được xác định thuộc những kiểu dữ
Các đối tượng dữ liệu được xác định thuộc những kiểu dữ
liệu này thường cứng ngắt, gò bó
liệu này thường cứng ngắt, gò bó
khó diễn tả được thực
khó diễn tả được thực
tế vốn sinh động, phong phú.
tế vốn sinh động, phong phú.
5
CTDL
CTDL
tĩnh
tĩnh
–
–
Một
Một
số
số
hạn
hạn
chế
chế
Một
Một
số
số
đối
đối
tượng
tượng
dữ
dữ
liệu
liệu
trong
trong
chu
chu
kỳ
kỳ
sống
sống
của
của
nó
nó
có
có
thể
thể
thay
thay
đổi
đổi
về
về
cấu
cấu
trúc
trúc
,
,
độ
độ
lớn
lớn
,
,
như
như
danh
danh
sách
sách
các
các
học
học
viên
viên
trong
trong
một
một
lớp
lớp
học
học
có
có
thể
thể
tăng
tăng
thêm
thêm
,
,
giảm
giảm
đi
đi
Nếu
Nếu
dùng
dùng
những
những
cấu
cấu
trúc
trúc
dữ
dữ
liệu
liệu
tĩnh
tĩnh
đã
đã
biết
biết
như
như
mảng
mảng
để
để
biểu
biểu
diễn
diễn
Những
Những
thao
thao
tác
tác
phức
phức
tạp
tạp
,
,
kém
kém
tự
tự
nhiên
nhiên
chương
chương
trình
trình
khó
khó
đọc
đọc
,
,
khó
khó
bảo
bảo
trì
trì
và
và
nhất
nhất
là
là
khó
khó
có
có
thể
thể
sử
sử
dụng
dụng
bộ
bộ
nhớ
nhớ
một
một
cách
cách
có
có
hiệu
hiệu
quả
quả
.
.
Dữ
Dữ
liệu
liệu
tĩnh
tĩnh
sẽ
sẽ
chiếm
chiếm
vùng
vùng
nhớ
nhớ
đã
đã
dành
dành
cho
cho
chúng
chúng
suốt
suốt
quá
quá
trình
trình
hoạt
hoạt
động
động
của
của
chương
chương
trình
trình
sử
sử
dụng
dụng
bộ
bộ
nhớ
nhớ
kém
kém
hiệu
hiệu
quả
quả
.
.
6
CTDL tĩnh
CTDL tĩnh
Mảng 1 chiều
Mảng 1 chiều
Kích thước cố định (fixed size)
Kích thước cố định (fixed size)
Chèn 1 phần tử vào mảng rất khó
Chèn 1 phần tử vào mảng rất khó
Các phần tử tuần tự theo chỉ số 0
Các phần tử tuần tự theo chỉ số 0
⇒
⇒
n-1
n-1
Truy cập ngẫu nhiên (random access)
Truy cập ngẫu nhiên (random access)
0
1
2 3 4
n-2
n-1
chè
n
7
Cấu trúc dữ liệu động
Cấu trúc dữ liệu động
Danh sách liên kết
Danh sách liên kết
Cấp phát động lúc chạy chương trình
Cấp phát động lúc chạy chương trình
Các phần tử nằm rải rác ở nhiều nơi trong bộ nhớ
Các phần tử nằm rải rác ở nhiều nơi trong bộ nhớ
Kích thước danh sách chỉ bị giới hạn do RAM
Kích thước danh sách chỉ bị giới hạn do RAM
Thao tác thêm xoá đơn giản
Thao tác thêm xoá đơn giản
Insert,
Delete
8
Hướng
Hướng
giải
giải
quyết
quyết
Cần
Cần
xây
xây
dựng
dựng
cấu
cấu
trúc
trúc
dữ
dữ
liệu
liệu
đáp
đáp
ứng
ứng
được
được
các
các
yêu
yêu
cầu
cầu
:
:
Linh
Linh
động
động
hơn
hơn
.
.
Có
Có
thể
thể
thay
thay
đổi
đổi
kích
kích
thước
thước
,
,
cấu
cấu
trúc
trúc
trong
trong
suốt
suốt
thời
thời
gian
gian
sống
sống
.
.
Cấu
Cấu
trúc
trúc
dữ
dữ
liệu
liệu
động
động
.
.
Danh sách liên kết
Danh sách liên kết
( LINKED LIST )
( LINKED LIST )
10
Biến
Biến
không
không
động
động
Biến
Biến
không
không
động
động
(
(
biến
biến
tĩnh
tĩnh
,
,
biến
biến
nửa
nửa
tĩnh
tĩnh
)
)
là
là
những
những
biến
biến
thỏa
thỏa
:
:
Được
Được
khai
khai
báo
báo
tường
tường
minh
minh
,
,
Tồn
Tồn
tại
tại
khi
khi
vào
vào
phạm
phạm
vi
vi
khai
khai
báo
báo
và
và
chỉ
chỉ
mất
mất
khi
khi
ra
ra
khỏi
khỏi
phạm
phạm
vi
vi
này
này
,
,
Được
Được
cấp
cấp
phát
phát
vùng
vùng
nhớ
nhớ
trong
trong
vùng
vùng
dữ
dữ
liệu
liệu
(
(
Data
Data
segment
segment
)
)
hoặc
hoặc
là
là
Stack
Stack
(
(
đối
đối
với
với
biến
biến
nửa
nửa
tĩnh
tĩnh
-
-
các
các
biến
biến
cục
cục
bộ
bộ
).
).
Kích
Kích
thước
thước
không
không
thay
thay
đổi
đổi
trong
trong
suốt
suốt
quá
quá
trình
trình
sống
sống
.
.
Do
Do
được
được
khai
khai
báo
báo
tường
tường
minh
minh
,
,
các
các
biến
biến
không
không
động
động
có
có
một
một
định
định
danh
danh
đã
đã
được
được
kết
kết
nối
nối
với
với
địa
địa
chỉ
chỉ
vùng
vùng
nhớ
nhớ
lưu
lưu
trữ
trữ
biến
biến
và
và
được
được
truy
truy
xuất
xuất
trực
trực
tiếp
tiếp
thông
thông
qua
qua
định
định
danh
danh
đó
đó
.
.
Ví
Ví
dụ
dụ
:
:
int a; // a, b là các biến không động
char b[10];
11
Biến
Biến
động
động
Trong
Trong
nhiều
nhiều
trường
trường
hợp
hợp
,
,
tại
tại
thời
thời
điểm
điểm
biên
biên
dịch
dịch
không
không
thể
thể
xác
xác
định
định
trước
trước
kích
kích
thước
thước
chính
chính
xác
xác
của
của
một
một
số
số
đối
đối
tượng
tượng
dữ
dữ
liệu
liệu
do
do
sự
sự
tồn
tồn
tại
tại
và
và
tăng
tăng
trưởng
trưởng
của
của
chúng
chúng
phụ
phụ
thuộc
thuộc
vào
vào
ngữ
ngữ
cảnh
cảnh
của
của
việc
việc
thực
thực
hiện
hiện
chương
chương
trình
trình
.
.
Các
Các
đối
đối
tượng
tượng
dữ
dữ
liệu
liệu
có
có
đặc
đặc
điểm
điểm
kể
kể
trên
trên
nên
nên
được
được
khai
khai
báo
báo
như
như
biến
biến
động
động
.
.
Biến
Biến
động
động
là
là
những
những
biến
biến
thỏa
thỏa
:
:
Biến
Biến
không
không
được
được
khai
khai
báo
báo
tường
tường
minh
minh
.
.
Có
Có
thể
thể
được
được
cấp
cấp
phát
phát
hoặc
hoặc
giải
giải
phóng
phóng
bộ
bộ
nhớ
nhớ
khi
khi
người
người
sử
sử
dụng
dụng
yêu
yêu
cầu
cầu
.
.
Các
Các
biến
biến
này
này
không
không
theo
theo
qui
qui
tắc
tắc
phạm
phạm
vi
vi
(
(
tĩnh
tĩnh
).
).
Vùng
Vùng
nhớ
nhớ
của
của
biến
biến
được
được
cấp
cấp
phát
phát
trong
trong
Heap
Heap
.
.
Kích
Kích
thước
thước
có
có
thể
thể
thay
thay
đổi
đổi
trong
trong
quá
quá
trình
trình
sống
sống
.
.
12
Biến
Biến
động
động
Do
Do
không
không
được
được
khai
khai
báo
báo
tường
tường
minh
minh
nên
nên
các
các
biến
biến
động
động
không
không
có
có
một
một
định
định
danh
danh
được
được
kết
kết
buộc
buộc
với
với
địa
địa
chỉ
chỉ
vùng
vùng
nhớ
nhớ
cấp
cấp
phát
phát
cho
cho
nó
nó
,
,
do
do
đó
đó
gặp
gặp
khó
khó
khăn
khăn
khi
khi
truy
truy
xuất
xuất
đến
đến
một
một
biến
biến
động
động
.
.
Để
Để
giải
giải
quyết
quyết
vấn
vấn
đề
đề
,
,
biến
biến
con
con
trỏ
trỏ
(
(
là
là
biến
biến
không
không
động
động
)
)
được
được
sử
sử
dụng
dụng
để
để
trỏ
trỏ
đến
đến
biến
biến
động
động
.
.
Khi
Khi
tạo
tạo
ra
ra
một
một
biến
biến
động
động
,
,
phải
phải
dùng
dùng
một
một
con
con
trỏ
trỏ
để
để
lưu
lưu
địa
địa
chỉ
chỉ
của
của
biến
biến
này
này
và
và
sau
sau
đó
đó
,
,
truy
truy
xuất
xuất
đến
đến
biến
biến
động
động
thông
thông
qua
qua
biến
biến
con
con
trỏ
trỏ
đã
đã
biết
biết
định
định
danh
danh
.
.
13
Biến
Biến
động
động
Hai
Hai
thao
thao
tác
tác
cơ
cơ
bản
bản
trên
trên
biến
biến
động
động
là
là
tạo
tạo
và
và
hủy
hủy
một
một
biến
biến
động
động
do
do
biến
biến
con
con
trỏ
trỏ
‘p’
‘p’
trỏ
trỏ
đến
đến
:
:
Tạo
Tạo
ra
ra
một
một
biến
biến
động
động
và
và
cho
cho
con
con
trỏ
trỏ
‘p’
‘p’
chỉ
chỉ
đến
đến
nó
nó
Hủy
Hủy
một
một
biến
biến
động
động
do
do
p
p
chỉ
chỉ
đến
đến
14
Biến
Biến
động
động
Tạo
Tạo
ra
ra
một
một
biến
biến
động
động
và
và
cho
cho
con
con
trỏ
trỏ
‘p’
‘p’
chỉ
chỉ
đến
đến
nó
nó
void* malloc(size);
//
//
trả
trả
về
về
con
con
trỏ
trỏ
chỉ
chỉ
đến
đến
vùng
vùng
nhớ
nhớ
//
//
size
size
byte
byte
vừa
vừa
được
được
cấp
cấp
phát
phát
.
.
void* calloc(n,size);
//
//
trả
trả
về
về
con
con
trỏ
trỏ
chỉ
chỉ
đến
đến
vùng
vùng
nhớ
nhớ
//
//
vừa
vừa
được
được
cấp
cấp
phát
phát
gồm
gồm
n
n
phần
phần
tử
tử
,
,
//
//
mỗi
mỗi
phần
phần
tử
tử
có
có
kích
kích
thước
thước
size
size
byte
byte
new
//
//
toán
toán
tử
tử
cấp
cấp
phát
phát
bộ
bộ
nhớ
nhớ
trong
trong
C
C
++
++
Hàm
Hàm
free
free
(
(
p
p
)
)
huỷ
huỷ
vùng
vùng
nhớ
nhớ
cấp
cấp
phát
phát
bởi
bởi
hàm
hàm
malloc
malloc
hoặc
hoặc
calloc
calloc
do
do
p
p
trỏ
trỏ
tới
tới
Toán
Toán
tử
tử
delete
p
p
huỷ
huỷ
vùng
vùng
nhớ
nhớ
cấp
cấp
phát
phát
bởi
bởi
toán
toán
tử
tử
new
do
do
p
p
trỏ
trỏ
tới
tới
15
Biến
Biến
động
động
–
–
Ví
Ví
dụ
dụ
int *p1, *p2;
// cấp phát vùng nhớ cho 1 biến động kiểu int
p1 = (int*)malloc(sizeof(int));
*p1 = 5; // đặt giá trị 5 cho biến động đang
được p1 quản lý
// cấp phát biến động kiểu mảng gồm 10 phần tử kiểu
int
p2 = (int*)calloc(10, sizeof(int));
*(p2+3) = 0; // đặt giá trị 0 cho phần tử thứ 4
của mảng p2
free(p1);
free(p2);
16
Kiểu
Kiểu
dữ
dữ
liệu
liệu
Con
Con
trỏ
trỏ
Kiểu
Kiểu
con
con
trỏ
trỏ
là
là
kiểu
kiểu
cơ
cơ
sở
sở
dùng
dùng
lưu
lưu
địa
địa
chỉ
chỉ
của
của
một
một
đối
đối
tượng
tượng
dữ
dữ
liệu
liệu
khác
khác
.
.
Biến
Biến
thuộc
thuộc
kiểu
kiểu
con
con
trỏ
trỏ
Tp
Tp
là
là
biến
biến
mà
mà
giá
giá
trị
trị
của
của
nó
nó
là
là
địa
địa
chỉ
chỉ
cuả
cuả
một
một
vùng
vùng
nhớ
nhớ
ứng
ứng
với
với
một
một
biến
biến
kiểu
kiểu
T
T
,
,
hoặc
hoặc
là
là
giá
giá
trị
trị
NULL
NULL
.
.
17
Con
Con
trỏ
trỏ
–
–
Khai
Khai
báo
báo
Cú
Cú
pháp
pháp
định
định
nghĩa
nghĩa
một
một
kiểu
kiểu
con
con
trỏ
trỏ
trong
trong
ngôn
ngôn
ngữ
ngữ
C
C
:
:
typedef <kiểu cơ sở> * < kiểu con trỏ>;
Ví
Ví
dụ
dụ
:
:
typedef int *intpointer;
intpointer p;
hoặc
hoặc
int *p;
là
là
những
những
khai
khai
báo
báo
hợp
hợp
lệ
lệ
.
.
18
Con
Con
trỏ
trỏ
–
–
Thao
Thao
tác
tác
căn
căn
bản
bản
Các
Các
thao
thao
tác
tác
cơ
cơ
bản
bản
trên
trên
kiểu
kiểu
con
con
trỏ
trỏ
:(
:(
minh
minh
họa
họa
bằng
bằng
C
C
)
)
Khi
Khi
1
1
biến
biến
con
con
trỏ
trỏ
p
p
lưu
lưu
địa
địa
chỉ
chỉ
của
của
đối
đối
tượng
tượng
x
x
,
,
ta
ta
nói
nói
‘p
‘p
trỏ
trỏ
đến
đến
x’
x’
.
.
Gán
Gán
địa
địa
chỉ
chỉ
của
của
một
một
vùng
vùng
nhớ
nhớ
con
con
trỏ
trỏ
p
p
:
:
p
p
= <
= <
địa
địa
chỉ
chỉ
>;
>;
ví duï :
ví duï :
int i,*
int i,*
p;
p;
p=&i;
p=&i;
Truy
Truy
xuất
xuất
nội
nội
dung
dung
của
của
đối
đối
tượng
tượng
do
do
p
p
trỏ
trỏ
đến
đến
(*
(*
p
p
)
)
19
Danh
Danh
sách
sách
liên
liên
kết
kết
(
(
List
List
)
)
I.
I.
Định
Định
nghĩa
nghĩa
:
:
Một danh sách (list) là một tập hợp gồm một
Một danh sách (list) là một tập hợp gồm một
số hữu hạn phần tử cùng kiểu, có thứ tự.
số hữu hạn phần tử cùng kiểu, có thứ tự.
Có hai cách cài đặt danh sách là :
Có hai cách cài đặt danh sách là :
Cài đặt theo kiểu kế tiếp : ta có danh sách
Cài đặt theo kiểu kế tiếp : ta có danh sách
kề hay danh sách đặc.
kề hay danh sách đặc.
Cài đặt theo kiểu liên kết : ta có danh sách
Cài đặt theo kiểu liên kết : ta có danh sách
liên kết.
liên kết.
20
Danh
Danh
sách
sách
liên
liên
kết
kết
(
(
List
List
)
)
a.
a.
Danh sách kề :
Danh sách kề :
Các phần tử của danh sách gọi là các node, được lưu trữ
Các phần tử của danh sách gọi là các node, được lưu trữ
kề liền nhau trong bộ nhớ. Mỗi node có thể là một giá
kề liền nhau trong bộ nhớ. Mỗi node có thể là một giá
trò kiểu int, float, char, … hoặc có thể là một struct với
trò kiểu int, float, char, … hoặc có thể là một struct với
nhiều vùng tin. Mảng hay chuỗi là dạng của danh sách
nhiều vùng tin. Mảng hay chuỗi là dạng của danh sách
kề.
kề.
Đòa chỉ của mỗi node trong danh sách được xác đònh
Đòa chỉ của mỗi node trong danh sách được xác đònh
bằng chỉ số (index). Chỉ số của danh sách là một số
bằng chỉ số (index). Chỉ số của danh sách là một số
nguyên và được đánh từ 0 đến một giá trò tối đa nào đó.
nguyên và được đánh từ 0 đến một giá trò tối đa nào đó.
Danh sách kề là cấu trúc dữ liệu tónh, số node tối đa
Danh sách kề là cấu trúc dữ liệu tónh, số node tối đa
của danh sách kề cố đònh sau khi cấp phát nên số node
của danh sách kề cố đònh sau khi cấp phát nên số node
cần dùng có khi thừa hay thiếu. Ngoài ra danh sách kề
cần dùng có khi thừa hay thiếu. Ngoài ra danh sách kề
không phù hợp với các thao tác thường xuyên như thêm
không phù hợp với các thao tác thường xuyên như thêm
hay xóa phần tử trên danh sách,
hay xóa phần tử trên danh sách,
21
Danh
Danh
sách
sách
liên
liên
kết
kết
(
(
List
List
)
)
b.
b.
Danh sách liên kết :
Danh sách liên kết :
Các phần tử của danh sách gọi là node, nằm rải rác
Các phần tử của danh sách gọi là node, nằm rải rác
trong bộ nhớ. Mỗi node, ngoài vùng dữ liệu thông
trong bộ nhớ. Mỗi node, ngoài vùng dữ liệu thông
thường, còn có vùng liên kết chứa đòc chỉ của node kế
thường, còn có vùng liên kết chứa đòc chỉ của node kế
tiếp hay node trước nó.
tiếp hay node trước nó.
Danh sách liên kết là cấu trúc dữ liệu động, có thể
Danh sách liên kết là cấu trúc dữ liệu động, có thể
thêm hay hủy node của danh sách trong khi chay
thêm hay hủy node của danh sách trong khi chay
chương trình. Với cách cài đặt các thao tác thêm hay
chương trình. Với cách cài đặt các thao tác thêm hay
hủy node ta chỉ cần thay đổi lại vùng liên kết cho phù
hủy node ta chỉ cần thay đổi lại vùng liên kết cho phù
hợp.
hợp.
Tuy nhiên, việc lưu trữ danh sách liên kết tốn bộ nhớ
Tuy nhiên, việc lưu trữ danh sách liên kết tốn bộ nhớ
hơn anh sách kề vì mỗi node của danh sách phải chứa
hơn anh sách kề vì mỗi node của danh sách phải chứa
thêm vùng liên kết. Ngoài ra việc truy xuất node thứ I
thêm vùng liên kết. Ngoài ra việc truy xuất node thứ I
trong danh sách liên kết chậm hơn vì phải duyệt từ đầu
trong danh sách liên kết chậm hơn vì phải duyệt từ đầu
danh sách.
danh sách.
22
Có
Có
nhiều
nhiều
kiểu
kiểu
tổ
tổ
chức
chức
liên
liên
kết
kết
giữa
giữa
các
các
phần
phần
tử
tử
trong
trong
danh
danh
sách
sách
như
như
:
:
Danh
Danh
sách
sách
liên
liên
kết
kết
đơn
đơn
Danh
Danh
sách
sách
liên
liên
kết
kết
kép
kép
Danh
Danh
sách
sách
liên
liên
kết
kết
vòng
vòng
…
…
Danh
Danh
sách
sách
liên
liên
kết
kết
(
(
List
List
)
)
23
Danh
Danh
sách
sách
liên
liên
kết
kết
(
(
List
List
)
)
Danh
Danh
sách
sách
liên
liên
kết
kết
đơn
đơn
:
:
mỗi
mỗi
phần
phần
tử
tử
liên
liên
kết
kết
với
với
phần
phần
tử
tử
đứng
đứng
sau
sau
nó
nó
trong
trong
danh
danh
sách
sách
:
:
Danh
Danh
sách
sách
liên
liên
kết
kết
kép
kép
:
:
mỗi
mỗi
phần
phần
tử
tử
liên
liên
kết
kết
với
với
các
các
phần
phần
tử
tử
đứng
đứng
trước
trước
và
và
sau
sau
nó
nó
trong
trong
danh
danh
sách
sách
:
:
A B X Z Y
A B C D
24
Danh
Danh
sách
sách
liên
liên
kết
kết
(
(
List
List
)
)
Danh
Danh
sách
sách
liên
liên
kết
kết
vòng
vòng
:
:
phần
phần
tử
tử
cuối
cuối
danh
danh
sách
sách
liên
liên
kết
kết
với
với
phần
phần
tử
tử
đầu
đầu
danh
danh
sách
sách
:
:
A B X Z Y
A B C D
Danh
Danh
sách liên kết đơn
sách liên kết đơn
(
(
xâu
xâu
đơn
đơn
)
)