SlideShare a Scribd company logo
1 of 69
CHAPTER 3: DANH SÁCH LIÊN KẾT
(LINKED LISTS)
Chương 3: Danh sách liên kết
Nội dung
 Giới thiệu
 Danh sách liên kết đơn (Single Linked List)
 Danh sách liên kết đôi (Double Linked List)
 Danh sách liên kết vòng (Circular Linked List)
2
Chương 3: Danh sách liên kết
Giới thiệu - Cấu trúc dữ liệu tĩnh
 Cấu trúc dữ liệu tĩnh:
 Khái niệm: Các đối tượng dữ liệu không thay đổi được kích
thước, cấu trúc, … trong suốt quá trình sống thuộc về kiểu 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 dựng từ
các kiểu cơ sở như: kiểu số thực, kiểu số nguyên, kiểu ký tự ...
hoặc từ các cấu trúc đơn giản như mẩu tin, tập hợp, mảng ...
3
Chương 3: Danh sách liên kết
Giới thiệu - Cấu trúc dữ liệu tĩnh
 Một số hạn chế của CTDL tĩnh:
 Một số đối tượng dữ liệu trong chu kỳ sống của nó có thể thay
đổi về cấu trúc, độ lớn,…
 Ví dụ như danh sách các học viên trong một lớp học có thể tăng
thêm, giảm đi ... Nếu dùng những cấu trúc dữ liệu tĩnh đã biết như
mảng để biểu diễn  Những thao tác phức tạp, kém tự nhiên 
chương trình khó đọc, khó bảo trì và nhất là khó có thể sử dụng bộ
nhớ một cách có hiệu quả
 Dữ liệu tĩnh sẽ chiếm vùng nhớ đã dành cho chúng suốt quá
trình hoạt động của chương trình  sử dụng bộ nhớ kém hiệu
quả
4
Chương 3: Danh sách liên kết
Giới thiệu – Ví dụ cấu trúc dữ liệu tĩnh
 Cấu trúc dữ liệu tĩnh: Ví dụ: Mảng 1 chiều
 Kích thước cố định (fixed size)
 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 1 phần tử vào mảng, xóa 1 phần tử khỏi mảng tốn nhiều chi
phí
5
0 1 2 3 4 n-2 n-1
chèn
Chương 3: Danh sách liên kết
Giới thiệu - Cấu trúc dữ liệu động
 Cần xây dựng cấu trúc dữ liệu đáp ứng được các yêu cầu:
 Linh động hơn
 Có thể thay đổi kích thước, cấu trúc trong suốt thời gian sống
 Cấu trúc dữ liệu động
6
Chương 3: Danh sách liên kết
Giới thiệu - Cấu trúc dữ liệu động
 Cấu trúc dữ liệu động: Ví dụ: Danh sách liên kết, cây
 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
 Tốn bộ nhớ hơn (vì phải chứa thêm vùng liên kết)
 Khó truy cập ngẫu nhiên
 Thao tác thêm, xoá đơn giản
7
Insert,
Delete
Chương 3: Danh sách liên kết
Giới thiệu - Danh sách liên kết
 Danh sách liên kết:
 Mỗi phần tử của danh sách gọi là node (nút)
 Mỗi node có 2 thành phần: phần dữ liệu và phần liên kết
(phần liên kết chứa địa chỉ của node kế tiếp hay node
trước nó)
 Các thao tác cơ bản trên danh sách liên kết:
 Thêm một phần tử mới
 Xóa một phần tử
 Tìm kiếm
 …
8
Chương 3: Danh sách liên kết
Giới thiệu - Danh sách liên kết
 Có nhiều kiểu tổ chức liên kết giữa các phần tử trong danh
sách như:
 Danh sách liên kết đơn
 Danh sách liên kết kép
 Danh sách liên kết vòng
9
Chương 3: Danh sách liên kết
Giới thiệu - Danh sách liên kết
 Danh sách liên kết đơn: mỗi phần tử liên kết với phần tử
đứng sau nó trong danh sách:
 Danh sách liên kết kép: mỗi phần tử liên kết với các phần
tử đứng trước và sau nó trong danh sách:
10
A B X Z Y
A B C D
Chương 3: Danh sách liên kết
Giới thiệu - Danh sách liên kết
11
 Danh sách liên kết vòng : phần tử cuối danh sách liên kết
với phần tử đầu danh sách:
A B X Z Y
A B C D
Chương 3: Danh sách liên kết
Nội dung
 Giới thiệu
 Danh sách liên kết đơn (Single Linked List)
 Danh sách liên kết kép (Doule Linked List)
 Danh sách liên kết vòng (Circular Linked List)
12
Chương 3: Danh sách liên kết
Danh sách liên kết đơn (DSLK đơn)
 Khai báo
 Các thao tác cơ bản trên DSLK đơn
 Sắp xếp trên DSLK đơn
13
Chương 3: Danh sách liên kết
DSLK đơn – Khai báo
 Là danh sách các node mà mỗi node có 2 thành phần:
 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
 Khai báo node:
struct Node
{
DataType data; // DataType là kiểu đã định nghĩa trước
Node *pNext; // con trỏ chỉ đến cấu trúc Node
};
14
data
pNext
Node* tên_nút;
Chương 6: Danh sách liên kết
DSLK đơn – Khai báo
 Ví dụ 1: Khai báo node lưu số
nguyên:
struct Node
{
int data;
Node *pNext;
};
 Ví dụ 2: Khai báo node lưu
thông tin của một sinh viên:
struct SinhVien {
char Ten[30];
int MaSV;
};
struct Node {
SinhVien data;
Node *pNext;
};
15
Chương 3: Danh sách liên kết
DSLK đơn – Khai báo
 Tổ chức, quản lý:
 Để quản lý một DSLK đơn chỉ cần biết địa chỉ phần tử đầu
danh sách
 Con trỏ pHead sẽ được dùng để lưu trữ địa chỉ phần tử đầu
danh sách. Ta có khai báo:
Node *pHead;
 Để tiện lợi, có thể sử dụng thêm một con trỏ pTail giữ địa chỉ
phần tử cuối danh sách. Khai báo pTail như sau:
Node *pTail;
16
A B X Z Y
pHead
pTail
A
Chương 3: Danh sách liên kết
DSLK đơn – Khai báo
 Ví dụ: Khai báo cấu trúc 1 DSLK đơn chứa số nguyên
// kiểu của một phần tử trong danh sách
struct Node
{
int data;
Node* pNext;
};
// kiểu danh sách liên kết
struct List
{
Node* pHead;
Node* pTail;
};
17
Khai báo biến kiểu danh sách:
List tên_biến;
Chương 3: Danh sách liên kết
DSLK đơn – Khai báo
 Tạo một node mới
 Viết hàm getNode để tạo ra một nút cho danh sách với dữ
liệu là x
18
Node* getNode ( DataType x)
{
Node *p;
p = new Node; // Cấp phát vùng nhớ cho node
if (p==NULL)
{
cout<<“Khong du bo nho!”; return NULL;
}
p->data = x; // Gán dữ liệu cho phần tử p
p->pNext = NULL;
return p;
}
x
p
Chương 3: Danh sách liên kết
Danh sách liên kết đơn (DSLK đơn)
 Khai báo
 Các thao tác cơ bản trên DSLK đơn
 Sắp xếp trên DSLK đơn
19
Chương 3: Danh sách liên kết
DSLK đơn
 Các thao tác cơ bản
 Tạo danh sách rỗng
 Thêm một phần tử vào danh sách
 Duyệt danh sách
 Tìm kiếm
 Xóa một phần tử ra khỏi danh sách
 Hủy toàn bộ danh sách
 …
20
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Tạo danh sách rỗng
21
pHead
pTail
void Init(List &l)
{
l.pHead = l.pTail = NULL;
}
Chương 3: Danh sách liên kết
DSLK đơn
 Các thao tác cơ bản
 Tạo danh sách rỗng
 Thêm một phần tử vào danh sách
 Duyệt danh sách
 Tìm kiếm một giá trị trên danh sách
 Xóa một phần tử ra khỏi danh sách
 Hủy toàn bộ danh sách
 …
