You are on page 1of 76

Chương 4

Danh sách liên kết


Nội dung

4.1 Giới
thiệu danh
sách liên
kết

4.2 Danh
sách liên kết
đơn 4.3 Danh
sách liên kết
mở rộng

Cấu trúc dữ liệu - Khoa CNTT 2


4.1 Giới thiệu danh sách liên kết
 Mảng 1 chiều
- Kích thước cố định (fixed size)
- 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 n-1
- Truy cập ngẫu nhiên (random access)

chèn

0 1 2 3 4 n-2 n-1

Cấu trúc dữ liệu - Khoa CNTT 4


4.1 Giới thiệu 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á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
- Thao tác thêm xoá đơn giản

Insert,
Delete

Cấu trúc dữ liệu - Khoa CNTT 5


Cấu trúc dữ liệu - Khoa CNTT 6
4.2 Danh sách liên kết đơn - SLL

Định
nghĩa

Ứng Khai
dụng SLL báo

Thao
tác

Cấu trúc dữ liệu - Khoa CNTT 7


4.2.1 SLL - định nghĩa
 DSLK đơn là chuỗi các node, được tổ chức theo thứ
tự tuyến tính

 Mỗi node gồm 2 phần:


- Phần Data, information => info
- Phần link hay con trỏ trỏ đến node kế tiếp => next

info next

Node

Cấu trúc dữ liệu - Khoa CNTT 8


SLL – Ôn pointer
 Nhắc lại pointer
1FF0 1FF4
int i, *pi; i ? pi ?

i 1FF0 1FF4
pi = &i; *pi ? pi 1FF0

i 1FF0 1FF4
i = 10 or *pi = 10 *pi 10 pi 1FF0

Cấu trúc dữ liệu - Khoa CNTT 9


SLL – Minh hoạ
 Mô tả DSLK info next

A1 A2 A3 An

null
Node Tail Node
pHead

pHead
Danh sách rỗng

null
Cấu trúc dữ liệu - Khoa CNTT 10
SLL – Minh họa
 VD:
Địa chỉ

pHead 700 500


700 ‘D’ 500 ‘S’ 600

600 300
‘L’ 300 ‘D’ null

Cấu trúc dữ liệu - Khoa CNTT 11


4.2.2 SLL – Khai báo
 Khai báo DSLK - DataType
- Kiểu dữ liệu định nghĩa trước
- Chứa dữ liệu, thông tin của từng node
typedef struct
{
char Ten[30];
char MaSv[10];
DateTime NgaySinh;
typedef struct float diem;
} SinhVien;
{ int ngay;
int thang;
int nam;
} DateTime;

Cấu trúc dữ liệu - Khoa CNTT 12


4.2.2 SLL – Khai báo
 Khai báo DSLK - DataType
- Kiểu dữ liệu định nghĩa trước
- Chứa dữ liệu, thông tin của từng node

typedef struct
{
char Ten[30];
char MaSv[10];
int Gioitinh;
float diem;
} SinhVien;

Cấu trúc dữ liệu - Khoa CNTT 13


4.2.2 SLL – Khai báo
typedef struct node
{ Cấu trúc
DataType info; node
node* next;
} NODE;

typedef struct node typedef struct node


{ {
int info; SinhVien info;
node* next; node* next;
} NODE; }NODE;

Cấu trúc dữ liệu - Khoa CNTT 14


4.2.2 SLL – Khai báo
 Khai báo và khởi tạo danh sách liên kết đơn

typedef struct node


{
int info;
node* next;
}NODE;
typedef NODE * NodePtr;

NodePtr pHead; pHead quản lý ds

Cấu trúc dữ liệu - Khoa CNTT 15


4.2.3. SLL – Các thao tác
 Các thao tác cơ bản
Phần minh
- Init
hoạ sẽ dùng
- IsEmpty
- ShowList DataType là
int
 Bổ sung 1 phần tử mới vào danh sách
- InsertFirst - InsertAfter
- InsertLast - InsertBefore
 Loại bỏ 1 phần tử khỏi danh sách
- DeleteFirst - DeleteAfter - DeleteNode
- DeleteLast - DeleteBefore - DeleteAll
 Các thao tác khác
- Search
- Sort

Cấu trúc dữ liệu - Khoa CNTT 16


4.2.3 SLL – Các thao tác
 Init: khởi tạo danh sách, ban đầu chưa có phần tử

1. void Init(NodePtr &pHead)

2. {

3. *pHead = NULL;

4. }

Cấu trúc dữ liệu - Khoa CNTT 17


4.2.3 SLL - Các thao tác
 IsEmpty: kiểm tra danh sách rỗng

1. int IsEmpty(NodePtr pHead)


2. {
3. if (pHead == NULL)
4. return 1;
5. else
6. return 0;
7. }

Cấu trúc dữ liệu - Khoa CNTT 18


4.2.3 SLL – Các thao tác
 ShowList: duyệt toàn bộ danh sách
- Duyệt từ đầu danh sách
- Đến khi nào hết danh sách thì dừng
1. void ShowList(NodePtr pHead)
2. { NodePtr p; //p là con trỏ để duyệt
3. p = pHead; //duyệt từ đầu danh sách
4. while (p!=NULL)//khi chưa hết ds
5. {
6. ShowNode(p); //tác động lên nút
7. p = p->next; //chuyển nút sau
8. }
9. }
Cấu trúc dữ liệu - Khoa CNTT 19
4.2.3 SLL - Các thao tác
 ShowNode:

1. void ShowNode (NodePtr q)


2. {
3. cout<< q -> info<<“\t”;
4. }

Cấu trúc dữ liệu - Khoa CNTT 20


4.2.3 SLL – Các thao tác
 Bổ sung:
- Tạo nút mới
- Nối vào danh sách
Tạo nút mới
NodePtr node; //node là con trỏ trỏ nút mới
node = new NODE;//xin cấp phát địa chỉ
node -> info = x;

Cấu trúc dữ liệu - Khoa CNTT 21


4.2.3 SLL – Các thao tác
 Bổ sung vào đầu danh sách InsertFirst
node new
pHead pHead

node node
pHead pHead

Cấu trúc dữ liệu - Khoa CNTT 22


4.2.3 SLL – Các thao tác
 InsertFirst: bổ sung nút có nội dung x vào đầu ds
1. void InsertFirst(NodePtr &pHead, int x)
2. { //tạo nút mới
3. NodePtr node;
4. node = new NODE;
5. node->info = x;
6. //nối vào danh sách
7. node->next = pHead;//noi node vao truoc pHead
8. pHead = node;//node thanh nut dau danh sach
9.}

Cấu trúc dữ liệu - Khoa CNTT 23


4.2.3 SLL – Các thao tác
 Bổ sung vào sau nút p - InsertLast
p new
pHead node
x

node node
p p

Cấu trúc dữ liệu - Khoa CNTT 24


4.2.3 SLL – Các thao tác
 InsertLast: thêm node có nội dung x vào cuối ds
1. void InsertLast(NodePtr &pHead, int x)
2. { //tao nut moi
3. NodePtr node;
4. node = new NODE;
5. node->info = x;
6. node -> next = NULL;
7. //noi vao danh sach
8. if (pHead == NULL)
9. pHead = node;

Cấu trúc dữ liệu - Khoa CNTT 25


4.2.3 SLL – Các thao tác
 InsertLast: thêm node có nội dung x vào cuối ds
10. else
11. { // tim den nut cuoi
12. NodePtr p;
13. p = pHead;
14. while (p -> next != NULL)
15. p = p->next;
16. // noi vao cuoi danh sach
17. p ->next = node;
18. }
19.}
Cấu trúc dữ liệu - Khoa CNTT 26
4.2.3 SLL – Các thao tác
 Bổ sung vào sau nút p - InsertAfter
node new
pHead p

node node
p p

Cấu trúc dữ liệu - Khoa CNTT 27


4.2.3 SLL – Các thao tác
 InsertAfter: thêm node có nội dung x sau node p
1. void InsertAfter(NodePtr &pHead,NodePtr &p, int x)
2. { if (p == NULL)
3. cout<<“Cannot insert new node!”;
4. else
5. { //tao nut moi
6. NodePtr node;
7. node = new NODE;
8. node->info = x;
9. //noi vao danh sach
10. node->next = p->next;
11. p->next = node; }
12.}
Cấu trúc dữ liệu - Khoa CNTT 28
4.2.3 SLL – Các thao tác
 InsertBefore: thêm node có nội dung x trước node p
