Ngôn ngữ lập trình - Bài 11: Các cấu trúc dữ liệu liên kết

pdf 44 trang vanle 2230
Bạn đang xem 20 trang mẫu của tài liệu "Ngôn ngữ lập trình - Bài 11: Các cấu trúc dữ liệu liên kết", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfngon_ngu_lap_trinh_bai_11_cac_cau_truc_du_lieu_lien_ket.pdf

Nội dung text: Ngôn ngữ lập trình - Bài 11: Các cấu trúc dữ liệu liên kết

  1. NGÔN NGỮ LẬP TRÌNH Bài 11: Các cấu trúc dữ liệu liên kết Giảng viên: Lý Anh Tu ấn Email: tuanla@tlu.edu.vn
  2. Nội dung 1. Các nút và danh sách liên kết ◦ Tạo, tìm kiếm 2. Ứng dụng danh sách liên kết ◦ Ngăn xếp, hàng đợi 3. Biến lặp (iterator) ◦ Con trỏ và biến lặp 2
  3. Giới thiệu  Danh sách liên kết ◦ Được tạo bằng việc sử dụng các con trỏ ◦ Mở rộng và co lại trong thời gian chạy  Cây cũng sử dụng các con trỏ  Các con trỏ là xương sống của các cấu trúc như vậy ◦ Sử dụng các biến động  Thư viện khuôn mẫu chuẩn ◦ Có phiên bản định nghĩa trước của một số cấu trúc 3
  4. Tiếp cận  Ba cách vận hành các cấu trúc dữ liêu như vậy 1. Các hàm toàn cục và các struct có dữ liệu public 2. Các lớp với các biến thành viên private và các hàm truy cập và biến đổi 3. Các lớp bạn  Danh sách liên kết sử dụng phương pháp 1  Ngăn xếp, hàng đợi sử dụng phương pháp 2  Cây sử dụng phương pháp 3 4
  5. Nút và danh sách liên kết  Danh sách liên kết ◦ Ví dụ đơn giản của “cấu trúc dữ liệu động” ◦ Bao gồm các nút  Mỗi nút là biến kiểu cấu trúc hoặc lớp được tạo động bằng new ◦ Các nút cũng bao gồm các con trỏ tới các nút khác ◦ Cung cấp các liên kết 5
  6. Nút và con trỏ 6
  7. Định nghĩa nút  struct ListNode { string item; int count; ListNode *link; }; typedef ListNode* ListNodePtr;  Trật tự ở đây là quan trọng ◦ Listnode được định nghĩa trước vì được sử dụng trong typedef  Cũng lưu ý tới khả năng có chu trình 7
  8. Con trỏ head  Hộp được gán nhãn “head” không phải là một nút: ListNodePtr head; ◦ Một con trỏ trỏ tới một nút ◦ Được thiết lập trỏ tới nút đầu tiên của danh sách  head được sử dụng để “duy trì” vị trí bắt đầu của danh sách  Cũng được sử dụng làm đối số của hàm 8
  9. Ví dụ truy cập nút  (*head).count = 12; ◦ Thiết lập thành viên count của nút được trỏ bởi head bằng 12  Toán tử thay thế, -> ◦ Được gọi là “toán tử mũi tên” ◦ Ký hiệu viết tắt kết hợp * và . ◦ head->count = 12; //tương tự như trên  cin >> head->item ◦ Gán chuỗi nhập vào cho thành viên item 9
  10. Ký hiệu kết thúc  Sử dụng NULL cho con trỏ nút ◦ Được xem là cờ hiệu cho các nút ◦ Chỉ ra rằng không còn liên kết phía sau nút này  Việc cung cấp ký hiệu kết thúc tương tự như cách chúng ta sử dụng mảng được nhập giá trị một phần 10
  11. Truy cập dữ liệu nút 11
  12. Danh sách liên kết  Danh sách minh họa được gọi là danh sách liên kết  Nút đầu tiên được gọi là head ◦ Được trỏ tới bởi con trỏ có tên là head  Nút cuối cũng đặc biệt ◦ Biến con trỏ thành viên của nó là NULL ◦ Dễ dàng kiểm tra việc kết thúc danh sách liên kết 12
  13. Định nghĩa lớp danh sách liên kết  class IntNode { public: IntNode() { } IntNode(int theData, IntNOde* theLink) : data(theData), link(theLink) { } IntNode* getLink() const {return link;} int getData() const {return data;} void setData(int theData) {data = theData;} void setLink(IntNode* pointer) {link=pointer;} private: int data; IntNode *link; }; typedef IntNode* IntNodePtr; 13
  14. Lớp danh sách liên kết  Lưu ý tất cả các định nghĩa hàm thành viên là nội tuyến ◦ Đủ nhỏ và đơn giản  Lưu ý hàm tạo hai tham số ◦ Cho phép tạo các nút với thành viên giá trị dữ liệu và thành viên liên kết ◦ Ví dụ: IntNodePtr p2 = new IntNode(42, p1); 14
  15. Tạo nút đầu tiên  IntNodePtr head; ◦ Khai báo biến con trỏ head  head = new IntNode; ◦ Cấp phát động nút mới ◦ Nút đầu tiên trong danh sách, do vậy được gán cho head  head->setData(3); head->setLink(NULL); ◦ Thiết lập dữ liệu cho head ◦ Thiết lập liên kết tới NULL vì nó là nút duy nhất 15
  16. Thêm một nút vào đầu danh sách liên kết 16
  17. Lỗi thường gặp: Mất nút 17
  18. Chèn vào giữa danh sách liên kết 18
  19. Chèn vào giữa danh sách liên kết 19
  20. Loại bỏ một nút 20
  21. Tìm kiếm trên danh sách liên kết  Hàm với hai đối số: IntNodePtr search(IntNodePtr head, int target); //Tiền điều kiện: con trỏ head trỏ tới đầu //danh sách liên kết. Con trỏ ở nút cuối cùng là NULL. //Nếu danh sách là rỗng, head là NULL //Trả về con trỏ trỏ tới nút đầu tiên chứa mục tiêu //Nếu không thấy, trả về NULL  Duyệt danh sách ◦ Tương tự như duyệt mảng 21
  22. Mã giả cho hàm search  while (here không trỏ tới nút mục tiêu hoặc nút cuối cùng) { Làm here trỏ tới nút tiếp theo trong danh sách liên kết } if (nút here trỏ tới mục tiêu) return here; else return NULL; 22
  23. Thuật toán cho hàm search  while (here->getData() != target && here->getLink() != NULL) here = here->getLink(); if (here->getData() == target) return here; else return NULL;  Phải xét thêm trường hợp đặc biệt khi danh sách rỗng 23
  24. Ngăn xếp  Cấu trúc dữ liệu ngăn xếp ◦ Nhận dữ liệu theo trật tự ngược lại của cách lưu trữ ◦ LIFO – vào sau/ra trước ◦ Hình dung giống như cái hố trên mặt đất  Ngăn xếp được sử dụng cho nhiều công việc ◦ Theo dõi lời gọi hàm C++ ◦ Quản lý bộ nhớ  Chúng ta sử dụng danh sách liên kết để thi hành ngăn xếp 24
  25. Ngăn xếp 25
  26. Giao diện cho lớp khuôn mẫu ngăn xếp 26
  27. Giao diện cho lớp khuôn mẫu ngăn xếp 27
  28. Chương trình sử dụng lớp khuôn mẫu ngăn xếp 28
  29. Chương trình sử dụng lớp khuôn mẫu ngăn xếp 29
  30. Chương trình sử dụng lớp khuôn mẫu ngăn xếp 30
  31. Ngăn xếp: Push và Pop  Thêm mục dữ liệu vào ngăn xếp push ◦ Được xem là đưa dữ liệu vào trong ngăn xếp ◦ Đi vào đỉnh của ngăn xếp  Loại bỏ mục dữ liệu từ ngăn xếp pop ◦ Được xem là lấy dữ liệu khỏi ngăn xếp ◦ Loại bỏ từ đỉnh của ngăn xếp 31
  32. Hàng đợi  Một cấu trúc dữ liệu phổ biến khác ◦ Vận hành dữ liệu theo cách thức vào trước/ra trước (FIFO) ◦ Các mục được chèn vào cuối danh sách ◦ Các mục được loại bỏ từ đầu danh sách  Biểu diễn dạng dòng điển hình ◦ Giống như dòng máy đếm tiền ở ngân hàng, dòng xếp hàng ở rạp chiếu phim, vân vân. 32
  33. Giao diện cho lớp khuôn mẫu hàng đợi 33
  34. Giao diện cho lớp khuôn mẫu hàng đợi 34
  35. Giao diện cho lớp khuôn mẫu hàng đợi 35
  36. Chương trình sử dụng lớp khuôn mẫu hàng đợi 36
  37. Lớp bạn  Việc sử dụng liên tục các hàm truy cập và biến đổi getLink và setLink: ◦ Có đôi chút trở ngại ◦ So sánh với việc làm cho dữ liệu public?  Sử dụng lớp bạn ◦ Làm cho lớp khuôn mẫu hàng đợi là bạn của lớp khuôn mẫu nút ◦ Tất cả các thành viên liên kết private cung cấp trực tiếp trong các hàm thành viên của lớp hàng đợi 37
  38. Khai báo tiến  Mối quan hệ bạn bè đòi hỏi các lớp tham chiếu lẫn nhau ◦ Biểu diễn vấn đề ◦ Làm thế nào để cả hai có thể được khai báo cùng một lúc  Đòi hỏi khai báo tiến ◦ Tiêu đề lớp này nằm bên trong lớp kia class Queue; //Khai báo tiến. ◦ Thông báo “lớp Queue tồn tại” 38
  39. Biến lặp (iterator)  Cấu trúc giúp luân chuyển trên dữ liệu ◦ Giống như “duyệt” ◦ Cho phép các hành động tùy ý trên dữ liệu  Con trỏ thường được sử dụng làm biến lặp ◦ Đã sử dụng khi thi hành danh sách liên kết 39
  40. Con trỏ làm biến lặp  Danh sách liên kết: cấu trúc dữ liệu nguyên mẫu  Con trỏ: ví dụ nguyên mẫu về biến lặp ◦ Con trỏ được sử dụng làm biến lặp bằng việc di chuyển qua từng nút của danh sách liên kết bắt đầu từ head ◦ Ví dụ: Node_Type *iterator; for (iterator = Head; iterator != NULL; iterator=iterator->Link) Do_Action 40
  41. Lớp iterator  Đa năng hơn con trỏ  Các thao tác được nạp chồng điển hình ++ tiến biến lặp tới mục tiếp theo lùi biến lặp về mục phía trước == so sánh các biến lặp != so sánh khác * truy cập một mục  Lớp cấu trúc dữ liệu có các thành viên: begin(): trả biến lặp về mục đầu tiên trong cấu trúc end(): trả về biến lặp để kiểm tra xem có đang ở mục cuối cùng trong cấu trúc không 41
  42. Ví dụ lớp iterator  Luân chuyển trên cấu trúc dữ liệu tên là ds: for (i=ds.begin();i!=ds.end();i++) process *i //*i là mục dữ liệu hiện thời  i là tên của biến lặp 42
  43. Tóm tắt  Nút là đối tượng cấu trúc hoặc đối tượng lớp ◦ Một hoặc nhiều thành viên là con trỏ ◦ Các nút được liên kết bởi các con trỏ thành viên  Tạo ra các cấu trúc có thể mở rộng hoặc co lại ở thời điểm chạy  Danh sách liên kết ◦ Danh sách các nút trong đó mỗi nút trỏ tới nút tiếp theo  Con trỏ NULL được sử dụng làm ký hiệu kết thúc danh sách liên kết 43
  44. Tóm tắt  Ngăn xếp là cấu trúc dữ liệu LIFO  Hàng đợi là cấu trúc dữ liệu FIFO  Cấu trúc biến lặp cho phép luân chuyển trên các mục dữ liệu trong một cấu trúc dữ liệu cho trước 44