22
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Thêm một phần tử vào danh sách: Có 3 vị trí thêm
 Gắn vào đầu danh sách
 Gắn vào cuối danh sách
 Chèn vào sau nút q trong danh sách
 Chú ý trường hợp danh sách ban đầu rỗng
23
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Thêm một phần tử
 Nếu danh sách ban đầu rỗng
24
pHead
pTail
new_node
XpHead = pTail = new_node;
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Thêm một phần tử
 Gắn node vào đầu danh sách
25
A B C D E
pHead pTail
X
new_node
new_node->pNext = pHead;
pHead = new_node;
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Cài đặt: Gắn nút vào đầu DS
26
void addHead(List &l, Node* new_node)
{
if (l.pHead == NULL) // DS rỗng
{
l.pHead = l.pTail = new_node;
}
else
{
new_node->pNext = l.pHead;
l.pHead = new_node;
}
}
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Thuật toán: Thêm một thành phần dữ liệu vào đầu DS
// input: danh sách l
// output: danh sách l với phần tử chứa X ở đầu DS
 Nhập dữ liệu cho X (???)
 Tạo nút mới chứa dữ liệu X (???)
 Nếu tạo được:
 Gắn nút mới vào đầu danh sách (???)
27
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Ví dụ: Thêm một số nguyên vào đầu ds:
// Nhập dữ liệu cho X
int x;
cout<<“Nhap X=”;
cin>>x;
// Tạo nút mới
Node* new_node = getNode(x);
// Gắn nút vào đầu ds
if (new_node != NULL)
addHead(l, new_node);
28
43
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Thêm một phần tử vào danh sách: Có 3 vị trí thêm
 Gắn vào đầu danh sách
 Gắn vào cuối danh sách
 Chèn vào sau nút q trong danh sách
 Chú ý trường hợp danh sách ban đầu rỗng
29
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Thêm một phần tử
 Gắn node vào cuối danh sách:
30
A B C D E
pHead
pTail
X
new_node
pTail->pNext = new_node;
pTail = new_node;
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Cài đặt: Gắn nút vào cuối DS
31
void addTail(List &l, Node *new_node)
{
if (l.pHead == NULL)
{
l.pHead = l.pTail = new_node;
}
else
{
l.pTail->pNext = new_node;
l.pTail = new_node ;
}
}
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Ví dụ: Thêm một số nguyên vào cuối ds:
// Nhập dữ liệu cho X
int x;
cout<<“Nhập X=”;
cin>>x;
// Tạo nút mới
Node* p = getNode(x);
// Gắn nút vào cuối DS
if (p != NULL)
addTail(l, p);
32
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Thêm một phần tử vào danh sách: Có 3 vị trí thêm
 Gắn vào đầu danh sách
 Gắn vào cuối danh sách
 Chèn vào sau nút q trong danh sách
 Chú ý trường hợp danh sách ban đầu rỗng
33
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Thêm một phần tử
 Chèn một phần tử vào sau nút q
34
A B C D E
pHead
pTail
X
new_node
q
new_node -> pNext = q -> pNext;
q -> pNext = new_node ;
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Cài đặt: Chèn một phần tử vào sau nút q
35
void addAfter (List &l, Node *q, Node* new_node)
{
if (q!=NULL)
{
new_node->pNext = q->pNext;
q->pNext = new_node;
if (q==l.pTail)
l.pTail = new_node;
}
}
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Thuật toán: Thêm một thành phần dữ liệu vào sau q
// input: danh sách thành phần dữ liệu X
// output: danh sách với phần tử chứa X ở cuối DS
 Nhập dữ liệu cho nút q (???)
 Tìm nút q (???)
 Nếu tồn tại q trong ds thì:
 Nhập dữ liệu cho X (???)
 Tạo nút mới chứa dữ liệu X (???)
 Nếu tạo được:
 Gắn nút mới vào sau nút q (???)
 Ngược lại thì báo lỗi
36
Chương 3: Danh sách liên kết
DSLK đơn
 Các thao tác cơ bản
 Tạo danh sách rỗng
 Thêm một phần tử vào danh sách
 Duyệt danh sách
 Tìm kiếm một giá trị trên danh sách
 Xóa một phần tử ra khỏi danh sách
 Hủy toàn bộ danh sách
 …
37
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Duyệt danh sách
 Là thao tác thường được thực hiện khi có nhu cầu muốn lấy lần
lượt từng phần tử trong danh sách để xử lý, chẳng hạn xử lý:
 Xuất các phần tử trong danh sách
 Đếm các phần tử trong danh sách
 Tính tổng các phần tử trong danh sách
 Tìm tất cả các phần tử danh sách thoả điều kiện nào đó
 Hủy toàn bộ danh sách (và giải phóng bộ nhớ)
 …
38
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Duyệt danh sách
 Bước 1: p = pHead; //Cho p trỏ đến phần tử đầu danh sách
 Bước 2: Trong khi (chưa hết danh sách) thực hiện:
 B2.1 : Xử lý phần tử p
 B2.2 : p=p->pNext; // Cho p trỏ tới phần tử kế
39
Node *p = l.pHead;
while ( p!=NULL )
{
// xử lý cụ thể p tùy ứng dụng
p = p->pNext;
}
Chuyển
thành vòng
lặp for??
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Ví dụ: In các phần tử trong danh sách
40
void Output (List l)
{
Node* p=l.pHead;
while (p!=NULL)
{
cout<<p->data<<“t”;
p=p->pNext;
}
cout<<endl;
}
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Đếm số nút trong danh sách:
41
int CountNodes (List l)
{
int count = 0;
Node *p = l.pHead;
while (p!=NULL)
{
count++;
p = p->pNext;
}
return count;
}
Gọi hàm???
Chương 3: Danh sách liên kết
DSLK đơn
 Các thao tác cơ bản
 Tạo danh sách rỗng
 Thêm một phần tử vào danh sách
 Duyệt danh sách
 Tìm kiếm một giá trị trên danh sách
 Xóa một phần tử ra khỏi danh sách
 Hủy toàn bộ danh sách
 …
42
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
43
 Tìm kiếm một phần tử có khóa x
Node* Search (List l, int x)
{
Node* p = l.pHead;
while ( p!=NULL ) {
if ( p->data==x )
return p;
p=p->pNext;
}
return NULL;
}
Gọi hàm???
Chương 3: Danh sách liên kết
DSLK đơn
 Các thao tác cơ bản
 Tạo danh sách rỗng
 Thêm một phần tử vào danh sách
 Duyệt danh sách
 Tìm kiếm một giá trị trên danh sách
 Xóa một phần tử ra khỏi danh sách
 Hủy toàn bộ danh sách
 …
44
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Xóa một node của danh sách
 Xóa node đầu danh sách
 Xóa node sau node q trong danh sách
 Xóa node có khoá k
45
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Thuật toán: Xóa node đầu danh sách
 Bước 1: Nếu danh sách rỗng thì không xóa được và thoát
ct, ngược lại qua Bước 2
 Bước 2: Gọi p là node đầu của danh sách (p=pHead)
 Bước 3: Cho pHead trỏ vào node sau node p (pHead =p->pNext)
 Bước 4: Nếu không còn node nào thì pTail = NULL
 Bước 5: Giải phóng vùng nhớ mà p trỏ tới
46
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Minh họa: Xóa node đầu danh sách
47
A B C D E
pHead
pTail
p
pHead = p->pNext;
delete p;
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
// xóa được: hàm trả về 1
// xóa không được: hàm trả về 0
int removeHead (List &l){
if (l.pHead == NULL)
return 0;
Node* p=l.pHead;
l.pHead = p->pNext;
if (l.pHead == NULL) l.pTail=NULL; //Nếu danh sách rỗng
delete p;
return 1;
}
48
Cài đặt: Xóa node đầu danh sách
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Xóa một node của danh sách
 Xóa node đầu danh sách
 Xóa node sau node q trong danh sách
 Xóa node có khoá k
