Bài giảng Cấu trúc dữ liệu và giải thuật – Bài 15: Danh sách liên kết trình bày giới thiệu chung, danh sách liên kết đơn, danh sách liên kết vòng, danh sách liên kết kép, một số ví dụ về danh sách liên kết.
Cấu trúc liệu giải thuật Bài 15 Danh sách liên kết Giảng viên: TS Ngo Huu Phuc Tel: 0438 326 077 Mob: 098 5696 580 Email: ngohuuphuc76@gmail.com @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 Bài 15: Danh sách liên kết 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: Deshpande Kakde: C and Data structures.chm, Chapter 20: Linked Lists Elliz Horowitz – Fundamentals of Data Structures.chm, Chapter 4: Linked Lists Kyle Loudon: Mastering Algorithms with C.chm, Chapter Linked Lists Bài giảng TS Nguyễn Nam Hồng @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.1 Giới thiệu chung (1/2) Với CTDL dạng mảng, nhớ sử dụng dãy liền kề 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 phải thay đổi phần tử lại mảng Ngay khai báo lượng lớn phần tử cho mảng để áp dụng cho nhiều toán, thấy khả dư thừa nhớ xuất @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.1 Giới thiệu chung (2/2) Để khắc phục nhược điểm trên, sử dụng danh sách liên kết 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 đị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 kết với phần tử khác @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.2 Danh sách liên kết đơn (1/23) Trong 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 Danh sách liên kết kép @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.2 Danh sách liên kết đơn (2/23) 15.2.1 Khái niệm danh sách liên kết đơn Danh sách liên kết đơn cấu trúc liệu bao gồm tập nút, mà nút bao gồm: Data Link Add Node Dữ liệu cần lưu trữ Liên kết đến nút 60 1000 800 45 800 90 55 NULL 90 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.2 Danh sách liên kết đơn (3/23) 15.2.1 Khái niệm danh sách liên kết đơn Để quản lý danh sách liên kết, thơng thường cần: • Start 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 start 60 1000 800 45 800 90 55 NULL 90 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.2 Danh sách liên kết đơn (4/23) 15.2.1 Khái niệm danh sách liên kết đơn Khai báo cấu trúc Node danh sách: template struct node { ListEntry data; struct node *link; }; @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.2 Danh sách liên kết đơn (5/23) 15.2.2 Các thao tác danh sách liên kết đơn Khởi tạo danh sách LAdd: Thêm node vào đầu danh sách LInsert: Chèn node vào danh sách LAppend: Thêm node vào cuối danh sách LFind: Tìm node danh sách LDelete: Xóa node danh sách LLength: Số phần tử danh sách LMakeEmpty: Làm rỗng danh sách LGet: Lấy thông tin phần tử danh sách @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.2 Danh sách liên kết đơn (6/23) 15.2.2 Các thao tác danh sách liên kết đơn 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 friend void LPrint(LList list); private: node *start; }; 10 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.4 Danh sách liên kết kép (9/22) 15.4.2 Các thao tác danh sách liên kết kép Chèn node vào danh sách LK kép: Nhập thông tin node đứng trước node thêm Sử dụng trỏ curr để xác định node đứng trước node cần thêm Cấp phát ô nhớ cho biến temp Tạo liên kết left right temp thông qua curr curr->right Lưu ý: khơng xác định node đứng trước, khơng thực temp curr ? 60 1000 56 1000 45 90 curr->right 800 800 800 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 55 ? 90 Tháng 09 năm 2009 15.4 Danh sách liên kết kép (10/22) 15.4.2 Các thao tác danh sách liên kết kép Chèn node vào danh sách LK kép : template int DLList::DLInsert(ListEntry value, ListEntry entry) { int kt=0; dnode *temp, *curr; if (start==NULL) printf("Danh sach rong!"); else { curr=start; while(curr!=NULL) { if (curr->data==value) break; else curr=curr->right; } if (curr==NULL) { if (end->data==value) { temp=(dnode *) malloc(sizeof(dnode)); if (temp==NULL) { printf("Loi cap phat bo nho!\n"); return kt; } 57 temp->data=entry; temp->right=NULL; temp->left=end; end->right=temp; end=temp; kt=1; } } else { temp=(dnode *) malloc(sizeof(dnode)); if (temp==NULL) { printf("Loi cap phat bo nho!\n"); return kt; } temp->data=entry; temp->right=curr->right; temp->left=curr; temp->right->left=temp; temp->left->right=temp; kt=1; } } return kt; } @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.4 Danh sách liên kết kép (11/22) 15.4.2 Các thao tác danh sách liên kết kép Thêm node cuối danh sách LK kép: Nếu danh sách rỗng, cấp phát ô nhớ cho start start end trỏ vào ô nhớ end Nếu danh sách khơng rỗng: Cấp phát ô nhớ cho trỏ temp Tạo liên kết left right tương ứng (liên kết NULL left data right temp->right trỏ vào NULL, liên kết temp->left trỏ vào end) End->right trỏ vào temp End trỏ vào vùng ô nhớ end temp 60 1000 58 800 1000 45 800 NUL L 90 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 800 55 NULL 90 Tháng 09 năm 2009 15.4 Danh sách liên kết kép (12/22) 15.4.2 Các thao tác danh sách liên kết kép Thêm node cuối danh sách LK kép: template int DLList::DLAppend(ListEntry entry){ int kt=0; dnode *temp; if (start==NULL) { start=(dnode *) malloc(sizeof(dnode)); if (start==NULL) { printf("Loi cap phat bo nho!\n"); return kt; } kt=1; start->data=entry; start->left=start->right=NULL; end=start; } else { temp=(dnode *) malloc(sizeof(dnode)); if (temp==NULL) { printf("Loi cap phat bo nho!\n"); return kt; } kt=1; temp->data=entry; temp->right=NULL; temp->left=end; end->right=temp; end=temp; } return kt; } 59 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.4 Danh sách liên kết kép (13/22) 15.4.2 Các thao tác danh sách liên kết kép Tìm node danh sách LK kép: Sử dụng trỏ temp để duyệt qua danh sách, temp NULL Sử dụng thêm biến pos để lưu vị trí 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 start NULL 60 1000 60 Tìm vị trí phần tử có giá trị 45! pos=2 temp 800 1000 45 90 800 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University end 800 55 NULL 90 Tháng 09 năm 2009 15.4 Danh sách liên kết kép (14/22) 15.4.2 Các thao tác danh sách liên kết kép temp=temp->right; Tìm node danh sách LK kép: template } int DLList::DLFind(ListEntry value) if (found) return pos; { else int pos=0; return 0; int found=0; dnode *temp=start; } while (temp!=NULL && !found) { pos++; if (temp->data==value) found=1; else 61 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.4 Danh sách liên kết kép (15/22) 15.4.2 Các thao tác danh sách liên kết kép Xóa node danh sách LK kép: curr Sử dụng trỏ curr để xác định vị trí start 45 ? cần xóa Nếu vị trí cần xóa start: NULL Chuyển trỏ start sang phải Thay đổi liên kết left start NULL Giải phóng nhớ curr quản lý 60 800 800 1000 Nếu vị trí cần xóa khơng phải start: Thay đổi liên kết dựa vào left right Giải phóng nhớ curr quản lý 60 1000 62 800 curr 1000 45 90 800 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 800 55 90 Tháng 09 năm 2009 15.4 Danh sách liên kết kép (16/22) 15.4.2 Các thao tác danh sách liên kết kép Xóa node danh sách LK kép: template int DLList::DLDelete(ListEntry value) { dnode *curr; int kt=0; if (start==NULL) return kt; else { curr=start; while (!kt && curr!=NULL) { if (curr->data==value) { kt=1; break; } else curr=curr->right; } 63 } } if (kt!=1 && curr==NULL) kt=2; if (kt==1) { if (curr==start) { start=start->right; start->left=NULL; free(curr); } else { curr->left->right=curr->right; curr->right->left=curr->left; free(curr); } } return kt; @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.4 Danh sách liên kết kép (17/22) 15.4.2 Các thao tác danh sách liên kết kép Lấy thơng tin node vị trí LK kép: Sử dụng trỏ temp để duyệt qua danh sách Duyệt đến node thứ pos, lấy thơng tin node trả lại cho nơi gọi hàm start NULL 60 1000 64 temp 800 1000 45 Cho trước pos=2 90 800 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 800 end 55 NULL 90 Tháng 09 năm 2009 15.4 Danh sách liên kết kép (18/22) 15.4.2 Các thao tác danh sách liên kết kép if(i!=pos) Lấy thơng tin node vị trí đó: template return 0; int DLList::DGet(int pos, ListEntry *value) else { { int i=0; *value=temp->data; dnode *temp=start; return 1; while(temp!=NULL && iright; } } if(temp!=NULL) i++; } 65 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.4 Danh sách liên kết kép (19/22) 15.4.2 Các thao tác danh sách liên kết kép Xác định số phần tử danh sách LK kép: Sử dụng trỏ temp để duyệt qua danh sách, temp start Sử dụng biến length để đếm số phần tử duyệt start NULL 60 1000 66 length = temp 800 1000 45 90 800 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 800 end 55 NULL 90 Tháng 09 năm 2009 15.4 Danh sách liên kết kép (20/22) 15.4.2 Các thao tác danh sách liên kết kép Xác định số phần tử danh sách LK kép: template int DLList::DLLength() { int length=0; dnode *temp=start; if (temp!=NULL) { while (temp!=NULL) { length++; temp=temp->right; } } return length; } 67 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.4 Danh sách liên kết kép (21/22) 15.4.2 Các thao tác danh sách liên kết kép Làm rỗng danh sách liên kết kép: Để làm rỗng danh sách, cách đơn giản sử dụng xóa phần tử hàm Delete Ngồi ra, viết lại hàm xóa phần tử start NULL 60 1000 68 800 1000 end 45 90 800 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 800 55 NULL 90 Tháng 09 năm 2009 15.4 Danh sách liên kết kép (22/22) 15.4.2 Các thao tác danh sách liên kết kép Làm rỗng danh sách LK kép: template void DLList::DLMakeEmpty() { dnode *temp; while (start!=NULL) { temp=start; start=start->right; DLDelete(temp->data); } } 69 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 15.4 Một số dạng ví dụ sử dụng DSLK (1/) Trong thực tế, sử dụng DSLK cho nhiều ứng dụng như: Xây dựng Stack, Queue sử dụng danh sách liên kết Biểu diễn sử dụng danh sách liên kết Biểu diễn mảng, ma trận thưa danh sách liên kết Biểu diễn đồ thị danh sách liên kết Bài toán đa thức sử dụng danh sách liên kết Bài toán số lớn sử dụng danh sách liên kết 70 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Tháng 09 năm 2009 .. .Bài 15: Danh sách liên kết 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. .. 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... 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 Danh sách liên kết kép @copyright by