1. void InsertBefore(NodePtr &pHead,NodePtr &p, int x)
2. { if (p == NULL) cout<<“Cannot insert new node!”;
3. else
4. { //tao nut moi
5. NodePtr node;
6. node = new NODE;
7. node->info = x;
8. //tim den nut truoc p
9. NodePtr q = pHead;
10. while (q -> next != p)
11. q = q -> next;

Cấu trúc dữ liệu - Khoa CNTT 29


4.2.3 SLL – Các thao tác
 InsertAfter: thêm node có nội dung x sau node p
1. //noi vao truoc p
2. q -> next = node; //noi q voi node
3. node -> next = p; //noi node voi p
4. }
5. }

Cấu trúc dữ liệu - Khoa CNTT 30


4.2.3 SLL – Các thao tác
 Loại bỏ phần tử đầu danh sách DeleteFirst

pHead pHead

p p
pHead pHead

p
Cấu trúc dữ liệu - Khoa CNTT 31
4.2.3 SLL – Các thao tác
 DeleteFirst: loại bỏ node đầu tiên của danh sách
1. void DeleteFirst(NodePtr &pHead)
2. { NodePtr p;
3. if (IsEmpty(pHead))
4. cout<<“List is empty!”;
5. else
6. { p = pHead;
7. pHead = pHead->next;
8. delete p;
9. }
10.}

Cấu trúc dữ liệu - Khoa CNTT 32


4.2.3 SLL – Các thao tác
 Loại bỏ phần tử cuối danh sách DeleteLast

pHead

q p p
pHead q

Cấu trúc dữ liệu - Khoa CNTT 33


4.2.3 SLL – Các thao tác
 DeleteLast: xoá node cuối trong danh sách
1. void DeleteLast(NodePtr &pHead)
2. { if (pHead == NULL)
3. cout<<“List is empty!”;
4. else
5. { NodePtr p, q; //p tim den nut cuoi, q truoc nut p
6. p = pHead -> next; q = pHead;
7. while (p -> next != NULL)
8. { p = p->next;
9. q = q->next;
10. }
11. delete p;
12. q -> next = NULL; } //end if
13.}
Cấu trúc dữ liệu - Khoa CNTT 34
4.2.3 SLL – Các thao tác
 Loại bỏ phần tử sau nút p - DeleteAfter

pHead q

p
q pHead

p
Cấu trúc dữ liệu - Khoa CNTT 35
4.2.3 SLL – Các thao tác
 DeleteAfter: xoá node sau node p trong danh sách
1. void DeleteAfter(NodePtr &pHead, NodePtr &p)
2. { NodePtr q;
3. if (p->next == NULL)
4. cout<<“Cannot delete node!”;
5. else
6. {
7. q = p->next; //q tro nut sau p
8. p->next = q->next;
9. delete q; //giai phong nut sau p
10. }
11.}
Cấu trúc dữ liệu - Khoa CNTT 36
4.2.3 SLL – Các thao tác
 Loại bỏ phần tử trước nút p - DeleteBefore

pHead r q

p
pHead r q

p
Cấu trúc dữ liệu - Khoa CNTT 37
4.2.3 SLL – Các thao tác
 Loại bỏ phần tử được trỏ bởi p - DeleteNode

pHead

q
pHead p
q

p
Cấu trúc dữ liệu - Khoa CNTT 38
4.2.3 SLL – Các thao tác
 DeleteNode: xoá node p trong danh sách
1. void DeleteNode(NodePtr &pHead, NodePtr &p)
2. { if (p == NULL)
3. cout<<“Cannot delete node!”;
4. else
5. { NodePtr q = pHead;
6. while (q->next !=p)
7. q = q->next;
8. q->next = p->next;
9. delete p;
10. }
11.}
Cấu trúc dữ liệu - Khoa CNTT 39
4.2.3 SLL – Các thao tác
 DeleteAll: xoá toàn bộ danh sách