49
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Thuật toán: Xóa node sau node q trong danh sách:
 Điều kiện để có thể xóa được node sau q là:
 q phải khác NULL (q !=NULL)
 Node sau q phải khác NULL (q->pNext !=NULL)
 Thuật toán:
 Bước 1: Gọi p là node sau q
 Bước 2: Cho q trỏ vào node đứng sau p
 Bước 3: Nếu p là phần tử cuối thì pTail là q
 Bước 4: Giải phóng vùng nhớ mà p trỏ tới
50
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Minh họa: Xóa node sau node q trong danh sách
51
A B C D E
pHead
pTail
q p
q->pNext = p->pNext;
delete p;
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Cài đặt: Xóa node sau node q trong danh sách
52
// xóa được: hàm trả về 1
// xóa không được: hàm trả về 0
int removeAfter (List &l, Node* q ){
if (q !=NULL && q->pNext !=NULL) {
Node* p = q->pNext;
q->pNext = p->pNext;
if (p==l.pTail) l.pTail = q;
delete p;
return 1;
}
else return 0;
}
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Xóa một node của danh sách
 Xóa node đầu của danh sách
 Xóa node sau node q trong danh sách
 Xóa node có khoá k
53
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
Thuật toán: Xóa 1 node có khoá k
 Bước 1:
 Tìm node có khóa k (gọi là p) và node đứng trước nó (gọi
là q)
 Bước 2:
 Nếu (p!= NULL) thì // tìm thấy k
 Hủy p ra khỏi danh sách: tương tự hủy phần tử sau q
 Ngược lại
 Báo không có k
54
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Cài đặt:
Xóa 1
node có
khoá k
55
int removeNode (List &l, int k)
{
Node *p = l.pHead;
Node *q = NULL;
while (p != NULL)
{
if (p->data == k) break;
q = p;
p = p->pNext;
}
if (p == NULL) { cout<<“Không tìm thấy k”; return 0;}
else if (q == NULL)
// thực hiện xóa phần tử đầu ds là p
else
// thực hiện xóa phần tử p sau q
}
Tìm phần tử p có khóa k và
phần tử q đứng trước nó
A B C D E
pHead
pTail
Chương 3: Danh sách liên kết
DSLK đơn
 Các thao tác cơ bản
 Tạo danh sách rỗng
 Thêm một phần tử vào danh sách
 Duyệt danh sách
 Tìm kiếm một giá trị trên danh sách
 Xóa một phần tử ra khỏi danh sách
 Hủy toàn bộ danh sách
 …
56
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Hủy toàn bộ danh sách
 Để hủy toàn bộ danh sách, thao tác xử lý bao gồm hành động giải
phóng một phần tử, do vậy phải cập nhật các liên kết liên quan:
 Thuật toán:
 Bước 1: Trong khi (chưa hết danh sách) thực hiện:
 B1.1:
 p = pHead;
 pHead = pHead ->pNext; // Cho p trỏ tới phần tử kế
 B1.2:
 Hủy p;
 Bước 2:
 pTail = NULL; //Bảo đảm tính nhất quán khi xâu rỗng
57
Chương 3: Danh sách liên kết
DSLK đơn – Các thao tác cơ sở
 Cài đặt: Hủy toàn bộ danh sách
58
void RemoveList (List &l)
{
Node *p;
while (l.pHead!=NULL)
{
p = l.pHead;
l.pHead = p->pNext;
delete p;
}
l.pTail = NULL;
}
Gọi hàm???
Chương 3: Danh sách liên kết
Danh sách liên kết đơn (DSLK đơn)
 Khai báo
 Các thao tác cơ bản trên DSLK đơn
 Sắp xếp trên DSLK đơn
59
Chương 3: Danh sách liên kết
Sắp xếp trên DSLK đơn
 Các cách tiếp cận:
 Phương án 1: Hoán vị nội dung các phần tử trong danh
sách (thao tác trên vùng data)
 Sử dụng thêm vùng nhớ trung gian  thích hợp cho DSLK
với thành phần data có kích thước nhỏ
 Phương án 2: Thay đổi các mối liên kết (thao tác trên vùng
pNext)
 Phức tạp hơn
60
Chương 3: Danh sách liên kết
Sắp xếp trên DSLK đơn: Hoán vị data
 Cài đặt bằng pp đổi chỗ trực tiếp (Interchange Sort)
void InterChangeSort (List &l)
{
for (Node* p=l.pHead; p!=l.pTail; p=p->pNext)
for (Node* q=p->pNext; q!=NULL; q=q->pNext)
if (p->data > q->data)
Swap (p->data, q->data);
}
61
Chương 3: Danh sách liên kết
Sắp xếp trên DSLK đơn: Hoán vị data
62
12 2 8 1 5
p
q
l.pHead
l.pTail
Chương 3: Danh sách liên kết
Sắp xếp trên DSLK đơn: Hoán vị data
63
1 12 8 2 5
p
q
l.pHead
l.pTail
Chương 3: Danh sách liên kết
64
1 2 12 8 5
p
q
l.pHead
l.pTail
Sắp xếp trên DSLK đơn: Hoán vị data
Chương 3: Danh sách liên kết
65
1 2 5 12 8
p
q
l.pHead
l.pTail
Sắp xếp trên DSLK đơn: Hoán vị data
Chương 3: Danh sách liên kết
66
1 2 5 8 12
p
q
ng
l.pHead
l.pTail
Sắp xếp trên DSLK đơn: Hoán vị data
Chương 3: Danh sách liên kết
Sắp xếp bằng pp chọn trực tiếp
(Selection sort)
void ListSelectionSort (List &l)
{
for ( Node* p = l.pHead ; p != l.pTail ; p = p->pNext )
{
Node* min = p;
for ( Node* q = p-> pNext; q != NULL ; q = q-> pNext )
if ( min->data > q->data ) min = q ;
Swap(min->data, p->data);
}
}
67
Chương 3: Danh sách liên kết
Sắp xếp trên DSLK đơn: Thay đổi liên kết
 Một trong những cách thay đổi liên kết đơn giản nhất là
tạo một danh sách mới là danh sách có thứ tự từ danh
sách cũ (GT.101)
 Bước 1: Khởi tạo danh sách mới Result là rỗng;
 Bước 2: Tìm phần tử nhỏ nhất min trong danh sách cũ l;
 Bước 3: Tách min khỏi danh sách l;
 Bước 4: Chèn min vào cuối danh sách Result;
 Bước 5: Lặp lại bước 2 khi chưa hết danh sách cũ l;
68
69
void SortList( List &l ){
List lResult;
Init( lResult );
Node *p,*q, *min, *minprev;
while( l.pHead != NULL ){
min = l.pHead;
q = min->pNext;
p = l.pHead;
minprev = NULL;
while ( q != NULL )
{
if (min->data >q->data ) {
min = q;
minprev = p;
}
p = q;
q = q->pNext;
}
if ( minprev != NULL )
minprev->pNext = min->pNext;
else
l.pHead = min->pNext;
min->pNext = NULL;
addTail( lResult, min );
}
l = lResult;
}
5 4 3 9
minminprev

More Related Content

What's hot

Cây và cây nhị phân
Cây và cây nhị phân Cây và cây nhị phân
Cây và cây nhị phân kikihoho
 
Hệ thống quản lý rạp chiếu phim
Hệ thống quản lý          rạp chiếu phimHệ thống quản lý          rạp chiếu phim
Hệ thống quản lý rạp chiếu phimvennguyennoinho
 
Lap trinh-huong-doi-tuong-bang-c#
Lap trinh-huong-doi-tuong-bang-c#Lap trinh-huong-doi-tuong-bang-c#
Lap trinh-huong-doi-tuong-bang-c#Thanhlanh nguyen
 
Báo cáo môn đảm bảo chất lượng phần mềm
Báo cáo môn đảm bảo chất lượng phần mềmBáo cáo môn đảm bảo chất lượng phần mềm
Báo cáo môn đảm bảo chất lượng phần mềmThuyet Nguyen
 
Bai tap va loi giai sql
Bai tap va loi giai sqlBai tap va loi giai sql
Bai tap va loi giai sql. .
 
Báo cáo dự án quản lí thư viện
Báo cáo dự án quản lí thư việnBáo cáo dự án quản lí thư viện
Báo cáo dự án quản lí thư việnQuân Không Quần
 
