You are on page 1of 15

Chương 4: Mảng và Danh

sách liên kết ( tiếp)


DANH SÁCH MÓC NỐI ĐƠN

Mỗi phần tử của danh sách đơn là một cấu trúc chứa 2 thông
tin:
an

-   Thành phần dữ liệu: lưu trữ các thông tin về bản thân phần
tử .

-   Thành phần mối liên kết: lưu trữ địa chỉ của phần tử kế
tiếp trong danh sách, hoặc lưu trữ giá trị NULL nếu là phần
tử cuối danh sách.
DANH SÁCH MÓC NỐI ĐƠN

Cách quản lý: Nếu biết được địa chỉ của phần tử đầu tiên trong
danh sách thì có thể dựa vào thành phần mối liên kết của phần
tử đó để truy xuất đến phần tử thứ 2 trong xâu, và lại dựa vào
thành phần mối liên kết của phần tử thứ 2 để truy xuất đến
phần tử thứ 3...
Bổ sung một phần tử vào DSMN đơn
INSERT(L, Q, X)
{
/* Cho L là con trỏ, trỏ tới nút đầu tiên của một danh sách móc nối
đơn, Q là con trỏ trỏ tới một nút đang có trong danh sách.
Giải thuật này thực hiện bổ sung vào sau nút trỏ bởi Q một nút mới
mà thành phần DATA nhận giá trị X */
P= malloc(); // cấp phát bộ nhớ - tạo một nút mới)
P->DATA=X;
P->NEXT= NULL;
if (L == NULL) // Danh sách rỗng
L= P;
else
{
P->NEXT= Q->NEXT;
Q->NEXT= P;
}
}
Bổ sung một phần tử vào DSMN đơn
L = NULL L ≠ NULL
Loại bỏ một nút khỏi DSMN đơn
DELETE(L, Q)
{ /* Cho danh sách móc nối đơn trỏ bởi L. Giải thuật này thực hiện loại bỏ nút trỏ bởi Q ra khỏi danh
sách đó */
if (L == NULL) printf (“Danh sách rỗng”); // Trường hợp danh sách rỗng
else
if (Q == L) // Loại bỏ nút đầu tiên của danh sách
{
L= Q->NEXT; // Loại bỏ nút trỏ bởi Q
free(Q); // giải phóng vùng nhớ của nút mà Q trỏ vào
}
else
{
// Tìm đến nút đứng trước nút trỏ bởi Q
P = L;
while (P->NEXT != Q)
P = P->NEXT;
P->NEXT = Q->NEXT; // Loại bỏ nút trỏ bởi Q
free(Q);
}
}
Ghép hai DSMN đơn
COMBINE (P, Q)
{/* Cho hai danh sách móc nối đơn lần lượt trỏ bởi P và Q. Giải thuật này thực hiện ghép hai danh sách trên
thành một danh sách (ghép Q vào cuối P) */
if (Q != NULL) // Q khác rỗng mới tiến hành ghép
if (P == NULL) // Trường hợp danh sách trỏ bởi P rỗng
P= Q;
else
{
// Tìm đến nút cuối danh sách P
P1 = P;
while (P1->NEXT != NULL)
P1 = P1->NEXT;
P1->NEXT = Q; // Ghép danh sách Q vào cuối P
}
Áp dụng: Biểu diễn đa thức trong bài toán
cộng hai đa thức (tr 71 – giáo trình)
Danh sách móc nối vòng
• Là cải tiến của danh sách móc nối đơn
• Phần NEXT của nút cuối cùng trỏ vào phần tử đầu tiên
Danh sách móc nối vòng
• Nhược điểm: Không biết chỗ kết thúc danh sách  dẫn tới lặp vô hạn
• Giải pháp: Đưa một nút đặc biệt gọi là nút đầu danh sách. Thành phần
Data của nút không chứa dữ liệu của phần tử nào.
Danh sách móc nối kép
• Cấu trúc 1 nút: Data, P_L, P_R
Bổ sung một nút vào ds móc nối kép
DOUBLE_IN (L, R, Q, X) // bổ sung nút chứa dl X vào trước nút trỏ bởi Q; L,R trỏ tới nút trái cùng phải cùng của DS
{
P= malloc(); // 1- Tạo nút mới
P->DATA=X;
P->P_R= P->P_L= NULL;
if (R == NULL) // 2- Trường hợp danh sách rỗng
L = R = P;
else
if (Q == L) // 3- Q trỏ tới nút cực trái
{
P->P_R = Q;
Q->P_L = P;
L = P;
}
else // 4- Bổ sung vào giữa
{
P->P_L = Q->P_L;
P->P_R = Q;
Q->P_L = P;
P->P_L->P_R = P;
}
}
Xóa một nút vào ds móc nối kép
DOUBLE_DEL (L, R, Q) // Xóa nút được trỏ bởi Q ra khỏi danh sách
{
if (R == NULL) printf(“Danh sách rỗng”); // 1- Trường hợp danh sách rỗng
else // 2- Loại bỏ
{
if (L== R) // Danh sách chỉ có một nút và Q trỏ tới nút đó
L = R = NULL;
else
if (Q == L) // Nút cực trái bị loại
{L = L->P_R; L->P_L = NULL; }
else
if (M == R) // Nút cực phải bị loại
{R= R->P_L; R->P_R = NULL; }
else // Loại bỏ nút bên trong
{
Q->P_L->P_R = Q->P_R;
Q->P_R->P_L = Q->P_L;
}
free(Q);
}
}
Danh sách móc nối kép theo kiểu nối vòng
• Đọc thêm giáo trình trang 78
Xây dựng ngăn xếp hàng đợi sử dụng DS móc
nối
• Ngăn xếp:
• Nếu sử dụng DS móc nối đơn trỏ bởi L để biểu diễn ngăn xếp  Coi L trỏ vào
đỉnh ngăn xếp
Push, pop một phần tử từ ngăn xếp giống như them, xóa một phần tử đầu
ds.
• Hàng đợi:
• Sử dụng DSMN đơn trỏ bằng L, coi L trỏ vào lối ra  Thêm vào 1 phần tử thì
phải tìm đến cuối DS
• Có thể sử dụng DSMN kép để lưu trữ  Hai đầu ứng với đầu ra và đầu vào

You might also like