1. void DeleteAll(NodePtr &pHead)
2. {
3. NodePtr p;
4. while (pHead!=NULL)
5. {
6. p = pHead;
7. pHead = pHead -> next;
8. delete p;
9. }
10.}

Cấu trúc dữ liệu - Khoa CNTT 40


4.2.3 SLL – Tìm kiếm
 Search:
- Xuất phát từ đầu danh sách
- Nếu tìm thấy trả về địa chỉ nút đó
- Ngược lại qua phần tử tiếp theo
- Điều kiện dừng khi hết danh sách thì dừng
- Không tìm thấy trả về NULL

Cấu trúc dữ liệu - Khoa CNTT 41


4.2.3 SLL – Các thao tác
 Search: Tìm kiếm phần tử x trong danh sách
1. NodePtr Search(NodePtr pHead, int x)
2. { if (pHead == NULL) return NULL;
3. NodePtr p; //p để duyệt và tìm
4. p = pHead; //tìm từ đầu ds
5. while ( p != NULL && p->info != x)
6. p = p->next;
7. return p;
8. }

Cấu trúc dữ liệu - Khoa CNTT 42


4.2.3 SLL – Các thao tác
 Sắp xếp ds theo thứ tự tăng dần, dùng Selection Sort
1. void Sort(NodePtr &pHead)
2. { NodePtr q, min, p = pHead;
3. while (p!=NULL)
4. { min = p; q = p -> next;
5. while (q!=NULL)
6. { if (q->info < min->info)
7. min = q;
8. q = q->next;
9. }
10. swap(p->info, min->info);
11. p = p->next;
12. }
13.}
Cấu trúc dữ liệu - Khoa CNTT 43
4.2.4 SLL - Ứng dụng
Bài toán
Cộng hai đa thức P(x) = anxn + an-1 xn-1 +... +a1x1 + a0
Lưu trữ
Một đa thức được biểu diễn dưới dạng danh sách nối đơn,
mỗi số hạng của đa thức được lưu trữ bởi phần tử nhớ có
quy cách:
COEF EXP NEXT

Trường COEF chứa hệ số khác không của một số hạng


trong đa thức.
Trường EXP chứa số mũ tương ứng.
Trường NEXT chứa mối nối tới nút tiếp theo.

Cấu trúc dữ liệu - Khoa CNTT 44


4.2.4 SLL - Ứng dụng
Ví dụ đa thức A(x) = 4x10 - 2x3 + 6 sẽ được biểu diễn bởi:
A

4 10 -2 3 6 0

Cấu trúc dữ liệu - Khoa CNTT 45


4.2.4 SLL – Ứng dụng
 Khai báo một số hạng của đa thức

typedef struct node


{
int coef;
int exp;
node * next;
}NODE;
typedef NODE * NodePtr;

NodePtr L; L trỏ đầu đa thức

Cấu trúc dữ liệu - Khoa CNTT 46


4.2.4 SLL - Ứng dụng
Như vậy đa thức A(x) = 4x10 - 2x3 + 6 sẽ được biểu diễn
bởi: A

4 10 -2 3 6 0

Đa thức B(x) = - 6x10 + 8x6 +2x3 + 5x, sẽ biểu diễn bởi:


B

-6 10 8 6 2 3 5 1

Phép cộng hai đa thức:

C
C(x) = A(x) + B(x) = -2x10 + 8x6 +5x +6

-2 10 8 6 5 1 6 0

Cấu trúc dữ liệu - Khoa CNTT 47


Câu hỏi củng cố bài
1. Cho 2 con trỏ p và q, p trỏ vào một nút bất kỳ trong
danh sách (không phải nút đầu). Lệnh nào dưới đây
là đúng để con trỏ q trỏ vào nút trước p?

A. q = pHead; B. q = pHead;
while (q -> next != p) while (q != p)
q = q -> next; q = q -> next;

C. q = NULL; D. q!= NULL;

Cấu trúc dữ liệu - Khoa CNTT 54


Câu hỏi củng cố bài
2. Cho danh sách nối đơn có nhiều hơn một phần tử
được quản lý bởi con trỏ pHead, trường info chứa số
nguyên dương. Chọn đoạn code đếm số phần tử chia
hết cho 5 trong danh sách?
A. int dem=0; B. int dem=0;
NodePtr p; NodePtr p;
p = pHead; p =pHead;
while (p!=NULL) { while (p!=NULL) {
if (p->info % 5 == 0) dem++; if (p->info % 5== 0) dem;
p = p->next; } p = p->next; }
return dem; return dem;

C. int dem=0; D. int dem=1;


NodePtr p; NodePtr p;
p =pHead; p = pHead;
while (p!=NULL) { while (p!=NULL) {
if (p->info %5 !=0) dem++; if (p->info %5 !== 0) dem++;
p = p->next; } p = p->next; }
return dem; return dem;

Cấu trúc dữ liệu - Khoa CNTT 55


Câu hỏi củng cố bài
3. Nếu có một con trỏ p thuộc kiểu NodePtr trỏ vào một
nút hợp lệ trong danh sách, các lệnh nào sau đây sẽ
thực hiện loại bỏ nút sau p trong danh sách?

A. p->next = p->next->next; B. tmp = p -> next;

delete p -> next; p -> next = tmp -> next;

delete tmp;

C. tmp = p->next->next; D. tmp = p -> next;

p -> next = p->next->next; tmp -> next = p -> next;

delete tmp; delete tmp;

Cấu trúc dữ liệu - Khoa CNTT 56


Câu hỏi củng cố bài
4. Cho danh sách nối đơn, p là con trỏ trỏ vào đầu danh
sách có nhiều hơn một phần tử. Đoạn lệnh dưới đây
thực hiện chèn nút q vào cuối danh sách nói trên.
NodePtr temp;
temp = p;
while (**A**)
**B**;
temp->next = q;
Câu lệnh nào sẽ điền vào vị trí A?
A. temp ->next != NULL
B. temp ->next != p
C. temp ->next != q
D. temp != NULL
Cấu trúc dữ liệu - Khoa CNTT 57
Câu hỏi củng cố bài
5. Cho danh sách nối đơn, p là con trỏ trỏ vào đầu danh
sách có nhiều hơn một phần tử. Đoạn lệnh dưới đây
thực hiện chèn nút q vào cuối danh sách nói trên.
NodePtr temp;
temp = p;
while (**A**)
**B**;
temp->next = q;
Câu lệnh nào sẽ điền vào vị trí B?
A. p = p ->next;
B. temp++;
C. temp = temp.next;
D. temp = temp -> next;
Cấu trúc dữ liệu - Khoa CNTT 58
Câu hỏi củng cố bài
6. Cho danh sách nối đơn, p là con trỏ trỏ vào
đầu danh sách có nhiều hơn một phần tử.
Lệnh nào dưới đây có tác dụng di chuyển nút
đầu danh sách?

A. p++;

B. p = p->next;

C. p->next = p->next->next

D. while (p != NULL) p=p->next;

Cấu trúc dữ liệu - Khoa CNTT 59


Câu hỏi củng cố bài
 Câu hỏi trắc nghiệm
1. Làm thế nào để thêm nút r vào đầu danh sách nối đơn có nút
đầu trỏ bởi p?

A. r->next=p; C. p = r;
r->next = NULL;
B. r -> next = p; D. p->next=r;
p = r;
60
Câu hỏi củng cố bài
 Câu hỏi trắc nghiệm
2. Làm thế nào để xóa nút ở đầu danh sách nối đơn có nút đầu
được trỏ bởi p?

A. p = p->next; C. NodePtr r;
r = p;
p = p->next;
delete p;
B. NodePtr r; D. NodePtr r;
r = p; r = p;
p=p->next; r = r->next; 61
Câu hỏi củng cố bài
 Câu hỏi trắc nghiệm
3. Làm thế nào để thêm nút r vào cuối danh sách nối đơn có nút
đầu trỏ bởi p?

A. NodePtr temp; C. NodePtr temp;

temp = p; temp = p;

while (temp->next!=NULL) while (temp->next!=NULL)

temp = temp -> next; { temp=temp->next;

temp->next = r; temp->next=r;

r->next=NULL; }

B. NodePtr temp; r->next=NULL;

temp = p; D. while (p->next!=NULL)


62
Tổng kết Định nghĩa Là chuỗi các nút được tổ chức theo thứ tự
tuyến tính

Cấu trúc 1 nút


info next
Mô tả
Node

typedef struct node


{ int info;
Khai báo
Danh sách struct node * next;
liên kết đơn } NODE;
typedef NODE* NodePtr;
NodePtr pHead;

Cơ bản
Các thao Init, IsEmpty, ShowList
tác Bổ sung
InsertFirst, InsertLast, InsertAfter, InsertBefore
Loại bỏ
DeleteFirst, DeleteLast, DeleteAfter,
DeleteBefore, DeleteNode, DeleteAll
Khác
Search, Sort

Cấu trúc dữ liệu - Khoa CNTT 64


SLL– Bài tập
1. Cho một danh sách nối đơn có nút đầu được trỏ bởi
pHead. Trường info của các nút chứa giá trị nguyên.Viết
giải thuật thực hiện các công việc sau:
a. Đếm số nút của danh sách
b. Bổ sung một nút mới với thông tin x vào làm nút thứ k
trong danh sách
c. Loại bỏ nút có giá trị y trong danh sách
d. Tìm và in ra các nút chia 5 dư 2 trong danh sách

Cấu trúc dữ liệu - Khoa CNTT 65


SLL – Bài tập
 Đếm số nút của danh sách CountList

pHead d=0

int d = 0;

p NodePtr p = pHead;
while ( p != NULL)
{ d++;
p = p -> next;
}
return d;

Cấu trúc dữ liệu - Khoa CNTT 66


SLL – Bài tập
 CountList: đếm số phần tử của danh sách
int CountList(NodePtr pHead)
{ int d = 0;
NodePtr p; //p là con trỏ để duyệt
p = pHead; //duyệt từ đầu danh sách
while (p!=NULL)//khi chưa hết ds
{
d++; //tăng biến đếm
p = p->next; //chuyển nút sau
}
return d;
}
Cấu trúc dữ liệu - Khoa CNTT 67
SLL – Bài tập
 Bổ sung vào làm nút thứ k - Insert_k
node new
pHead d=0

q node
p
pHead
d=k

q p
Cấu trúc dữ liệu - Khoa CNTT 68
SLL – Bài tập
 Insert_k: thêm node có nội dung x vào cuối ds
void Insert_k(NodePtr &pHead, int k, int x)
{ //tao nut moi
NodePtr node;
node = new NODE;
node->info = x;
//noi vao danh sach
int d = 0; //bien d de dem so nut
NodePtr p, q; //con tro duyet ds
p = pHead -> next; q = pHead;

Cấu trúc dữ liệu - Khoa CNTT 69


SLL – Bài tập
 Insert_k:
while (d != k)
{ d++;
p = p -> next;
q = q -> next;
}
// nối node vào giữa q và p
q -> next = node;
node -> next = p;
}

Cấu trúc dữ liệu - Khoa CNTT 70


SLL – Bài tập
 Loại bỏ nút có giá trị y – Delete_y
pHead q p

pHead q p

Cấu trúc dữ liệu - Khoa CNTT 71


SLL– Bài tập
 Loại bỏ nút có giá trị y trong danh sách
void Delete_y(NodePtr pHead, int y)
{ NodePtr p; //p để duyệt và tìm
p = pHead; //tìm từ đầu ds
while ( p != NULL && p->info != y)
p = p->next;
if (p == NULL) return;

if (p== pHead) DeleteFirst(pHead);

else
Cấu trúc dữ liệu - Khoa CNTT 72
SLL– Bài tập
 Loại bỏ nút có giá trị y trong danh sách

{ NodePtr q = pHead;
while (q -> next != p)
q = q -> next;
q -> next = p -> next;
delete p;
}
}

Cấu trúc dữ liệu - Khoa CNTT 73


SLL – Bài tập
 Tìm in ra các phần tử chia cho 5 dư 2
void ShowDivide(NodePtr pHead)
{
NodePtr p; //p là con trỏ để duyệt
p = pHead; //duyệt từ đầu danh sách
while (p != NULL)
{ if (p -> info % 5 == 2)
ShowNode(p);
p = p->next;
}
}

Cấu trúc dữ liệu - Khoa CNTT 74


SLL– Bài tập
2. Cho một danh sách nối đơn có nút đầu được trỏ bởi
pHead. Trường info của các nút chứa giá trị nguyên.Viết
giải thuật thực hiện các công việc sau:
a. Bổ sung một nút mới với thông tin x vào cuối danh sách
b. Loại bỏ nút trước nút p bất kỳ trong danh sách
c. Tìm và in ra các nút chia hết cho 7 trong danh sách

Cấu trúc dữ liệu - Khoa CNTT 75


SLL – Bài tập
 InsertLast: thêm node có nội dung x vào cuối ds
void InsertLast(NodePtr &pHead, int x)
{ NodePtr node;
node = new NODE;
node->info = x;
node -> next =null;
//noi vao danh sach
if (pHead == NULL)
pHead = node;

Cấu trúc dữ liệu - Khoa CNTT 76


SLL – Bài tập
 InsertLast: thêm node có nội dung x vào cuối ds
else {
// tìm đến nút cuối
NodePtr p;
p = pHead;
while (p -> next != NULL)
p = p->next;
// nối vào cuối ds
p ->next = node;
}
}
Cấu trúc dữ liệu - Khoa CNTT 77
SLL – Bài tập
 Loại bỏ phần tử trước nút p - DeleteBefore
r q
pHead

p
r q
pHead

p
Cấu trúc dữ liệu - Khoa CNTT 78
SLL – Bài tập
void DeleteBefore(NodePtr &pHead, NodePtr &p)
{ if (p == NULL)
cout<<“Cannot delete node!”;
else
{ NodePtr q, r; //con tro de duyet ds
r = pHead; q = pHead -> next;
while ( q -> next != p)
{ q = q -> next; r = r -> next; }
r -> next = p;
delete q;
}
}
Cấu trúc dữ liệu - Khoa CNTT 79
SLL – Bài tập
 Tìm in ra các phần tử chia hết cho 7
void ShowDivide(NodePtr pHead)
{
NodePtr p; //p là con trỏ để duyệt
p = pHead; //duyệt từ đầu danh sách
while (p != NULL && p -> info % 7 == 0)
{
ShowNode(p); //tác động lên nút
p = p->next; //chuyển nút sau
}
}

Cấu trúc dữ liệu - Khoa CNTT 80


SLL– Bài tập
3. Cho một danh sách nối đơn có nút đầu được trỏ bởi
pHead. Trường info của các nút chứa giá trị nguyên.Viết
giải thuật thực hiện các công việc sau:
a. Bổ sung một nút mới với thông tin x vào trước nút p bất
kỳ trong danh sách
b. Loại bỏ nút cuối danh sách
c. Cho một số nguyên y. Tìm xem trong danh sách có nút
nào mà trường info = y hay không? Nếu tìm thấy trả về
địa chỉ của nút đó, nếu không tìm thấy trả về NULL.

Cấu trúc dữ liệu - Khoa CNTT 81


SLL– Bài tập
4. Viết chương trình C++ thực hiện việc cộng 2 đa thức một
biến A(x) và B(x) sử dụng danh sách liên kết đơn.
5. Viết chương trình C++ thực hiện việc in ra menu chọn
thực hiện các thao tác trên danh sách liên kết đơn.

Cấu trúc dữ liệu - Khoa CNTT 82


Tài liệu tham khảo
[1]. Giáo trình Cấu trúc dữ liệu và giải thuật – Lê Văn
Vinh, NXB Đại học quốc gia TP HCM, 2013
[2]. Cấu trúc dữ liệu & thuật toán, Đỗ Xuân Lôi, NXB
Đại học quốc gia Hà Nội, 2010.
[3]. Trần Thông Quế, Cấu trúc dữ liệu và thuật toán
(phân tích và cài đặt trên C/C++), NXB Thông tin và
truyền thông, 2018
[4]. Robert Sedgewick, Cẩm nang thuật toán, NXB
Khoa học kỹ thuật, 2004 .
[5]. PGS.TS Hoàng Nghĩa Tý, Cấu trúc dữ liệu và
thuật toán, NXB xây dựng, 2014

Cấu trúc dữ liệu - Khoa CNTT 83


Cấu trúc dữ liệu - Khoa CNTT 84

You might also like