Thực tập kiểm thử phần mềm
Thực tập kiểm thử phần mềmThực tập kiểm thử phần mềm
Thực tập kiểm thử phần mềmNguyễn Anh
 
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư việnThe Nguyen Manh
 
Slide báo cáo đồ án tốt nghiệp "Website cửa hàng điện thoại trực tuyến"
Slide báo cáo đồ án tốt nghiệp "Website cửa hàng điện thoại trực tuyến"Slide báo cáo đồ án tốt nghiệp "Website cửa hàng điện thoại trực tuyến"
Slide báo cáo đồ án tốt nghiệp "Website cửa hàng điện thoại trực tuyến"Tú Cao
 
Phân tích thiết kế hệ thống của hàng bán điện thoại di động
Phân tích thiết kế hệ thống của hàng bán điện thoại di độngPhân tích thiết kế hệ thống của hàng bán điện thoại di động
Phân tích thiết kế hệ thống của hàng bán điện thoại di độngNguyễn Danh Thanh
 
Bai 1 tong quan ve ctdl&amp;gt
Bai 1   tong quan ve ctdl&amp;gtBai 1   tong quan ve ctdl&amp;gt
Bai 1 tong quan ve ctdl&amp;gtTrangThu251076
 
Bai13-Cau truc du lieu va giai thuat - Cay (Tree)
Bai13-Cau truc du lieu va giai thuat - Cay (Tree)Bai13-Cau truc du lieu va giai thuat - Cay (Tree)
Bai13-Cau truc du lieu va giai thuat - Cay (Tree)iwanttoit
 
Đảm bảo chất lượng phầm mềm (nguồn PTIT)
Đảm bảo chất lượng phầm mềm (nguồn PTIT)Đảm bảo chất lượng phầm mềm (nguồn PTIT)
Đảm bảo chất lượng phầm mềm (nguồn PTIT)Thuyet Nguyen
 
Chuẩn hóa lược đồ quan hệ
Chuẩn hóa lược đồ quan hệChuẩn hóa lược đồ quan hệ
Chuẩn hóa lược đồ quan hệHưởng Nguyễn
 
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 1
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 1Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 1
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 1pisu412
 

What's hot (20)

Cây và cây nhị phân
Cây và cây nhị phân Cây và cây nhị phân
Cây và cây nhị phân
 
Hệ thống quản lý rạp chiếu phim
Hệ thống quản lý          rạp chiếu phimHệ thống quản lý          rạp chiếu phim
Hệ thống quản lý rạp chiếu phim
 
Cây Nhị Phân
Cây Nhị PhânCây Nhị Phân
Cây Nhị Phân
 
Lap trinh-huong-doi-tuong-bang-c#
Lap trinh-huong-doi-tuong-bang-c#Lap trinh-huong-doi-tuong-bang-c#
Lap trinh-huong-doi-tuong-bang-c#
 
29421864 cosodulieu02
29421864 cosodulieu0229421864 cosodulieu02
29421864 cosodulieu02
 
Báo cáo môn đảm bảo chất lượng phần mềm
Báo cáo môn đảm bảo chất lượng phần mềmBáo cáo môn đảm bảo chất lượng phần mềm
Báo cáo môn đảm bảo chất lượng phần mềm
 
Bai tap va loi giai sql
Bai tap va loi giai sqlBai tap va loi giai sql
Bai tap va loi giai sql
 
Báo cáo dự án quản lí thư viện
Báo cáo dự án quản lí thư việnBáo cáo dự án quản lí thư viện
Báo cáo dự án quản lí thư viện
 
Thực tập kiểm thử phần mềm
Thực tập kiểm thử phần mềmThực tập kiểm thử phần mềm
Thực tập kiểm thử phần mềm
 
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
 
Báo Cáo Bài Tập Lớn Môn Lập Trình Web Xây Dựng Website Tin Tức
Báo Cáo Bài Tập Lớn Môn Lập Trình Web Xây Dựng Website Tin TứcBáo Cáo Bài Tập Lớn Môn Lập Trình Web Xây Dựng Website Tin Tức
Báo Cáo Bài Tập Lớn Môn Lập Trình Web Xây Dựng Website Tin Tức
 
Slide báo cáo đồ án tốt nghiệp "Website cửa hàng điện thoại trực tuyến"
Slide báo cáo đồ án tốt nghiệp "Website cửa hàng điện thoại trực tuyến"Slide báo cáo đồ án tốt nghiệp "Website cửa hàng điện thoại trực tuyến"
Slide báo cáo đồ án tốt nghiệp "Website cửa hàng điện thoại trực tuyến"
 
Phân tích thiết kế hệ thống của hàng bán điện thoại di động
Phân tích thiết kế hệ thống của hàng bán điện thoại di độngPhân tích thiết kế hệ thống của hàng bán điện thoại di động
Phân tích thiết kế hệ thống của hàng bán điện thoại di động
 
Bai 1 tong quan ve ctdl&amp;gt
Bai 1   tong quan ve ctdl&amp;gtBai 1   tong quan ve ctdl&amp;gt
Bai 1 tong quan ve ctdl&amp;gt
 
Luận văn: Ứng dụng kỹ thuật học máy vào phát hiện mã độc, 9đ
Luận văn: Ứng dụng kỹ thuật học máy vào phát hiện mã độc, 9đLuận văn: Ứng dụng kỹ thuật học máy vào phát hiện mã độc, 9đ
Luận văn: Ứng dụng kỹ thuật học máy vào phát hiện mã độc, 9đ
 
Bai13-Cau truc du lieu va giai thuat - Cay (Tree)
Bai13-Cau truc du lieu va giai thuat - Cay (Tree)Bai13-Cau truc du lieu va giai thuat - Cay (Tree)
Bai13-Cau truc du lieu va giai thuat - Cay (Tree)
 
Đảm bảo chất lượng phầm mềm (nguồn PTIT)
Đảm bảo chất lượng phầm mềm (nguồn PTIT)Đảm bảo chất lượng phầm mềm (nguồn PTIT)
Đảm bảo chất lượng phầm mềm (nguồn PTIT)
 
Bai tp dap_an_mo_hinh_toan_kinh_t
Bai tp dap_an_mo_hinh_toan_kinh_tBai tp dap_an_mo_hinh_toan_kinh_t
Bai tp dap_an_mo_hinh_toan_kinh_t
 
Chuẩn hóa lược đồ quan hệ
Chuẩn hóa lược đồ quan hệChuẩn hóa lược đồ quan hệ
Chuẩn hóa lược đồ quan hệ
 
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 1
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 1Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 1
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 1
 

Viewers also liked

Ky thuatkhudequy
Ky thuatkhudequyKy thuatkhudequy
Ky thuatkhudequyHồ Lợi
 
CTDL&GT: Các loại danh sách liên kết
CTDL&GT: Các loại danh sách liên kếtCTDL&GT: Các loại danh sách liên kết
CTDL&GT: Các loại danh sách liên kếtVan-Duyet Le
 
Programming technique 1_2_7921
Programming technique 1_2_7921Programming technique 1_2_7921
Programming technique 1_2_7921tienhien110293
 
Cach giai bai tap ham de quy minh tim duoc
Cach giai bai tap ham de quy minh tim duocCach giai bai tap ham de quy minh tim duoc
Cach giai bai tap ham de quy minh tim duochcmavano
 
Chuong 2. de quy dai hoc
Chuong 2. de quy   dai hocChuong 2. de quy   dai hoc
Chuong 2. de quy dai hocVũ Nam
 
Chuong 05 de quy
Chuong 05 de quyChuong 05 de quy
Chuong 05 de quyCau Chu Nho
 
Bài 7: Danh sách liên kết (LINKED LIST) và tập hợp (SET) - Giáo trình FPT
Bài 7: Danh sách liên kết (LINKED LIST) và tập hợp (SET) - Giáo trình FPTBài 7: Danh sách liên kết (LINKED LIST) và tập hợp (SET) - Giáo trình FPT
Bài 7: Danh sách liên kết (LINKED LIST) và tập hợp (SET) - Giáo trình FPTMasterCode.vn
 

