Danh sách (list)

65 298 0
Danh sách (list)

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật Chương 4: DANH SÁCH (LIST) 4.1 Khái niệm danh sách Danh sách tập hợp phần tử có kiểu liệu xác định chúng có mối liên hệ Số phần tử danh sách gọi chiều dài danh sách Một danh sách có chiều dài danh sách rỗng 4.2 Các phép toán danh sách Tùy thuộc vào đặc điểm, tính chất loại danh sách mà loại danh sách có cần thiết có số phép toán (thao tác) định Nói chung, danh sách thường có phép toán 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 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 - Tìm kiếm phần tử danh sách: Thao tác vận dụng thuật toá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ị) - 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ỏ bớt phần tử khỏi danh sách vậy, việc loại bỏ thành công chiều dài danh sách bị giảm xuống Thông thường, trước thực thao tác thường phải thực thao tác tìm kiếm phần tử cần loại bỏ - Cập nhật (sửa đổi) giá trị cho phần tử danh sách: Thao tác nhằm sửa đổ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 để xếp phần tử danh sách theo trật tự xác định - Tách danh sách thành nhiều danh sách: Trang: 84 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật Thao tác thực việc chia danh sách thành nhiều danh sách theo tiêu thức chia 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 vào trường hợp mà việc nhập là: + Ghép nối đuôi danh sách lại với nhau, + Trộn xen 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 danh sách sang danh sách khác cho sau chép, hai danh sách có nội dung giống hệt - Hủy danh sách: Thao tác tiến hành hủy bỏ (xóa bỏ) toàn phần tử danh sách Việc xóa bỏ tùy vào loại danh sách mà xóa bỏ toàn nội dung hay nội dung lẫn không gian nhớ lưu trữ danh sách 4.3 Danh sách đặc (Condensed List) 4.3.1 Định nghóa Danh sách đặc danh sách mà không gian nhớ lưu trữ phần tử đặt liên tiếp nhớ 4.3.2 Biểu diễn danh sách đặc Để biểu diễn danh sách đặc sử dụng dãy (mảng) phần tử có kiểu liệu kiểu liệu phần tử danh sách Do vậy, cần biết trước số phần tử tối đa mảng chiều dài tối đa danh sách thông qua số nguyên Ngoài ra, chiều dài danh sách luôn biến động cần quản lý chiều dài thực danh sách thông qua biến nguyên Giả sử quy ước chiều dài tối đa danh sách đặc 10000, cấu trúc liệu để biểu diễn danh sách đặc sau: const int MaxLen = 10000; int Length; T CD_LIST[MaxLen]; // hoaëc: #define MaxLen 10000 // hoaëc: T * CD_LIST = new T[MaxLen]; Nếu sử dụng chế cấp phát động để cấp phát nhớ cho danh sách đặc cần kiểm tra thành công việc cấp phát động 4.3.3 Các thao tác danh sách đặc Ở có nhiều thao tác trình bày chương trước, không trình bày lại mà liệt kê cho có hệ thống trình bày tóm tắt nội dung thao tác Trang: 85 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật Các thao tác danh sách đặc sau: a Khởi tạo danh sách (Initialize): Trong thao tác đơn giản cho chiều dài danh sách Hàm khởi tạo danh sách đặc sau: void CD_Initialize(int &Len) { Len = 0; return; } b Tạo danh sách/ Nhập danh sách: Hàm CD_Create_List có prototype: int CD_Create_List(T M[], int &Len); Hàm tạo danh sách đặc có chiều dài tối đa MaxLen Hàm trả chiều dài thực danh sách sau tạo Nội dung hàm sau: int CD_Create_List(T M[], int &Len) { if (Len > MaxLen) Len = MaxLen; for (int i = 0; i < Len; i++) M[i] = Input_One_Element(); return (Len); } Lưu ý: Hàm Input_One_Element thực nhập vào nội dung phần tử có kiểu liệu T trả giá trị phần tử nhập vào Tùy vào trường hợp cụ thể mà viết hàm Input_One_Element cho phù hợp c Thêm phần tử vào danh sách: Giả sử cần thêm phần tử có giá trị NewValue vào danh sách M có chiều dài Length vị trí InsPos - Thuật toán: B1: IF (Length = MaxLen) Thực Bkt //Dời phần tử từ vị trí InsPos->Length sau vị trí B2: Pos = Length+1 B3: IF (Pos = InsPos) Thực B7 B4: M[Pos] = M[Pos-1] B5: Pos-B6: Lặp lại B3 B7: M[InsPos] = NewValue //Đưa phần tử có giá trị NewValue vào vị trí InsPos B8: Length++ //Tăng chiều dài danh sách lên Bkt: Kết thúc Trang: 86 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật - Cài đặt thuật toán: Hàm CD_Insert_Element có prototype: int CD_Insert_Element(T M[], int &Len, T NewValue, int InsPos); Hàm thực việc chèn phần tử có giá trị NewValue vào danh sách M có chiều dài Len vị trí InsPos Hàm trả chiều dài thực danh sách sau chèn việc chèn thành công ngược lại, hàm trả giá trị -1 Nội dung hàm sau: int CD_Insert_Element(T M[], int &Len, T NewValue, int InsPos) { if (Len == MaxLen) return (-1); for (int i = Len; i > InsPos; i ) M[i] = M[i-1]; M[InsPos] = NewValue; Len++; return (Len); } d Tìm kiếm phần tử danh sách: Thao tác sử dụng thuật toán tìm kiếm nội (Tìm tuyến tính tìm nhị phân) trình bày Chương e Loại bỏ bớt phần tử khỏi danh sách: Giả sử cần loại bỏ phần tử vị trí DelPos danh sách M có chiều dài Length (Trong số trường hợp phải thực thao tác tìm kiếm để xác định vị trí phần tử cần xóa) - Thuật toán: B1: IF (Length = OR DelPos > Len) Thực Bkt //Dời phần tử từ vị trí DelPos+1->Length trước vị trí B2: Pos = DelPos B3: IF (Pos = Length) Thực B7 B4: M[Pos] = M[Pos+1] B5: Pos++ B6: Lặp lại B3 B7: Length-//Giảm chiều dài danh sách Bkt: Kết thúc - Cài đặt thuật toán: Hàm CD_Delete_Element có prototype: int CD_Delete_Element(T M[], int &Len, int DelPos); Hàm thực việc xóa phần tử vị trí DelPos danh sách M có chiều dài Len Hàm trả chiều dài thực danh sách sau xóa việc xóa thành công ngược lại, hàm trả giá trị -1 Nội dung hàm sau: Trang: 87 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật int CD_Delete_Element(T M[], int &Len, int DelPos) { if (Len == || DelPos >= Len) return (-1); for (int i = DelPos; i < Len-1; i++) M[i] = M[i+1]; Len ; return (Len); } f Cập nhật (sửa đổi) giá trị cho phần tử danh sách: Giả sử cần sửa đổi phần tử vị trí ChgPos danh sách M có chiều dài Length thành giá trị NewValue Thao tác đơn giả việc gán lại giá trị cho phần tử cần thay đổi: M[ChgPos] = NewValue; Trong số trường hợp, trước tiên phải thực thao tác tìm kiếm phần tử cần thay đổi giá trị để xác định vị trí sau thực phép gán g Sắp xếp thứ tự phần tử danh sách: Thao tác sử dụng thuật toán xếp nội (trên mảng) trình bày Chương h Tách danh sách thành nhiều danh sách: Tùy thuộc vào yêu cầu cụ thể mà việc tách danh sách thành nhiều danh sách thực theo tiêu thức khác nhau: + Có thể phân phối luân phiên theo đường chạy trình bày thuật toán xếp theo phương pháp trộn Chương 3; + Có thể phân phối luân phiên phần danh sách cần tách cho danh sách Ở dây trình bày theo cách phân phối này; + Tách phần tử danh sách thỏa mãn điều kiện cho trước Giả sử cần tách danh sách M có chiều dài Length thành danh sách SM1, SM2 có chiều dài tương ứng SLen1, SLen2 - Thuật toán: // Kiểm tra tính hợp lệ SLen1 SLen2: SLen1 + SLen2 = Length B1: IF (SLen1 ≥ Length) B1.1: SLen1 = Length B1.2: SLen2 = B2: IF (SLen2 ≥ Length) B2.1: SLen2 = Length B2.2: SLen1 = B3: IF (SLen1 + Slen2 ≠ Length) SLen2 = Length – SLen1 B4: IF (SLen1 < 0) SLen1 = B5: IF (SLen2 < 0) SLen2 = Trang: 88 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật // Chép SLen1 phần tử đầu M vào SM1 B6: i = 1, si = B7: IF (i > SLen1) Thực B11 B8: SM1[si] = M[i] B9: i++, si++ B10: Lặp lại B7 // Chép SLen2 phần tử cuối M vào SM2 B11: si = B12: IF (i > Length) Thực Bkt B13: SM2[si] = M[i] B14: i++, si++ B15: Lặp lại B12 Bkt: Kết thúc - Cài đặt thuật toán: Hàm CD_Split có prototype: void CD_Split(T M[], int Len, T SM1[], int &SLen1, T SM2[], int &SLen2); Hàm thực việc chép nội dung SLen1 phần tử danh sách M vào danh SM1 chép SLen2 phần tử cuối danh sách M vào danh sách SM2 Hàm hiệu chỉnh lại SLen1, SLen2 cần thiết Nội dung hàm sau: void CD_Split(T M[], int Len, T SM1[], int &SLen1, T SM2[], int &SLen2) { if (SLen1 >= Len) { SLen1 = Len; SLen2 = 0; } if (SLen2 >= Len) { SLen2 = Len; SLen1 = 0; } if (SLen1 < 0) SLen1 = 0; if (SLen2 < 0) SLen2 = 0; if (SLen1 + SLen2 != Len) SLen2 = Len – SLen1; for (int i = 0; i < SLen1; i++) SM1[i] = M[i]; for (int j = 0; i < Len; i++, j++) SM2[j] = M[i]; return; } i Nhập nhiều danh sách thành danh sách: Tùy thuộc vào yêu cầu cụ thể mà việc nhập nhiều danh sách thành danh sách thực theo phương pháp khác nhau, là: Trang: 89 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật + Ghép nối đuôi danh sách lại với nhau; + Trộn xen lẫn phần tử danh sách vào danh sách lớn theo trật tự định trình bày thuật toán trộn Chương Ở trình bày cách ghép danh sách thành danh sách Giả sử cần ghép danh sách SM1, SM2 có chiều dài SLen1, SLen2 vào thành danh sách M có chiều dài Length = SLen1 + SLen2 theo thứ tự từ SM1 đến SM2 - Thuật toán: // Kiểm tra khả chứa M: SLen1 + SLen2 ≤ MaxLen B1: IF (SLen1 + SLen2 > MaxLen) Thực Bkt // Chép SLen1 phần tử đầu SM1 vào đầu M B2: i = B3: IF (i > SLen1) Thực B7 B4: M[i] = SM1[i] B5: i++ B6: Lặp lại B3 // Chép SLen2 phần tử đầu SM2 vào sau M B7: si = B8: IF (si > SLen2) Thực Bkt B9: M[i] = M2[si] B10: i++, si++ B11: Lặp lại B8 Bkt: Kết thúc - Cài đặt thuật toán: Hàm CD_Concat coù prototype: int CD_Concat (T SM1[], int SLen1, T SM2[], int SLen2, T M[], int &Len); Hàm thực việc ghép nội dung hai danh sách SM1, SM2 có chiều dài tương ứng SLen1, SLen2 danh sách M có chiều dài Len = SLen1 + SLen2 theo thứ tự SM1 đến SM2 Hàm trả chiều dài danh sách M sau ghép việc ghép thành công, trường hợp ngược lại hàm trả giá trị -1 Nội dung hàm sau: int CD_Concat (T SM1[], int SLen1, T SM2[], int SLen2, T M[], int &Len) { if (SLen1 + SLen2 > MaxLen) return (-1); for (int i = 0; i < SLen1; i++) M[i] = SM1[i]; for (int j = 0; j < SLen2; i++, j++) M[i] = SM2[j]; Len = SLen1 + SLen2; Trang: 90 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật return (Len); } j Sao chép danh sách: Giả sử cần chép nội dung dach sách M có chiều dài Length vào thành danh sách CM có chiều dài - Thuật toán: B1: i = B2: IF (i > Length) Thực Bkt B3: CM[i] = M[i] B4: i++ B5: Lặp lại B2 Bkt: Kết thúc - Cài đặt thuật toán: Hàm CD_Copy có prototype: int CD_Copy (T M[], int Len, T CM[]); Hàm thực việc chép nội dung danh sách M có chiều dài Len danh sách CM có chiều dài Hàm trả chiều dài danh sách CM sau chép Nội dung hàm sau: int CD_Copy (T M[], int Len, T CM[]) { for (int i = 0; i < Len; i++) CM[i] = M[i]; return (Len); } k Huûy danh sách: Trong thao tác này, danh sách cấp phát động tiến hành hủy bỏ (xóa bỏ) toàn phần tử danh sách toán tử hủy bỏ (trong C/C++ free/delete) Nếu danh sách cấp phát tónh việc hủy bỏ tạm thời cho chiều dài danh sách việc thu hồi nhớ ngôn ngữ tự thực 4.3.4 Ưu nhược điểm Ứng dụng a Ưu nhược điểm: Do phần tử lưu trữ liên tiếp nhớ, danh sách đặc có ưu nhược điểm sau đây: - Mật độ sử dụng nhớ danh sách đặc tối ưu tuyệt đối (100%); - Việc truy xuất tìm kiếm phần tử danh sách đặc dễ dàng phần tử đứng liền nên cần sử dụng số để định vị vị trí phần tử danh sách (định vị địa phần tử); - Việc thêm, bớt phần tử danh sách đặc có nhiều khó khăn phải di dời phần tử khác qua chỗ khác Trang: 91 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật b Ứng dụng danh sách đặc: Danh sách đặc ứ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 trình lập trình nhiều ngôn ngữ lập trình khác 4.4 Danh sách liên kết (Linked List) 4.4.1 Định nghóa Danh sách liên kết tập hợp phần tử mà chúng có nối kết với thông qua vùng liên kết chúng Sự nối kết phần tử danh sách liên kết quản lý, ràng buộc lẫn nội dung phần tử địa định vị phần tử Tùy thuộc vào mức độ cách thức nối kết mà danh sách liên kết chia nhiều loại khác nhau: - Danh sách liên kết đơn; - Danh sách liên kết đôi/kép; - Danh sách đa liên kết; - Danh sách liên kết vòng (vòng đơn, vòng đôi) Mỗi loại danh sách có cách biểu diễn phần tử (cấu trúc liệu) riêng thao tác Trong tài liệu trình bày 02 loại danh sách liên kết danh sách liên kết đơn danh sách liên kết đôi 4.4.2 Danh sách liên kết đơn (Singly Linked List) A Cấu trúc liệu: Nội dung phần tử danh sách liên kết (còn gọi nút) gồm hai vùng: Vùng liệu Vùng liên kết có cấu trúc liệu sau: typedef struct SLL_Node { T Key; InfoType Info; SLL_Node * NextNode; // Vùng liên kết quản lý địa phần tử } SLL_OneNode; Tương tự chương trước, để đơn giản giả thiết vùng liệu phần tử danh sách liên kết đơn bao gồm thành phần khóa nhận diện (Key) cho phần tử Khi đó, cấu trúc liệu viết lại đơn giản sau: typedef struct SLL_Node { T Key; SLL_Node * NextNode; // Vùng liên kết quản lý địa phần tử } SLL_OneNode; typedef SLL_OneNode * SLL_Type; Trang: 92 Giáo trình: Cấu Trúc Dữ Liệu Giải Thuật Để quản lý danh sách liên kết sử dụng nhiều phương pháp khác tương ứng với phương pháp có cấu trúc liệu khác nhau, cụ thể: - Quản lý địa phần tử đầu danh sách: SLL_Type SLList1; Hình ảnh minh hoïa: SLList1 NULL 15 10 20 18 40 35 30 - Quản lý địa phần tử đầu cuối danh sách: typedef struct SLL_PairNode { SLL_Type SLLFirst; SLL_Type SLLLast; } SLLP_Type; SLLP_Type SLList2; Hình ảnh minh họa: SLLFirst SLLLast 15 10 20 18 40 35 NULL 30 - Quản lý địa phần tử đầu, địa phần tử cuối số phần tử danh sách: typedef struct SLL_PairNNode { SLL_Type SLLFirst; SLL_Type SLLLast; unsigned NumNode; } SLLPN_Type; SLLPN_Type SLList3; Hình ảnh minh họa: SLLFirst SLLLast 15 10 20 18 40 35 NULL 30 NumNode = B Các thao tác danh sách liên kết đơn: Với cách quản lý khác danh sách liên kết đơn , thao tác có khác mặt chi tiết song nội dung có khác Do vậy, trình bày thao tác theo cách quản lý thứ (quản lý địa phần tử đầu danh sách liên kết đơn), cách quản lý khác sinh viên tự vận dụng để điều chỉnh cho thích hợp Trang: 93 ... tác thực việc chia danh sách thành nhiều danh sách theo tiêu thức chia 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... 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 vào trường hợp mà việc nhập là: + Ghép nối đuôi danh sách lại với nhau, + Trộn xen lẫn phần tử danh sách vào danh sách. .. danh sách Việc xóa bỏ tùy vào loại danh sách mà xóa bỏ toàn nội dung hay nội dung lẫn không gian nhớ lưu trữ danh sách 4.3 Danh sách đặc (Condensed List) 4.3.1 Định nghóa Danh sách đặc danh sách

Ngày đăng: 29/09/2013, 08:20

Hình ảnh liên quan

Hình ảnh minh họa: - Danh sách (list)

nh.

ảnh minh họa: Xem tại trang 10 của tài liệu.

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan