Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 20 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
20
Dung lượng
1,09 MB
Nội dung
Bài 2: Danh sách BÀI 2: DANH SÁCH Mục tiêu Nội dung Sau học này, bạn có thể: Nắm khái niệm danh sách danh sách liên kết, phân biệt dạng danh sách liên kết Nắm thao tác danh sách liên kết Nắm cách cài đặt danh sách mảng danh sách liên kết Nắm cách cài đặt thao tác danh sách danh sách liên kết đơn Vận dụng cấu trúc liệu danh sách vào giải toán thực tế Khái niệm danh sách thao tác danh sách Biểu diễn danh sách mảng Danh sách liên kết Biểu diễn danh sách liên kết cấu trúc mảng Ứng dụng danh sách Thời lượng học tiết CS101_Bai2_v2.0014101214 31 Bài 2: Danh sách Trong lập trình, danh sách kiểu liệu trừu tượng hữu dụng Ở số ngôn ngữ lập trình danh sách cấu trúc liệu tiền định Như ngơn ngữ lập trình danh sách (LISP), danh sách cấu trúc liệu cung cấp LISP hay C++ danh sách xây dựng sẵn cung cấp thư viện chuẩn Tuy nhiên đa số ngôn ngữ lập trình danh sách khơng phải cấu trúc liệu tiền định kỹ thuật để xây dựng cấu trúc danh sách quan trọng Trong này, xem xét cách chi tiết danh sách tổng quát cách xây dựng danh sách dựa tảng cấu trúc liệu mảng danh sách liên kết Trong công việc hàng ngày, sử dụng danh sách thường xuyên danh sách học viên lớp, danh sách người đăng kí mua vé máy bay, danh sách người chờ khám bệnh, danh sách triển lãm tổ chức vào năm 2004 Hà Nội…v.v Trong danh sách lưu trữ thông tin mà cần quan tâm phải nhớ để phục vụ cho công việc Xét danh sách học viên lớp danh sách ghi thông tin tất học viên lớp như: họ tên, ngày tháng năm sinh, quê quán, giới tính, chỗ nay… nhằm phục vụ công tác quản lí học viên; thơng tin học viên lớp phần tử danh sách Do số học viên lớp hữu hạn nên danh sách có số phần tử hữu hạn Thơng tin học viên danh sách thường xếp theo thứ tự (thường xếp theo thứ tự từ điển tên họ) để tiện cho việc quản lý Khi có thêm học viên vào lớp hay có học viên chuyển sang lớp khác danh sách học viên phải thay đổi cách bổ sung hay xóa bớt thông tin học viên Cách giải tốn trình bầy 2.1 Khái niệm danh sách thao tác danh sách 2.1.1 Khái niệm Danh sách cấu trúc liệu gồm hữu hạn phần tử có kiểu liệu xác định phần tử có mối liên hệ với Trên phương diện toán học, danh sách tập hợp hữu hạn phần tử, có thứ tự chúng có mối liên hệ tuyến tính Mối liên hệ tuyến tính phần tử danh sách trừ phần tử có phần tử đứng trước phần tử danh sách trừ phần tử cuối có phần tử đứng sau Giả sử L danh sách gồm dãy n phần tử biểu diễn sau: L = (a1, a2, , an) Ở n > phần tử (1 i n) Ta gọi số n độ dài của danh sách Như độ dài danh sách số phần tử danh sách Nếu n a1 gọi phần tử danh sách, an phần tử cuối danh sách Nếu n = tức danh sách khơng có phần tử nào, danh sách gọi rỗng 32 CS101_Bai2_v2.0014101214 Bài 2: Danh sách Một tính chất quan trọng danh sách phần tử tuyến tính: (i = 1, 2, , n) phần tử vị trí thứ i danh sách phần tử "đi trước" phần tử an + "đi sau" phần tử an – Ví dụ 2.1 Tập hợp họ tên sinh viên lớp TINHOC 28 liệt kê giấy sau: Nguyễn Trung Cang Nguyễn Ngọc Chương Lê Thị Lệ Sương Trịnh Vũ Thành Nguyễn Phú Vĩnh danh sách Danh sách gồm có phần tử, phần tử có vị trí danh sách theo thứ tự xuất Danh sách Nếu L = (a1, a2, , an) danh sách i, j vị trí, i j n danh sách L' gồm tất phần tử từ đến aj danh sách L gọi danh sách L Danh sách rỗng xem danh sách danh sách Danh sách gồm phần tử phần tử danh sách L gọi phần đầu danh sách L Phần cuối danh sách L danh sách kết thúc phần tử cuối danh sách L Dãy Một danh sách tạo thành cách loại bỏ số (có thể khơng) phần tử danh sách L gọi dãy danh sách L Ví dụ 2.2 Xét danh sách gồm số nguyên dương L = (1, 2, 3, 4, 5, 6) Khi danh sách (2, 3, 4) danh sách L Danh sách (3, 4, 5, 6) dãy L Danh sách (1, 2, 3) phần đầu, danh sách (4, 5, 6) phần cuối danh sách L 2.1.2 Các thao tác danh sách Tùy thuộc vào đặc điểm tính chất loại danh sách mà danh sách có cần có số thao tác định Mặc dù thao tác danh sách thay đổi theo ứng dụng chúng thường bao gồm thao tác sau: Tạo danh sách Trong thao tác này, đưa vào danh sách nội dung phần tử, chiều dài danh sách xác định Trong số trường hợp, cần khởi tạo giá trị trạng thái ban đầu cho danh sách Thêm phần tử vào danh sách Thao tác nhằm thêm phần tử vào danh sách, việc thêm thành cơng chiều dài danh sách tăng lên Cũng tùy thuộc vào loại danh sách CS101_Bai2_v2.0014101214 33 Bài 2: Danh sách trường hợp cụ thể mà việc thêm phần tử tiến hành đầu, cuối hay danh sách Loại bỏ bớt phần tử khỏi danh sách Ngược với thao tác thêm, thao tác loại bớt phần tử khỏi danh sách việc loại bỏ thành cơng chiều dài danh sách bị giảm Thơng thường, trước xóa bỏ phần tử phải thực thao tác tìm kiếm phần tử cần loại bỏ Tìm kiếm phần tử danh sách Thao tác vận dụng thuật tốn tìm kiếm để tìm kiếm phần tử danh sách thỏa mãn tiêu chuẩn (thường tiêu chuẩn giá trị) Cập nhật (sửa đổi) giá trị cho phần tử danh sách Thao tác nhằm thay đổi nội dung phân tử danh sách Tương tự thao tác loại bỏ, trước thay đổi thường phải thực thao tác tìm kiếm phần tử cần thay đổi Sắp xếp thứ tự phần tử danh sách Trong thao tác vận dụng thuật toán xếp để phần tử danh sách theo trật tự Tách danh sách thành nhiều danh sách Thao tác thực việc chia danh sách thành nhiều danh sách theo qui định Kết sau chia tổng chiều dài danh sách phải chiều dài danh sách ban đầu Nhập nhiều danh sách thành danh sách Ngược với thao tác chia, thao tác tiến hành nhập nhiều danh sách thành danh sách có chiều dài tổng chiều dài danh sách Tùy thuộc vào trường hợp yêu cầu cụ thể mà việc nhập ghép nối danh sách lại với trộn lẫn phần tử danh sách vào danh sách lớn theo trật tự định Sao chép danh sách Thao tác thực việc chép toàn nội dung từ danh sách sang danh sách khác cho sau chép ta có danh sách giống hệt nội dung Hủy danh sách Thao tác thực việc xóa bỏ tồn nội dung danh sách để thành danh sách rỗng Tùy thuộc vào loại danh sách việc xóa bỏ bao gồm việc xóa nội dung nhớ hay khơng Ví dụ 2.3 Giả sử ta có danh sách L = (3, 2, 1, 5) Ta có hàm: LisType Delete_E(int Pos,ListType List) để xóa phần tử khỏi danh sách hàm ListType Insert_E(int Pos,E_Type Item, ListType List) để thêm phần tử vào danh sách Khi đó, thực L = Delete_E(3,L) ta danh sách L = (3,2,5) Kết L = Insert_E(1,6,L) danh sách L = (6,3,2,1,5) 34 CS101_Bai2_v2.0014101214 Bài 2: Danh sách 2.2 Biểu diễn danh sách mảng Cài đặt danh sách máy tính tìm cấu trúc liệu cụ thể mà máy tính hiểu để lưu trữ phần tử danh sách đồng thời để viết chương trình thực thao tác danh sách Phương pháp tự nhiên để cài đặt danh sách sử dụng mảng, thành phần mảng lưu giữ phần tử danh sách, phần tử kế danh sách lưu giữ thành phần kế mảng Việc sử dụng mảng để biểu diễn danh sách thể hình đây: Như để biểu diễn danh sách mảng có khai báo sau : #define Max_Size N // N độ dài cực đại danh sách, N số hữu hạn typedef Kieu_du_lieu E_Type; //Đặt lại tên kiểu liệu phần tử mảng struct ListType //tên kiểu cấu trúc người lập trình đặt { E_Type Element[Max_Size]; //mảng chứa phần tử danh sách int Size; //biến đếm số phần tử danh sách } List; //khai báo List có kiểu cấu trúc vừa định nghĩa ListType Khi cài đặt danh sách qua mảng trên, thao tác danh sách thực dễ dàng Để khởi tạo danh sách rỗng, gần lệnh gán : List.Size:= 0; Và độ dài danh sách List.Size Danh sách đầy, List.Size = Max_Size Việc duyệt danh sách thực dễ ràng cách sử dụng vòng lặp với số mảng thay đổi Ví dụ để hiển thị tất phần tử danh sách ta cần sử dụng vòng lặp: for (int i=0; i= Pos-2; k ) { j = k + 1; if (k == Pos-2) List.Element[j]=Item; else List.Element[j]=List.Element[k]; } List.Size = List.Size + 1; } return List; } Nếu n độ dài danh sách; dễ dàng thấy rằng, thủ tục chèn thực thời gian (O(n): độ phức tạp tuyến tính số phép tính\thời gian chạm\dung lượng nhớ có xu hướng tỷ lệ thuận với độ lớn đầu vào) Việc cài đặt thao tác xóa địi hỏi phải dịch chuyển phần tử mảng phần tử danh sách lưu trữ vị trí liên tiếp mảng Hàm thực thao tác loại bỏ bớt phần tử khỏi danh sách: 36 CS101_Bai2_v2.0014101214 Bài 2: Danh sách // ham loai bo mot phan tu ListType Delete_E(int Pos,ListType List) { int k; if (List.Size == 0) printf("danh sach rong"); else { for (k = Pos-1; k < List.Size-1; k++) List.Element[k] = List.Element[k + 1]; List.Size = List.Size-1; } return List; } Và thời gian thực hàm O(n) Việc tìm kiếm danh sách phép tốn sử dụng thường xuyên ứng dụng Chúng ta xét riêng phép tốn phần tìm hiểu thuật tốn tìm kiếm sau Chúng ta cài đặt danh sách mảng, tức dùng mảng để lưu giữ phần tử danh sách Do tính chất mảng, phương pháp cho phép ta truy cập trực tiếp đến phần tử vị trí danh sách cách dễ dàng cần sử dụng số để định vị vị trí phần tử danh sách Tuy nhiên phương pháp không thuận tiện để thực thao tác thêm vào loại bỏ số phần tử danh sách Như trên, lần chèn phần tử vào danh sách vị trí p (hoặc loại bỏ phần tử vị trí p) ta phải đẩy xuống (hoặc lên trên) vị trí tất phần tử sau phần tử thứ p Mà không gian nhớ để lưu giữ phần tử danh sách cố định bị quy định cỡ mảng Do danh sách phát triển cỡ mảng, phép tốn chèn vào khơng thực mảng đầy Trong địi hỏi chèn xóa mục danh sách, cách cài đặt tốt dùng danh sách liên kết mô tả phần 2.3 Danh sách liên kết Danh sách dãy mục liệu nên có thứ tự gắn liền với phần tử danh sách; có phần tử đầu tiên, phần tử thứ hai… Như cách cài đặt cấu trúc liệu phải dùng phương pháp để biểu diễn thứ tự Trong cách cài đặt danh sách mảng, thứ tự phần tử danh sách biểu diễn dạng ẩn cách dùng thứ tự phần tử mảng Trong phần xem xét cách cài đặt khác danh sách thứ tự phần tử danh sách biểu diễn dạng hiển CS101_Bai2_v2.0014101214 37 Bài 2: Danh sách Khái niệm: Danh sách liên kết tập hợp phần tử gọi nút (node), nút chứa liệu phần tử danh sách trỏ vị trí nút chứa phần tử khác danh sách Con trỏ địa nhớ nút danh sách Do nút danh sách không cần phải lưu trữ liên tiếp nhớ kích thức danh sách mở rộng tùy ý (chỉ giới hạn dung lượng nhớ) Hình thể cấu trúc danh sách liên kết: Head: Con trỏ trỏ tới nút (phần tử) danh sách liên kết Như cấu tạo nút danh sách liên kết hình dung sau: Data Link Trong đó: phần Data: chứa thông tin phần tử danh sách phần Link: chứa địa nút khác danh sách Riêng nút cuối khơng có nút nên trường LINK phải chứa “địa đặc biệt”, mang tính chất quy ước, dùng để đánh dấu nút kết thúc danh sách không chứa địa nút khác, ta gọi “địa null” hay “con trỏ rỗng” (null pointer) Ví dụ 2.5 Ta có danh sách tên sinh viên Bây ta muốn đưa danh sách theo thứ tự “từ điển” ta tổ chức móc nối sau: STT Data Link Công Hiệp Anh Đồng Một danh sách liên kết chứa tên sinh viên theo thứ tự “từ điển” biểu diễn sau: 38 CS101_Bai2_v2.0014101214 Bài 2: Danh sách Trong sơ đồ mũi tên thể liên kết nút List vào nút danh sách Nút có địa (chính số thứ tự tên sinh viên danh sách thực), dựa vào trường LINK ta biết nút có địa 1, sau nút nút 4, sau nút nút 2, sau nút khơng cịn nút nào: nút kết thúc danh sách nên khơng có mũi tên phần tử khơng có phần tử Chú ý Không nên nhầm lẫn danh sách danh sách liên kết Danh sách danh sách liên kết hai khái niệm hoàn toàn khác Danh sách mơ hình liệu, cài đặt cấu trúc liệu khác Còn danh sách liên kết cấu trúc liệu, sử dụng để biểu diễn danh sách Do thao tác danh sách thực danh sách liên kết Khi dùng danh sách liên kết để biểu diễn danh sách, tùy thuộc vào mức độ cách thức kết nối nút danh sách liên kết mà danh sách liên kết chia thành nhiều loại: Danh sách liên kết đơn Danh sách liên kết đơn danh sách liên kết bao gồm nút nối với theo chiều Mỗi nút gồm hai gồm hai thành phần: Thành phần thứ chứa giá trị lưu nút o Thành phần thứ hai chứa trỏ (địa chỉ) tới nút danh sách, nghĩa chứa thông tin đủ để nhận biết nút danh sách nút Trong trường hợp nút cuối cùng, trường liên kết gán giá trị đặc biệt (gọi trỏ rỗng null) Cấu tạo nút liên kết đơn thể hình đây: o Và cấu trúc danh sách liên kết đơn thể qua hình sau: Danh sách liên kết đôi/ kép Danh sách liên kết kép danh sách liên kết mà nút danh sách ngồi thành phần liệu cịn có hai trỏ, trỏ tới nút kế tiếp, trở đến nút liền trước Như danh sách liên kết kép nút gồm ba thành phần: o Thành phần thứ chứa giá trị lưu nút o Thành phần thứ hai trỏ chứa liên kết tới nút (con trỏ Link), nghĩa chứa thông tin đủ để nhận biết nút danh sách nút Trong trường hợp nút cuối cùng, trường liên kết gán giá trị đặc biệt (gọi trỏ rỗng null) CS101_Bai2_v2.0014101214 39 Bài 2: Danh sách o Thành phần thứ ba trỏ chứa liên kết tới nút liền trước (Con trỏ Prev), nghĩa chứa thông tin đủ để nhận biết nút liền trước nút danh sách nút Trong trường hợp nút đầu tiên, trường liên kết gán giá trị đặc biệt (gọi trỏ rỗng null) Cấu trúc danh sách liên kết kép thể hình đây: Danh sách liên kết vòng đơn Trong danh sách liên kết đơn, trường liên kết nút cuối gán giá trị đặc biệt Nếu ta cho trường liên kết nút cuối trỏ thẳng nút danh sách ta kiểu danh sách liên kết gọi danh sách liên kết vòng đơn Cấu trúc danh sách liên kết vịng đơn mơ tả hình Danh sách liên kết vịng kép Danh sách liên kết vòng kép danh sách liên liên kết kép trường hợp trỏ Prev nút danh sách trỏ thẳng đến nút cuối danh sách trỏ Link nút cuối danh sách thẳng đến nút danh sách Cấu trúc danh sách liên kết vịng kép mơ tả hình đây: Vấn đề quan trọng cài đặt danh sách liên kết Để cài đặt danh sách liên kết, phải thực cơng việc sau: Dùng cách để chia nhớ thành nút, nút có thành phần liệu phần liên kết cách đặt cho trỏ Các thao tác để truy cập tới giá trị lưu nút Dùng cách để ghi dấu nút dùng nút tự do, để truyền nút hai vùng nói Danh sách liên kết Vấn đề quan trọng cài đặt danh sách liên kết Để cài đặt danh sách liên kết, phải thực công việc sau: 40 CS101_Bai2_v2.0014101214 Bài 2: Danh sách Dùng phương tiện để chia nhớ thành nút, nút có thành phần liệu phần liên kết cách đặt cho trỏ o Các thao tác để truy cập tới giá trị lưu nút o Dùng phương tiện để ghi dấu nút dùng nút tự do, để truyền nút hai vùng nói Danh sách liên kết cấu trúc liệu tiền định đa số ngơn ngữ lập trình, phải tiến hành cài đặt danh sách liên kết dựa vào cấu trúc tiền định khác Trong danh sách liên kết đơn, nút gồm hai thành phần: phần liệu để lưu thông tin phần tử danh sách phần liên kết đến nút danh sách trỏ rỗng Cấu trúc danh sách liên kết thiết lập khai báo sau: o Kieu_du_lieu ElementType; typedef struct NodeType { ElementType Data; struct NodeType *Link; } NodeType *List; Hàm thực thao tác kiểm tra danh sách có rống hay khơng cài đặt sau: int Empty(NodeType *List) { int empty; emty = 0; if (List == NULL) emty = 1; else emty = 0; return emty; } Để thực thao tác duyệt phần tử danh sách ta tiến hành cài đặt theo thuật toán đây: void Traverse( NodeType *List) { NodeType *Currp; Currp = List; while (Currp!=NULL) { printf("&f", Currp->Data); Currp =Currp->Link; } } CS101_Bai2_v2.0014101214 41 Bài 2: Danh sách Xây dựng thao tác thêm nút vào danh sách liên kết: Để chèn phần tử vào danh sách liên kết, trước hết ta phải tạo nút chứa phần tử cần chèn ta truy cập tới nút Trong thủ tục nút truy cập trỏ liệu nút chứa giá trị phần tử cần chèn Bước cần phải xác định xem nút chèn đầu danh sách hay sau phần tử cho trước danh sách Nếu chèn vào đầu danh sách, trước hết ta phải đặt trường liên kết nút chỏ tới nút danh sách sau đặt lại trỏ trỏ đến nút trước trỏ vào nút thêm vào Quá trình thêm nút nút vào đầu danh sách liên kết thực sau: Bước 1: Đặt Link(TempPtr) List Bước 2: Đặt List TempPtr Chú ý Việc chèn nút vào đầu danh sách phải thực theo thứ tự ta đặt List TempPtr trước, sau gắn Link(TempPtr) = List làm cho phần liên kết nút vào khơng đến nút danh sách liên kết, điều làm ta không truy cập đến danh sách ban đầu Trong trường hợp thứ hai, chèn nút vào sau nút danh sách ta đặt trỏ trường liên kết nút trỏ đến nút mà trỏ nút vị trí chén trỏ tới 42 CS101_Bai2_v2.0014101214 Bài 2: Danh sách Sau đặt trỏ trường liên kết nút định trỏ đến nút Chú ý Việc chèn phải thực theo thứ tự để tránh việc phần danh sách Từ ta có thuật tốn thêm nút vào danh sách liên kết: Thuật toán để thêm phân tử Item vào danh sách liên kết với nút trỏ trỏ List nút thứ PrevPtr Nếu PrevPtr = 0, nút thêm vào đầu danh sách void Insert(NodeType*List,ElementType Item,NodeType *PrevPtr) { NodeType *TempPtr; TempPtr=GetNode(Item); //tạo nút để chèn vào danh sách if (List==NULL) { List=TempPtr; TempPtr->Link=NULL; } else { TempPtr->Link=PrevPtr->Link; PrevPtr->Link=TempPtr; } } Trong thủ tục GetNode trả trỏ P vào nút tự do; khơng cịn P trả giá trị Null (P = NodeType* GetNode(ElementType Item) { NodeType *p = new NodeType; p->Data = Item; p->Link = NULL; return p; } CS101_Bai2_v2.0014101214 43 Bài 2: Danh sách Một trường hợp đặc biệt danh sách liên kết rỗng thao tác chèn thực trường hợp chèn vào đầu danh sách nút chèn vào nút danh sách Vì List có giá trị null danh sách rỗng nên sau thao tác đặt Link(TempPtr) null điều nút khơng có phần tử Thao tác thứ hai đặt List vào nút danh sách Trường hợp đặc biệt khác chèn vào cuối danh sách khơng rỗng qua thủ tục ta tiến hành chèn nút vào danh sách Vì trường liên kết nút null điều báo hiệu nút thêm vào nút cuối danh sách trường liên kết nút cuối danh sách cũ vào nút thêm vào Đối với thao tác xóa ta phải xét đến hai trường hợp: Trường hợp xóa nút danh sách liên kết, ta cần đặt trỏ List vào nút thứ hai danh sách sau tiến hành xóa nút Trường hợp xóa nút đứng sau nút PrevPtr, ta cần đặt phần liên kết nút đứng trước nút địng xóa vào nút sau nút định xóa tiến hành xóa nút muốn xóa Thuật tốn xóa nút danh sách liên kết: void Deletefromlist(NodeType *List,NodeType *PrevPtr) { NodeType * TempPtr; if (List == NULL) printf("danh sach rong"); else { if (PrevPtr == NULL) { TempPtr = List; List = TempPtr->Link; } else { TempPtr = PrevPtr -> Link; PrevPtr -> Link = TempPtr -> Link; } DeleteNode(List,TempPtr); } } 44 CS101_Bai2_v2.0014101214 Bài 2: Danh sách Trong thủ tục DeleteNode cài đặt sau: void Delete(NodeType *List,NodeType *PrevPtr) { NodeType *p; if (List == NULL) printf("danh sach rong"); else { p = List; while (p -> Link != PrevPtr) p = p -> Link; p -> Link = PrevPtr -> Link; free(PrevPtr); } } Các thao tác chèn xóa danh sách liên kết thực sở ta biết rõ vị trí để chèn vào hay vị trí nút định xóa Tuy nhiên nhiều trường hợp muốn xóa nút từ danh sách liên kết hay chèn nút vào sau nút ta biết trường giá trị nút cần phải có phương pháp định vị trỏ PrePtr mà nút tới nút danh sách Trong trường hợp ta sử dụng thuật tốn sau để tìm kiếm tuyến tính danh sách liên kết Thuật tốn tìm kiếm: tìm nút chứa Item danh sách liên kết có nút List Nếu tìm nút chứa Item giá trị Logic Found đặt đúng, trỏ CurrPtr tới nút trỏ PrevPtr tới nút đứng sau hay null Nếu khơng có Found đặt giá trị sai //Bước 1: Đặt Currptr = List; PrevPtr = Found = 0; //Bước 2: while (Found = =0) && (CurrPtr != NULL) { if (CurrPtr -> Data = Item) Found = 0; else { PrevPtr = CurrPtr; CurrPtr = CurrPtr -> Link; } } CS101_Bai2_v2.0014101214 45 Bài 2: Danh sách Thủ tục cài đặt thuật toán tìm kiếm danh sách liên kết thực sau: int SearchOfList(NodeType *List,ElementType Item) { int Found; Found=0; NodeType *PrevPtr; NodeType *CurrPtr; CurrPtr = List; PrevPtr=NULL; while ((Found==0)&&(CurrPtr != NULL)) { if (CurrPtr->Data ==Item) Found=1; else { PrevPtr = CurrPtr; CurrPtr = CurrPtr->Link; } } return Found; } 2.4 Ứng dụng danh sách Danh sách ứng dụng nhiều cấu trúc liệu mảng: mảng chiều, mảng nhiều chiều; mảng cấp phát tĩnh, mảng cấp phát động; … mà nghiên cứu thao tác nhiều ngơn ngữ lập trình Dưới số ứng dụng danh sách: Các phép tính số học đa thức Trong mục ta xét phép tính số học (cộng, trừ, nhân, chia) đa thức ẩn Các đa thức ẩn biểu thức có dạng: P(x) = anxn + an – 1xn – + … + a1x + a0 (1) Mỗi hạng thức đa thức đặc trưng hệ số (coef) số mũ x (exp) Giả sử hạng thức đa thức xếp theo thứ tự giảm dần số mũ, đa thức (1) Rõ ràng ta nhìn nhận đa thức danh sách tuyến tính hạng thức Khi ta thực phép toán đa thức ta nhận đa thức có bậc khơng thể đốn trước (bậc đa thức số mũ cao hạng thức đa thức) Ngay với đa thức có bậc xác định số hạng thức biến đổi nhiều từ đa thức đến đa thức khác Để biểu diễn đa thức, máy tính, ta chọn lưu trữ dạng danh sách gồm phần tử tuyến tính hay danh sách liên kết Với cách lưu dạng danh sách tuyến tính, nghĩa lưu trữ phần thông tin cần thiết ứng với số hạng đa thức phần tử danh sách lưu trữ Chú ý rằng: số hạng aixi đa thức với n i ta phải xác định hệ số số mũ i 46 CS101_Bai2_v2.0014101214 Bài 2: Danh sách Nhưng phần tử danh sách lưu trữ, thường ghi nhận giá trị thơi, phần tử danh sách lưu trữ ghi nhận giá trị hệ số hệ số a1 số mũ i phải ẩn dụ thứ tự phần tử Và điều cịn tùy thuộc vào kích thước danh sách, kích thước danh sách n + ta lưu trữ đa thức với số mũ tối đa n V[1] lưu trữ giá trị an V[2] lưu trữ giá trị an – …………………… V[n] lưu trữ giá trị a0 Bất kỳ đa thức phải lưu trữ theo quy ước Khi biểu diễn đa thức danh sách tuyến tính ta thấy ưu điểm lớn phép toán đa thức thực dễ dàng Nhưng bên cạnh xuất nhược điểm lớn Trước hết kích thước ấn định cho danh sách lưu trữ phụ thuộc vào số mũ lớn số hạng có đa thức Nếu đa thức có mũ cao, lại số hạng, chẳng hạn: A(x) = 15x1000 – x rõ ràng phải dùng danh sách với kích thước 1001 phần tử để thực lưu trữ Như lãng phí nhớ làm thời gian thực phép toán diễn chậm chạp Để khắc phục nhược điểm lưu trữ danh sách tuyến tính nêu trên, ta dùng danh sách liên kết để lưu trữ đa thức Với lưu trữ đa thức biển diển dạng danh sách nối đơn mà nút có quy cách sau : nút có trường : Trường COEF chứa hệ số khác không mổi số hạng đa thức Trường EXP chứa số mũ tương ứng Trường LINK chứa địa nút danh sách Ví dụ: A(x) = 2x8 – 5x7 + 3x2 + 4x – Với đa thức A(x) danh sách biểu diễn có dạng : Ở A trỏ, trỏ tới nút danh sách Với cách lưu trữ đa thức có số hạng với hiệu số khác không, danh sách nối đơn biểu diễn có nhiêu nút Bây ta xét tới giải thuật thực cộng đa thức A(x) B(x) Giả sử danh sách biểu diễn chúng tạo lập máy trỏ biến trỏ A B Ta gọi C trỏ, trỏ tới danh sách biểu diễn đa thức tổng Rõ ràng phải dùng biến trỏ p q để thăm nút, duyệt qua danh sách Khi ta thấy có tình sau : 1) Nếu EXP(p) = EXP(q) ta phải thực cộng giá trị trường COEF nút Nếu giá trị tổng khác khơng phải tạo nút để biểu diễn số hạng tương ứng bổ sung vào (gọi tắt “gắn vào”) danh sách tổng CS101_Bai2_v2.0014101214 47 Bài 2: Danh sách 2) Nếu EXP (p) >EXP (q), nghĩa danh sách B khơng có số hạng số mũ với p danh sách A (Ngược lại EXP(q) > EXP (p) xử lí tương tự) Như phải chép thông tin nút p vào nút gắn vào danh sách tổng 3) Nếu danh sách kết thúc trước nút lại danh sách chép vào nút “gắn vào” danh sách tổng Mỗi lần nút tạo gắn vào sau nút cuối danh sách tổng (ta gọi tắt nút “đuôi” danh sách tổng) Như vậy, phải thường xuyên nắm địa nút này, ta gọi d Ta thấy công việc : “– Xin cấp phát nút Sao chép thông tin vào trường COEF EXP nút “Gắn” nút vào sau nút trỏ d , lại biến thành nút mới” lặp lại nhiều lần q trình xử lí Vì ta viết dạng chương trình “gọi nó” cần sử dụng 48 CS101_Bai2_v2.0014101214 Bài 2: Danh sách TÓM LƯỢC CUỐI BÀI Trong xem xét đến cấu trúc trừu tượng danh sách với cách cài đặt quan trọng danh sách là: mảng liên kết Trong cách cài đặt mảng có ích cho nhiều toán xử lý danh sách nhiều ứng dụng ưu tiên cài đặt danh sách Ví dụ, xếp thứ tự tìm kiếm địi hỏi truy cập trực tiếp đến phần tử danh sách điều thực cài đặt mảng Cài đặt mảng thích hợp với danh sách có độ dài cực đại biết trước độ dài thực tế khơng bị thay đổi nhiều q trình xứ lý với danh sách địi hỏi thao tác chèn xóa hay có xẩy hai đầu danh sách Tuy nhiên, cách cài đặt mảng có điểm yếu khai báo mảng có độ dài xác Hay nói cách khác độ dài danh sách bị giới hạn Nếu khơng đốn độ dài lớn danh sách (mà điều thường khó chiều dài danh sách thường “động”) Còn ta dùng mảng có kích thước lớn để lưu danh sách thực tế danh sách có kích thước nhỏ gây lãng phí lớn nhớ Một điểm yếu khác việc phải dịch chuyển phần tử mảng thực thao tác chèn, xóa vị trí khơng phải đầu cuối danh sách Những danh sách có độ dài thay đổi thường xuyên phải thực thao tác chèn hay xóa phần tử danh sách việc cài đặt danh sách liên kết tốt Tuy nhiên cách cài đặt có số nhược điểm Một có phần tử danh sách truy cập trực tiếp, phần tử khác muốn truy cập phải qua phần tử đứng trước Hai phần nhớ bổ sung đòi hỏi cài đặt Việc cấp phát vùng nhớ cho phần tử danh sách mà cho phần liên kết để nối phần tử Hơn cài đặt danh sách liên kết sở mảng chiều dài danh sách liên kết bị hạn chế Để khác phục hạn chế dùng trỏ để cài đặt cho danh sách liên kết, kích thước danh sách liên kết bị giới hạn nhớ lưu trữ CS101_Bai2_v2.0014101214 49 Bài 2: Danh sách BÀI TẬP Dựa vào cài đặt danh sách liên kết đơn Hãy dùng mảng để cài đặt cấu trúc liệu danh sách liên kết đôi Một danh sách liên kết dùng cài đặt mảng để lưu trữ ký tự theo sơ đồ đây: Chỉ số mảng Data Link J z C p B M K 8 Q 9 ? 10 10 ? Với List = 5, Free = a) Viết phần tử danh sách xếp theo thứ tự b) Viết nút vùng lưu trữ theo thứ tự từ điển chúng nối với Viết thủ tục để: nhập vào dãy số nguyên nhập từ bàn phím, lưu trữ danh sách liên kết dạng mảng theo thứ tự nhập vào Viết thủ tục nhập vào từ bàn phím dãy số nguyên, lưu trữ danh sách liên kết có thứ tự không giảm, theo cách sau: Với phần tử nhập vào chương trình phải tìm vị trí thích hợp để xen vào danh sách cho thứ tự n Đa thức: P(x)= a0 + a1x + a2x + … + anx , lưu trữ máy tính dạng danh sách liên kết mà phần tử danh sách ghi có ba trường lưu giữ hệ số, số mũ, trưòng NEXT trỏ đến phần tử Chú ý cách lưu trữ đảm bảo thứ tự giảm dần theo số mũ hạng tử đa thức Ví dụ: đa thức – x + lưu trữ danh sách có phần tử sau: a) Viết khai báo cho cài đặt đa thức máy tính b) Viết thủ tục nhập thông tin đa thức dựa vào cách lưu trữ c) Viết thủ tục cài đặt phép cộng đa thức 50 CS101_Bai2_v2.0014101214