Viewers also liked (8)

Ky thuatkhudequy
Ky thuatkhudequyKy thuatkhudequy
Ky thuatkhudequy
 
CTDL&GT: Các loại danh sách liên kết
CTDL&GT: Các loại danh sách liên kếtCTDL&GT: Các loại danh sách liên kết
CTDL&GT: Các loại danh sách liên kết
 
Programming technique 1_2_7921
Programming technique 1_2_7921Programming technique 1_2_7921
Programming technique 1_2_7921
 
Giao trinh ky thuat lap trinh 2
Giao trinh ky thuat lap trinh 2Giao trinh ky thuat lap trinh 2
Giao trinh ky thuat lap trinh 2
 
Cach giai bai tap ham de quy minh tim duoc
Cach giai bai tap ham de quy minh tim duocCach giai bai tap ham de quy minh tim duoc
Cach giai bai tap ham de quy minh tim duoc
 
Chuong 2. de quy dai hoc
Chuong 2. de quy   dai hocChuong 2. de quy   dai hoc
Chuong 2. de quy dai hoc
 
Chuong 05 de quy
Chuong 05 de quyChuong 05 de quy
Chuong 05 de quy
 
Bài 7: Danh sách liên kết (LINKED LIST) và tập hợp (SET) - Giáo trình FPT
Bài 7: Danh sách liên kết (LINKED LIST) và tập hợp (SET) - Giáo trình FPTBài 7: Danh sách liên kết (LINKED LIST) và tập hợp (SET) - Giáo trình FPT
Bài 7: Danh sách liên kết (LINKED LIST) và tập hợp (SET) - Giáo trình FPT
 

Similar to C3 danh sachlienket

Danh sách liên kết là 1 cấu trúc dữ liệu được sử dụng để lưu trữ 1 tập hợp cá...
Danh sách liên kết là 1 cấu trúc dữ liệu được sử dụng để lưu trữ 1 tập hợp cá...Danh sách liên kết là 1 cấu trúc dữ liệu được sử dụng để lưu trữ 1 tập hợp cá...
Danh sách liên kết là 1 cấu trúc dữ liệu được sử dụng để lưu trữ 1 tập hợp cá...trantungminh4034
 
Cau truc dl_va_giai_thuat_bai1[1] - copy
Cau truc dl_va_giai_thuat_bai1[1] - copyCau truc dl_va_giai_thuat_bai1[1] - copy
Cau truc dl_va_giai_thuat_bai1[1] - copyNguyen Van Hung
 
Cấu trúc dữ liệu kiểu danh sách liên kết
Cấu trúc dữ liệu kiểu danh sách liên kếtCấu trúc dữ liệu kiểu danh sách liên kết
Cấu trúc dữ liệu kiểu danh sách liên kếthotro
 
Bài tập CTDL và GT 5
Bài tập CTDL và GT 5Bài tập CTDL và GT 5
Bài tập CTDL và GT 5Hồ Lợi
 
Cấu trúc dữ liệu cơ bản 2
Cấu trúc dữ liệu cơ bản 2Cấu trúc dữ liệu cơ bản 2
Cấu trúc dữ liệu cơ bản 2Hồ Lợi
 
ctdl&amp;gt 04-list_don
ctdl&amp;gt 04-list_donctdl&amp;gt 04-list_don
ctdl&amp;gt 04-list_donkikihoho
 
C3 stack queue
C3 stack queueC3 stack queue
C3 stack queuehiep0109
 
Giới thiệu Đại số quan hệ Phép toán tập hợp Phép chọn Phép chiếu Phép tích Ca...
Giới thiệu Đại số quan hệ Phép toán tập hợp Phép chọn Phép chiếu Phép tích Ca...Giới thiệu Đại số quan hệ Phép toán tập hợp Phép chọn Phép chiếu Phép tích Ca...
Giới thiệu Đại số quan hệ Phép toán tập hợp Phép chọn Phép chiếu Phép tích Ca...BangNgoVanCong
 
Chuong 4-Thiet ke du lieu.pdf
Chuong 4-Thiet ke du lieu.pdfChuong 4-Thiet ke du lieu.pdf
Chuong 4-Thiet ke du lieu.pdfEcCrm
 
Thuật toán Brich , Khai phá dữ liệu
Thuật toán Brich , Khai phá dữ liệu Thuật toán Brich , Khai phá dữ liệu
Thuật toán Brich , Khai phá dữ liệu Lương Bá Hợp
 
Ctdl c4-cay
Ctdl c4-cayCtdl c4-cay
Ctdl c4-cayhiep0109
 
Ctdl c4-cay
Ctdl c4-cayCtdl c4-cay
Ctdl c4-cayutteoteo
 
Bài 2 Làm quen với môi trường PHP và MySQL (phần 2) - Giáo trình FPT
Bài 2 Làm quen với môi trường PHP và MySQL (phần 2) - Giáo trình FPTBài 2 Làm quen với môi trường PHP và MySQL (phần 2) - Giáo trình FPT
Bài 2 Làm quen với môi trường PHP và MySQL (phần 2) - Giáo trình FPTMasterCode.vn
 
Cap nhat CSDL trong VB.NET
Cap nhat CSDL trong VB.NETCap nhat CSDL trong VB.NET
Cap nhat CSDL trong VB.NETANHMATTROI
 
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT.pptx
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT.pptxCẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT.pptx
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT.pptxVuDuong69
 
Bai5 dsachlket
Bai5 dsachlketBai5 dsachlket
Bai5 dsachlketHồ Lợi
 
Bài tập CTDL và GT 12
Bài tập CTDL và GT 12Bài tập CTDL và GT 12
Bài tập CTDL và GT 12Hồ Lợi
 

Similar to C3 danh sachlienket (20)

C5 danhsachlienket
C5 danhsachlienketC5 danhsachlienket
C5 danhsachlienket
 
Danh sách liên kết là 1 cấu trúc dữ liệu được sử dụng để lưu trữ 1 tập hợp cá...
Danh sách liên kết là 1 cấu trúc dữ liệu được sử dụng để lưu trữ 1 tập hợp cá...Danh sách liên kết là 1 cấu trúc dữ liệu được sử dụng để lưu trữ 1 tập hợp cá...
Danh sách liên kết là 1 cấu trúc dữ liệu được sử dụng để lưu trữ 1 tập hợp cá...
 
Cau truc dl_va_giai_thuat_bai1[1] - copy
Cau truc dl_va_giai_thuat_bai1[1] - copyCau truc dl_va_giai_thuat_bai1[1] - copy
Cau truc dl_va_giai_thuat_bai1[1] - copy
 
Cấu trúc dữ liệu kiểu danh sách liên kết
Cấu trúc dữ liệu kiểu danh sách liên kếtCấu trúc dữ liệu kiểu danh sách liên kết
Cấu trúc dữ liệu kiểu danh sách liên kết
 
Bài tập CTDL và GT 5
Bài tập CTDL và GT 5Bài tập CTDL và GT 5
Bài tập CTDL và GT 5
 
Cấu trúc dữ liệu cơ bản 2
Cấu trúc dữ liệu cơ bản 2Cấu trúc dữ liệu cơ bản 2
Cấu trúc dữ liệu cơ bản 2
 
ctdl&amp;gt 04-list_don
ctdl&amp;gt 04-list_donctdl&amp;gt 04-list_don
ctdl&amp;gt 04-list_don
 
CHƯƠNG 3.pdf
CHƯƠNG 3.pdfCHƯƠNG 3.pdf
CHƯƠNG 3.pdf
 
C3 stack queue
C3 stack queueC3 stack queue
C3 stack queue
 
Giới thiệu Đại số quan hệ Phép toán tập hợp Phép chọn Phép chiếu Phép tích Ca...
Giới thiệu Đại số quan hệ Phép toán tập hợp Phép chọn Phép chiếu Phép tích Ca...Giới thiệu Đại số quan hệ Phép toán tập hợp Phép chọn Phép chiếu Phép tích Ca...
Giới thiệu Đại số quan hệ Phép toán tập hợp Phép chọn Phép chiếu Phép tích Ca...
 
Chuong 4-Thiet ke du lieu.pdf
Chuong 4-Thiet ke du lieu.pdfChuong 4-Thiet ke du lieu.pdf
Chuong 4-Thiet ke du lieu.pdf
 
Thuật toán Brich , Khai phá dữ liệu
Thuật toán Brich , Khai phá dữ liệu Thuật toán Brich , Khai phá dữ liệu
Thuật toán Brich , Khai phá dữ liệu
 
BáO CáO Lý ThuyếT Java
BáO CáO Lý ThuyếT JavaBáO CáO Lý ThuyếT Java
BáO CáO Lý ThuyếT Java
 
Ctdl c4-cay
Ctdl c4-cayCtdl c4-cay
Ctdl c4-cay
 
Ctdl c4-cay
Ctdl c4-cayCtdl c4-cay
Ctdl c4-cay
 
Bài 2 Làm quen với môi trường PHP và MySQL (phần 2) - Giáo trình FPT
Bài 2 Làm quen với môi trường PHP và MySQL (phần 2) - Giáo trình FPTBài 2 Làm quen với môi trường PHP và MySQL (phần 2) - Giáo trình FPT
Bài 2 Làm quen với môi trường PHP và MySQL (phần 2) - Giáo trình FPT
 
Cap nhat CSDL trong VB.NET
Cap nhat CSDL trong VB.NETCap nhat CSDL trong VB.NET
Cap nhat CSDL trong VB.NET
 
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT.pptx
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT.pptxCẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT.pptx
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT.pptx
 
Bai5 dsachlket
Bai5 dsachlketBai5 dsachlket
Bai5 dsachlket
 
Bài tập CTDL và GT 12
Bài tập CTDL và GT 12Bài tập CTDL và GT 12
Bài tập CTDL và GT 12
 

