Các thao tác cơ bản của danh sách liên kết đơn. start[r]
(1)Giảng viên: TS Ngo Huu Phuc Tel: 0438 326 077 Mob: 098 5696 580
Email:
Cấu trúc liệu giải thuật
(2)Nội dung:
15.1 Giới thiệu chung.
15.2 Danh sách liên kết đơn.
15.2.1 Khái niệm danh sách liên kết đơn.
15.2.2 Các thao tác danh sách liên kết đơn. 15.3 Danh sách liên kết vòng.
15.3.1 Khái niệm danh sách liên kết vòng.
15.3.2 Các thao tác danh sách liên kết vòng. 15.4 Danh sách liên kết kép.
15.4.1 Khái niệm danh sách liên kết kép.
15.4.2 Các thao tác danh sách liên kết kép. 15.5 Một số ví dụ danh sách liên kết.
Tham khảo:
1 Deshpande Kakde: C and Data structures.chm, Chapter 20: Linked Lists
2 Elliz Horowitz – Fundamentals of Data Structures.chm, Chapter 4: Linked Lists Kyle Loudon: Mastering Algorithms with C.chm, Chapter Linked Lists.
(3) Với CTDL dạng mảng, nhớ sử dụng một dãy liền kề và có kích thước cố định
Tuy nhiên, CTDL có một số nhược điểm:
Thời gian cho việc thêm hay bớt phần tử mảng lâu vì phải thay đổi phần tử lại mảng.
(4) Để khắc phục nhược điểm trên, sử dụng danh sách liên kết như cấu trúc liệu thay
Trong cấu trúc này, không cần xác định kích thước cho
phần tử trước
Ta có thể định nghĩa phần tử lúc nào, sau liên kết
phần tử với danh sách có trước
Như vậy, phần tử bao gồm thông tin cần lưu trữ liên
(5) Trong rất nhiều trường hợp cần sử dụng đến danh sách liên kết
động, danh sách liên kết động cần dùng đến kích thước danh sách chưa biết thời điểm biên dịch chương trình
Khi đó, danh sách mở rộng thu hẹp lại thời điểm chạy chương trình
Cấu trúc liệu linked list sử dụng mơ hình liên kết động.
Một số dạng danh sách liên kết:
Danh sách liên kết đơn.
Danh sách liên kết vòng.
(6) Danh sách liên kết đơn là một cấu trúc dữ liệu bao gồm một tập các nút, mà mỗi nút bao gồm:
Dữ liệu cần lưu trữ
Liên kết đến nút tiếp theo
Link
Data
Node
Add
60 1000
800 45
800
90 55
90
0 NULL
(7) Để quản lý danh sách liên kết, thơng thường cần:
• Start là trỏ đến phần tử danh sách liên kết. • Phần tử cuối danh sách liên kết với vùng liên kết có nội dung
NULL.
60 1000
800 45
800
90 55
90
0 NULL
15.2.1 Khái niệm danh sách liên kết đơn
(8)Khai báo cấu trúc Node danh sách: template <class ListEntry>
struct node {
ListEntry data;
struct node *link; };
(9)1. Khởi tạo danh sách.
2. LAdd: Thêm một node vào đầu danh sách. 3. LInsert: Chèn một node vào danh sách.
4. LAppend: Thêm một node vào cuối danh sách. 5. LFind: Tìm một node danh sách.
6. LDelete: Xóa một node danh sách. 7. LLength: Số phần tử danh sách. 8. LMakeEmpty: Làm rỗng danh sách.
(10)class LList {
public: LList();
int LAdd(ListEntry entry);
int LInsert(ListEntry value, ListEntry entry);
int LAppend(ListEntry entry);
int LFind(ListEntry value);
int LDelete(ListEntry value);
int LLength();
void LMakeEmpty();
int LGet(int pos, ListEntry *value);
template<typename ListEntry> friend void LPrint(LList<ListEntry> list);
private:
node<ListEntry> *start; };
(11)Khởi tạo danh sách:
template <class ListEntry> LList<ListEntry>::LList() {
start = NULL; }
15.2.2 Các thao tác danh sách liên kết đơn
start
(12)Thêm một node đầu danh sách:
Nếu danh sách rỗng, cấp phát ô nhớ cho start trỏ vào nhớ đó.
Nếu danh sách không rỗng:
Cấp phát ô nhớ cho biến temp.
Phần liên kết temp trỏ vào đầu danh sách.
Con trỏ start trỏ vào temp.
15.2.2 Các thao tác danh sách liên kết đơn
start
NULL data link
temp 1
2
start
NULL data link
temp
(13)Thêm một node đầu danh sách:
template<classListEntry>
intLList<ListEntry>::LAdd(ListEntry entry) {
int kt=0;
node<ListEntry> *temp;
if(start==NULL) {
start=(node<ListEntry> *)
malloc(sizeof(node<ListEntry>));
if(start==NULL) {
printf("Loi cap phat bo nho!\n");
returnkt; } kt=1;
start->data=entry; start->link=NULL;
15.2.2 Các thao tác danh sách liên kết đơn
else {
temp=(node<ListEntry> *)
malloc(sizeof(node<ListEntry>));
if(temp==NULL) {
printf("Loi cap phat bo nho!\n");
(14)Chèn node vào danh sách:
Nhập thông tin node đứng trước node thêm mới.
Sử dụng trỏ temp để đến node đứng trước đó.
Cấp phát ô nhớ cho biến temp1.
Phần liên kết temp1 trỏ vào phần liên kết trỏ temp.
Phần liên kết trỏ temp trỏ vào temp1.
15.2.2 Các thao tác danh sách liên kết đơn
start
NULL
temp
data link
data link data link data link
data link
temp1 1
(15)Chèn node vào danh sách :
template<classListEntry>
intLList<ListEntry>::LInsert(ListEntry value, ListEntry entry) {
int kt=0;
node<ListEntry> *temp, *temp1;
if(start==NULL) printf("Danh sach rong!");
else {
temp=start;
while(temp!=NULL) {
if(temp->data==value)
break;
else
temp=temp->link; }
15.2.2 Các thao tác danh sách liên kết đơn
if(temp!=NULL) {
temp1=(node<ListEntry> *)
malloc(sizeof(node<ListEntry>));
if(temp1==NULL) {
printf("Loi cap phat bo nho!\n");
(16)Thêm một node cuối danh sách:
Nếu danh sách rỗng, cấp phát ô nhớ cho start trỏ vào nhớ đó.
Nếu danh sách không rỗng:
Sử dụng trỏ temp đến cuối danh sách.
Cấp phát ô nhớ cho temp->link.
Phần liên kết temp->link trỏ vào NULL.
15.2.2 Các thao tác danh sách liên kết đơn
start
NULL data link
temp 1
2
start
NULL
temp
data link
data link data link
(17)Thêm một node cuối danh sách:
template<classListEntry>
intLList<ListEntry>::LAppend(ListEntry entry) {
int kt=0;
node<ListEntry> *temp;
if(start==NULL) {
start=(node<ListEntry> *)
malloc(sizeof(node<ListEntry>));
if(start==NULL) {
printf("Loi cap phat bo nho!\n");
returnkt; } kt=1;
start->data=entry; start->link=NULL;
15.2.2 Các thao tác danh sách liên kết đơn else {
temp=start;
while(temp->link!=NULL) temp=temp->link;
temp->link=(node<ListEntry> *)
malloc(sizeof(node<ListEntry>));
if(temp->link==NULL) {
printf("Loi cap phat bo nho!\n");
returnkt; }
kt=1; temp=temp->link; temp->data=entry;
temp->link=NULL; }
(18)Tìm một node danh sách: Sử dụng trỏ temp để duyệt qua
danh sách.
Sử dụng thêm biến pos để lưu vị trí của node danh sách Nếu danh sách rỗng khơng tìm thấy trả
0, ngược lại trả vị trí node.
15.2.2 Các thao tác danh sách liên kết đơn
start
NULL
temp
data link
data link data link data link
(19)Tìm một node danh sách:
template <class ListEntry>
int LList<ListEntry>::LFind(ListEntry value) {
int pos=0;
node<ListEntry> *temp=start;
while(temp!=NULL) { pos++;
if(temp->data==value)
break;
temp=temp->link; }
if(temp!=NULL)
return pos;
else return0; }
(20)Xóa một node danh sách:
Sử dụng trỏ prev curr để tìm node cần xóa Con trỏ prev trỏ vào node
trước node cần xóa Con trỏ curr trỏ vào
node cần xóa.
Nếu curr = start, cho start trỏ vào start->link giải phóng nhớ curr. Nếu không, prev->link trỏ tới
curr->link giải phóng nhớ curr.
15.2.2 Các thao tác danh sách liên kết đơn
1 2 start NULL curr data link
data link data link data link