C3 danh sachlienket

  • 1. CHAPTER 3: DANH SÁCH LIÊN KẾT (LINKED LISTS)
  • 2. Chương 3: Danh sách liên kết Nội dung  Giới thiệu  Danh sách liên kết đơn (Single Linked List)  Danh sách liên kết đôi (Double Linked List)  Danh sách liên kết vòng (Circular Linked List) 2
  • 3. Chương 3: Danh sách liên kết Giới thiệu - Cấu trúc dữ liệu tĩnh  Cấu trúc dữ liệu tĩnh:  Khái niệm: Các đối tượng dữ liệu không thay đổi được kích thước, cấu trúc, … trong suốt quá trình sống thuộc về kiểu 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 dựng từ các kiểu cơ sở như: kiểu số thực, kiểu số nguyên, kiểu ký tự ... hoặc từ các cấu trúc đơn giản như mẩu tin, tập hợp, mảng ... 3
  • 4. Chương 3: Danh sách liên kết Giới thiệu - Cấu trúc dữ liệu tĩnh  Một số hạn chế của CTDL tĩnh:  Một số đối tượng dữ liệu trong chu kỳ sống của nó có thể thay đổi về cấu trúc, độ lớn,…  Ví dụ như danh sách các học viên trong một lớp học có thể tăng thêm, giảm đi ... Nếu dùng những cấu trúc dữ liệu tĩnh đã biết như mảng để biểu diễn  Những thao tác phức tạp, kém tự nhiên  chương trình khó đọc, khó bảo trì và nhất là khó có thể sử dụng bộ nhớ một cách có hiệu quả  Dữ liệu tĩnh sẽ chiếm vùng nhớ đã dành cho chúng suốt quá trình hoạt động của chương trình  sử dụng bộ nhớ kém hiệu quả 4
  • 5. Chương 3: Danh sách liên kết Giới thiệu – Ví dụ cấu trúc dữ liệu tĩnh  Cấu trúc dữ liệu tĩnh: Ví dụ: Mảng 1 chiều  Kích thước cố định (fixed size)  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 1 phần tử vào mảng, xóa 1 phần tử khỏi mảng tốn nhiều chi phí 5 0 1 2 3 4 n-2 n-1 chèn
  • 6. Chương 3: Danh sách liên kết Giới thiệu - Cấu trúc dữ liệu động  Cần xây dựng cấu trúc dữ liệu đáp ứng được các yêu cầu:  Linh động hơn  Có thể thay đổi kích thước, cấu trúc trong suốt thời gian sống  Cấu trúc dữ liệu động 6
  • 7. Chương 3: Danh sách liên kết Giới thiệu - Cấu trúc dữ liệu động  Cấu trúc dữ liệu động: Ví dụ: Danh sách liên kết, cây  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  Tốn bộ nhớ hơn (vì phải chứa thêm vùng liên kết)  Khó truy cập ngẫu nhiên  Thao tác thêm, xoá đơn giản 7 Insert, Delete
  • 8. Chương 3: Danh sách liên kết Giới thiệu - Danh sách liên kết  Danh sách liên kết:  Mỗi phần tử của danh sách gọi là node (nút)  Mỗi node có 2 thành phần: phần dữ liệu và phần liên kết (phần liên kết chứa địa chỉ của node kế tiếp hay node trước nó)  Các thao tác cơ bản trên danh sách liên kết:  Thêm một phần tử mới  Xóa một phần tử  Tìm kiếm  … 8
  • 9. Chương 3: Danh sách liên kết Giới thiệu - Danh sách liên kết  Có nhiều kiểu tổ chức liên kết giữa các phần tử trong danh sách như:  Danh sách liên kết đơn  Danh sách liên kết kép  Danh sách liên kết vòng 9
  • 10. Chương 3: Danh sách liên kết Giới thiệu - Danh sách liên kết  Danh sách liên kết đơn: mỗi phần tử liên kết với phần tử đứng sau nó trong danh sách:  Danh sách liên kết kép: mỗi phần tử liên kết với các phần tử đứng trước và sau nó trong danh sách: 10 A B X Z Y A B C D
  • 11. Chương 3: Danh sách liên kết Giới thiệu - Danh sách liên kết 11  Danh sách liên kết vòng : phần tử cuối danh sách liên kết với phần tử đầu danh sách: A B X Z Y A B C D
  • 12. Chương 3: Danh sách liên kết Nội dung  Giới thiệu  Danh sách liên kết đơn (Single Linked List)  Danh sách liên kết kép (Doule Linked List)  Danh sách liên kết vòng (Circular Linked List) 12
  • 13. Chương 3: Danh sách liên kết Danh sách liên kết đơn (DSLK đơn)  Khai báo  Các thao tác cơ bản trên DSLK đơn  Sắp xếp trên DSLK đơn 13
  • 14. Chương 3: Danh sách liên kết DSLK đơn – Khai báo  Là danh sách các node mà mỗi node có 2 thành phần:  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  Khai báo node: struct Node { DataType data; // DataType là kiểu đã định nghĩa trước Node *pNext; // con trỏ chỉ đến cấu trúc Node }; 14 data pNext Node* tên_nút;
  • 15. Chương 6: Danh sách liên kết DSLK đơn – Khai báo  Ví dụ 1: Khai báo node lưu số nguyên: struct Node { int data; Node *pNext; };  Ví dụ 2: Khai báo node lưu thông tin của một sinh viên: struct SinhVien { char Ten[30]; int MaSV; }; struct Node { SinhVien data; Node *pNext; }; 15
  • 16. Chương 3: Danh sách liên kết DSLK đơn – Khai báo  Tổ chức, quản lý:  Để quản lý một DSLK đơn chỉ cần biết địa chỉ phần tử đầu danh sách  Con trỏ pHead sẽ được dùng để lưu trữ địa chỉ phần tử đầu danh sách. Ta có khai báo: Node *pHead;  Để tiện lợi, có thể sử dụng thêm một con trỏ pTail giữ địa chỉ phần tử cuối danh sách. Khai báo pTail như sau: Node *pTail; 16 A B X Z Y pHead pTail A
  • 17. Chương 3: Danh sách liên kết DSLK đơn – Khai báo  Ví dụ: Khai báo cấu trúc 1 DSLK đơn chứa số nguyên // kiểu của một phần tử trong danh sách struct Node { int data; Node* pNext; }; // kiểu danh sách liên kết struct List { Node* pHead; Node* pTail; }; 17 Khai báo biến kiểu danh sách: List tên_biến;
  • 18. Chương 3: Danh sách liên kết DSLK đơn – Khai báo  Tạo một node mới  Viết hàm getNode để tạo ra một nút cho danh sách với dữ liệu là x 18 Node* getNode ( DataType x) { Node *p; p = new Node; // Cấp phát vùng nhớ cho node if (p==NULL) { cout<<“Khong du bo nho!”; return NULL; } p->data = x; // Gán dữ liệu cho phần tử p p->pNext = NULL; return p; } x p
  • 19. Chương 3: Danh sách liên kết Danh sách liên kết đơn (DSLK đơn)  Khai báo  Các thao tác cơ bản trên DSLK đơn  Sắp xếp trên DSLK đơn 19
  • 20. Chương 3: Danh sách liên kết DSLK đơn  Các thao tác cơ bản  Tạo danh sách rỗng  Thêm một phần tử vào danh sách  Duyệt danh sách  Tìm kiếm  Xóa một phần tử ra khỏi danh sách  Hủy toàn bộ danh sách  … 20
  • 21. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Tạo danh sách rỗng 21 pHead pTail void Init(List &l) { l.pHead = l.pTail = NULL; }
  • 22. Chương 3: Danh sách liên kết DSLK đơn  Các thao tác cơ bản  Tạo danh sách rỗng  Thêm một phần tử vào danh sách  Duyệt danh sách  Tìm kiếm một giá trị trên danh sách  Xóa một phần tử ra khỏi danh sách  Hủy toàn bộ danh sách  … 22
  • 23. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Thêm một phần tử vào danh sách: Có 3 vị trí thêm  Gắn vào đầu danh sách  Gắn vào cuối danh sách  Chèn vào sau nút q trong danh sách  Chú ý trường hợp danh sách ban đầu rỗng 23
  • 24. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Thêm một phần tử  Nếu danh sách ban đầu rỗng 24 pHead pTail new_node XpHead = pTail = new_node;
  • 25. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Thêm một phần tử  Gắn node vào đầu danh sách 25 A B C D E pHead pTail X new_node new_node->pNext = pHead; pHead = new_node;
  • 26. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Cài đặt: Gắn nút vào đầu DS 26 void addHead(List &l, Node* new_node) { if (l.pHead == NULL) // DS rỗng { l.pHead = l.pTail = new_node; } else { new_node->pNext = l.pHead; l.pHead = new_node; } }
  • 27. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Thuật toán: Thêm một thành phần dữ liệu vào đầu DS // input: danh sách l // output: danh sách l với phần tử chứa X ở đầu DS  Nhập dữ liệu cho X (???)  Tạo nút mới chứa dữ liệu X (???)  Nếu tạo được:  Gắn nút mới vào đầu danh sách (???) 27
  • 28. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Ví dụ: Thêm một số nguyên vào đầu ds: // Nhập dữ liệu cho X int x; cout<<“Nhap X=”; cin>>x; // Tạo nút mới Node* new_node = getNode(x); // Gắn nút vào đầu ds if (new_node != NULL) addHead(l, new_node); 28 43
  • 29. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Thêm một phần tử vào danh sách: Có 3 vị trí thêm  Gắn vào đầu danh sách  Gắn vào cuối danh sách  Chèn vào sau nút q trong danh sách  Chú ý trường hợp danh sách ban đầu rỗng 29
  • 30. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Thêm một phần tử  Gắn node vào cuối danh sách: 30 A B C D E pHead pTail X new_node pTail->pNext = new_node; pTail = new_node;
  • 31. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Cài đặt: Gắn nút vào cuối DS 31 void addTail(List &l, Node *new_node) { if (l.pHead == NULL) { l.pHead = l.pTail = new_node; } else { l.pTail->pNext = new_node; l.pTail = new_node ; } }
  • 32. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Ví dụ: Thêm một số nguyên vào cuối ds: // Nhập dữ liệu cho X int x; cout<<“Nhập X=”; cin>>x; // Tạo nút mới Node* p = getNode(x); // Gắn nút vào cuối DS if (p != NULL) addTail(l, p); 32
  • 33. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Thêm một phần tử vào danh sách: Có 3 vị trí thêm  Gắn vào đầu danh sách  Gắn vào cuối danh sách  Chèn vào sau nút q trong danh sách  Chú ý trường hợp danh sách ban đầu rỗng 33
  • 34. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Thêm một phần tử  Chèn một phần tử vào sau nút q 34 A B C D E pHead pTail X new_node q new_node -> pNext = q -> pNext; q -> pNext = new_node ;
  • 35. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Cài đặt: Chèn một phần tử vào sau nút q 35 void addAfter (List &l, Node *q, Node* new_node) { if (q!=NULL) { new_node->pNext = q->pNext; q->pNext = new_node; if (q==l.pTail) l.pTail = new_node; } }
  • 36. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Thuật toán: Thêm một thành phần dữ liệu vào sau q // input: danh sách thành phần dữ liệu X // output: danh sách với phần tử chứa X ở cuối DS  Nhập dữ liệu cho nút q (???)  Tìm nút q (???)  Nếu tồn tại q trong ds thì:  Nhập dữ liệu cho X (???)  Tạo nút mới chứa dữ liệu X (???)  Nếu tạo được:  Gắn nút mới vào sau nút q (???)  Ngược lại thì báo lỗi 36
  • 37. Chương 3: Danh sách liên kết DSLK đơn  Các thao tác cơ bản  Tạo danh sách rỗng  Thêm một phần tử vào danh sách  Duyệt danh sách  Tìm kiếm một giá trị trên danh sách  Xóa một phần tử ra khỏi danh sách  Hủy toàn bộ danh sách  … 37
  • 38. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Duyệt danh sách  Là thao tác thường được thực hiện khi có nhu cầu muốn lấy lần lượt từng phần tử trong danh sách để xử lý, chẳng hạn xử lý:  Xuất các phần tử trong danh sách  Đếm các phần tử trong danh sách  Tính tổng các phần tử trong danh sách  Tìm tất cả các phần tử danh sách thoả điều kiện nào đó  Hủy toàn bộ danh sách (và giải phóng bộ nhớ)  … 38
  • 39. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Duyệt danh sách  Bước 1: p = pHead; //Cho p trỏ đến phần tử đầu danh sách  Bước 2: Trong khi (chưa hết danh sách) thực hiện:  B2.1 : Xử lý phần tử p  B2.2 : p=p->pNext; // Cho p trỏ tới phần tử kế 39 Node *p = l.pHead; while ( p!=NULL ) { // xử lý cụ thể p tùy ứng dụng p = p->pNext; } Chuyển thành vòng lặp for??
  • 40. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Ví dụ: In các phần tử trong danh sách 40 void Output (List l) { Node* p=l.pHead; while (p!=NULL) { cout<<p->data<<“t”; p=p->pNext; } cout<<endl; }
  • 41. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Đếm số nút trong danh sách: 41 int CountNodes (List l) { int count = 0; Node *p = l.pHead; while (p!=NULL) { count++; p = p->pNext; } return count; } Gọi hàm???
  • 42. Chương 3: Danh sách liên kết DSLK đơn  Các thao tác cơ bản  Tạo danh sách rỗng  Thêm một phần tử vào danh sách  Duyệt danh sách  Tìm kiếm một giá trị trên danh sách  Xóa một phần tử ra khỏi danh sách  Hủy toàn bộ danh sách  … 42
  • 43. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở 43  Tìm kiếm một phần tử có khóa x Node* Search (List l, int x) { Node* p = l.pHead; while ( p!=NULL ) { if ( p->data==x ) return p; p=p->pNext; } return NULL; } Gọi hàm???
  • 44. Chương 3: Danh sách liên kết DSLK đơn  Các thao tác cơ bản  Tạo danh sách rỗng  Thêm một phần tử vào danh sách  Duyệt danh sách  Tìm kiếm một giá trị trên danh sách  Xóa một phần tử ra khỏi danh sách  Hủy toàn bộ danh sách  … 44
  • 45. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Xóa một node của danh sách  Xóa node đầu danh sách  Xóa node sau node q trong danh sách  Xóa node có khoá k 45
  • 46. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Thuật toán: Xóa node đầu danh sách  Bước 1: Nếu danh sách rỗng thì không xóa được và thoát ct, ngược lại qua Bước 2  Bước 2: Gọi p là node đầu của danh sách (p=pHead)  Bước 3: Cho pHead trỏ vào node sau node p (pHead =p->pNext)  Bước 4: Nếu không còn node nào thì pTail = NULL  Bước 5: Giải phóng vùng nhớ mà p trỏ tới 46
  • 47. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Minh họa: Xóa node đầu danh sách 47 A B C D E pHead pTail p pHead = p->pNext; delete p;
  • 48. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở // xóa được: hàm trả về 1 // xóa không được: hàm trả về 0 int removeHead (List &l){ if (l.pHead == NULL) return 0; Node* p=l.pHead; l.pHead = p->pNext; if (l.pHead == NULL) l.pTail=NULL; //Nếu danh sách rỗng delete p; return 1; } 48 Cài đặt: Xóa node đầu danh sách
  • 49. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Xóa một node của danh sách  Xóa node đầu danh sách  Xóa node sau node q trong danh sách  Xóa node có khoá k 49
  • 50. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Thuật toán: Xóa node sau node q trong danh sách:  Điều kiện để có thể xóa được node sau q là:  q phải khác NULL (q !=NULL)  Node sau q phải khác NULL (q->pNext !=NULL)  Thuật toán:  Bước 1: Gọi p là node sau q  Bước 2: Cho q trỏ vào node đứng sau p  Bước 3: Nếu p là phần tử cuối thì pTail là q  Bước 4: Giải phóng vùng nhớ mà p trỏ tới 50
  • 51. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Minh họa: Xóa node sau node q trong danh sách 51 A B C D E pHead pTail q p q->pNext = p->pNext; delete p;
  • 52. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Cài đặt: Xóa node sau node q trong danh sách 52 // xóa được: hàm trả về 1 // xóa không được: hàm trả về 0 int removeAfter (List &l, Node* q ){ if (q !=NULL && q->pNext !=NULL) { Node* p = q->pNext; q->pNext = p->pNext; if (p==l.pTail) l.pTail = q; delete p; return 1; } else return 0; }
  • 53. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Xóa một node của danh sách  Xóa node đầu của danh sách  Xóa node sau node q trong danh sách  Xóa node có khoá k 53
  • 54. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở Thuật toán: Xóa 1 node có khoá k  Bước 1:  Tìm node có khóa k (gọi là p) và node đứng trước nó (gọi là q)  Bước 2:  Nếu (p!= NULL) thì // tìm thấy k  Hủy p ra khỏi danh sách: tương tự hủy phần tử sau q  Ngược lại  Báo không có k 54
  • 55. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Cài đặt: Xóa 1 node có khoá k 55 int removeNode (List &l, int k) { Node *p = l.pHead; Node *q = NULL; while (p != NULL) { if (p->data == k) break; q = p; p = p->pNext; } if (p == NULL) { cout<<“Không tìm thấy k”; return 0;} else if (q == NULL) // thực hiện xóa phần tử đầu ds là p else // thực hiện xóa phần tử p sau q } Tìm phần tử p có khóa k và phần tử q đứng trước nó A B C D E pHead pTail
  • 56. Chương 3: Danh sách liên kết DSLK đơn  Các thao tác cơ bản  Tạo danh sách rỗng  Thêm một phần tử vào danh sách  Duyệt danh sách  Tìm kiếm một giá trị trên danh sách  Xóa một phần tử ra khỏi danh sách  Hủy toàn bộ danh sách  … 56
  • 57. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Hủy toàn bộ danh sách  Để hủy toàn bộ danh sách, thao tác xử lý bao gồm hành động giải phóng một phần tử, do vậy phải cập nhật các liên kết liên quan:  Thuật toán:  Bước 1: Trong khi (chưa hết danh sách) thực hiện:  B1.1:  p = pHead;  pHead = pHead ->pNext; // Cho p trỏ tới phần tử kế  B1.2:  Hủy p;  Bước 2:  pTail = NULL; //Bảo đảm tính nhất quán khi xâu rỗng 57
  • 58. Chương 3: Danh sách liên kết DSLK đơn – Các thao tác cơ sở  Cài đặt: Hủy toàn bộ danh sách 58 void RemoveList (List &l) { Node *p; while (l.pHead!=NULL) { p = l.pHead; l.pHead = p->pNext; delete p; } l.pTail = NULL; } Gọi hàm???
  • 59. Chương 3: Danh sách liên kết Danh sách liên kết đơn (DSLK đơn)  Khai báo  Các thao tác cơ bản trên DSLK đơn  Sắp xếp trên DSLK đơn 59
  • 60. Chương 3: Danh sách liên kết Sắp xếp trên DSLK đơn  Các cách tiếp cận:  Phương án 1: Hoán vị nội dung các phần tử trong danh sách (thao tác trên vùng data)  Sử dụng thêm vùng nhớ trung gian  thích hợp cho DSLK với thành phần data có kích thước nhỏ  Phương án 2: Thay đổi các mối liên kết (thao tác trên vùng pNext)  Phức tạp hơn 60
  • 61. Chương 3: Danh sách liên kết Sắp xếp trên DSLK đơn: Hoán vị data  Cài đặt bằng pp đổi chỗ trực tiếp (Interchange Sort) void InterChangeSort (List &l) { for (Node* p=l.pHead; p!=l.pTail; p=p->pNext) for (Node* q=p->pNext; q!=NULL; q=q->pNext) if (p->data > q->data) Swap (p->data, q->data); } 61
  • 62. Chương 3: Danh sách liên kết Sắp xếp trên DSLK đơn: Hoán vị data 62 12 2 8 1 5 p q l.pHead l.pTail
  • 63. Chương 3: Danh sách liên kết Sắp xếp trên DSLK đơn: Hoán vị data 63 1 12 8 2 5 p q l.pHead l.pTail
  • 64. Chương 3: Danh sách liên kết 64 1 2 12 8 5 p q l.pHead l.pTail Sắp xếp trên DSLK đơn: Hoán vị data
  • 65. Chương 3: Danh sách liên kết 65 1 2 5 12 8 p q l.pHead l.pTail Sắp xếp trên DSLK đơn: Hoán vị data
  • 66. Chương 3: Danh sách liên kết 66 1 2 5 8 12 p q ng l.pHead l.pTail Sắp xếp trên DSLK đơn: Hoán vị data
  • 67. Chương 3: Danh sách liên kết Sắp xếp bằng pp chọn trực tiếp (Selection sort) void ListSelectionSort (List &l) { for ( Node* p = l.pHead ; p != l.pTail ; p = p->pNext ) { Node* min = p; for ( Node* q = p-> pNext; q != NULL ; q = q-> pNext ) if ( min->data > q->data ) min = q ; Swap(min->data, p->data); } } 67
  • 68. Chương 3: Danh sách liên kết Sắp xếp trên DSLK đơn: Thay đổi liên kết  Một trong những cách thay đổi liên kết đơn giản nhất là tạo một danh sách mới là danh sách có thứ tự từ danh sách cũ (GT.101)  Bước 1: Khởi tạo danh sách mới Result là rỗng;  Bước 2: Tìm phần tử nhỏ nhất min trong danh sách cũ l;  Bước 3: Tách min khỏi danh sách l;  Bước 4: Chèn min vào cuối danh sách Result;  Bước 5: Lặp lại bước 2 khi chưa hết danh sách cũ l; 68
  • 69. 69 void SortList( List &l ){ List lResult; Init( lResult ); Node *p,*q, *min, *minprev; while( l.pHead != NULL ){ min = l.pHead; q = min->pNext; p = l.pHead; minprev = NULL; while ( q != NULL ) { if (min->data >q->data ) { min = q; minprev = p; } p = q; q = q->pNext; } if ( minprev != NULL ) minprev->pNext = min->pNext; else l.pHead = min->pNext; min->pNext = NULL; addTail( lResult, min ); } l = lResult; } 5 4 3 9 minminprev