Danh sách trong một mô hình dữ liệu
Chơng danh sách Trong chơng này, nghiên cứu danh sách, mô hình liệu quan trọng nhất, đợc sử dụng thờng xuyên thuật toán Các phơng pháp khác để cài đặt danh sách đợc xét Chúng ta phân tích hiệu phép toán danh sách cách cài đặt Hai kiểu liệu trừu tợng đặc biệt quan trọng stack (ngăn xếp) hàng (hàng đợi) đợc nghiên cứu Chúng ta trình bày số ứng dụng danh sách 3.1 Danh sách lớp đối tợng Chẳng hạn, ta Về mặt toán học, danh sách dÃy hữu hạn phần tử thuộc nói đến danh sách sinh viên lớp, danh sách số nguyên đó, danh sách báo xuất hàng ngày thủ đô, Giả sử L danh sách có n (n 0) phÇn tư) phÇn tư L = (a1, a2, , an) Ta gọi số n độ dài của danh sách Nếu n a1 đợc gọi phần tử danh sách, an phần tử cuối danh sách Nếu n = 0) phần tử tức danh sách phần tử nào, danh sách đợc gọi rỗng Một tính chất quan trọng danh sách phần tử đợc tuyến tính : n > phần tử a i "đi trớc" phần tử ai+1 hay "đi sâu" phần tử với i = 1,2, , n-1 Ta sÏ nãi a i (i = 1,2, , n) phần tử vị trí thứ i danh sách Cần ý rằng, đối tợng xuất nhiều lần danh sách Chẳng hạn nh danh sách số ngày tháng năm (31, 28, 31, 30) phÇn tư, 31, 30) phÇn tư, 31, 31, 30) phÇn tử, 31, 30) phần tử, 31) Danh sách Nếu L = (a1, a2, , an) danh sách i, j vị trí, i j n danh sách L' = (b1, b2, , bj-i+1) ®ã b1 = , b2 = ai+1) bj-i+1=aj, Nh vËy, danh s¸ch L' gồm tất phần tử từ a i đến aj danh sách L Danh sách rỗng đợc xem danh sách danh sách Danh sách gồm phần tử phần tử danh sách L đợc gọi phần đầu (prefix) danh sách L Phần cuối (postfix) danh sách L danh sách kết thúc phần tử cuối cïng cđa danh s¸ch L D·y Mét danh s¸ch đợc tạo thành cách loại bỏ số (có thể không) phần tử danh sách L đợc gọi dÃy danh sách L Ví dụ XÐt danh s¸ch L = (black, blue, green, cyan, red, brown, yellow) 32 Khi danh sách (blue, green, cyan, red) danh sách L Danh sách (black, green, brown) dÃy L Danh sách (black, blue, green) phần đầu, danh sách (red, brown, yellow) phần cuối danh sách L Các phép toán danh sách Chúng ta đà trình bày khái niệm toán học danh sách Khi mô tả mô tả mô hình liệu, cần xác định phép toán thực mô hình toán học đợc dùng làm sở cho mô hình liệu Có nhiều phép toán danh sách Trong ứng dụng, thông thờng sử dụng nhóm phép toán Sau số phép toán danh sách Giả sử L danh sách (List), phần tử có kiểu liệu Item đó, p vị trí (position) danh sách Các phép toán đợc mô tả thủ tục hàm Khởi tạo danh sách rỗng procedure Initialize (var L : List) ; Xác định độ dài cđa danh s¸ch function Length (L : List) : integer Loại phần tử vị trí thứ p danh s¸ch procedure Delete (p : position ; var L : List) ; Xen phần tử x vào danh sách sau vị trí thứ p procedure Insert After (p : position ; x : Item ; var L: List) ; Xen phần tử x vào danh sách trớc vÞ trÝ thø p procedure Insert Before (p : position ; x : Item ; var L:List) ; T×m xem danh sách có chứa phần tử x hay kh«ng ? procedure Search (x : Item ; L : List : var found : boolean) ; KiÓm tra danh sách có rỗng không ? function Empty (L : List) : boolean ; KiĨm tra danh s¸ch cã đầy không ? function Full (L : List) : boolean ; Đi qua dah sách Trong nhiều áp dụng cần phải qua danh sách, từ đầu đến hết danh sách, thực nhóm hành động với phần tử danh sách procedure Traverse (var L : List) ; 10) phÇn tư Các phép toán khác Còn kể nhiều phép toán khác Chẳng hạn truy cập đến phần tử vị trí thứ i danh sách (để tham khảo thay thế), kết hợp hai danh sách thành danh sách, phân tích danh sách thành nhiều danh sách, Ví dụ : Giả sử L danh sách L = (3,2,1,5) Khi đó, thực Delete (3,L) ta đợc danh sách (3,2,5) Kết InsertBefor (1, 6, L) danh sách (6, 3, 2, 1, 5) 33 3.2 Cài đặt danh sách bới mảng Phơng pháp tự nhiên để cài đặt danh sách sử dụng mảng, thành phần mảng lu giữ phần tử danh sách, phần tử kế danh sách đợc lu giữ thành phần kế mảng Giả sử độ dài tối đa danh sách (maxlength) số N đó, phần tử danh sách có kiểu liệu Item Item kiểu liệu đơn, liệu có cấu trúc, thông thờng Item ghi Chúng ta biểu diễn danh sách (List) ghi gồm hai trờng Trờng thứ mảng Item phần tử thứ i danh sách đợc lu giữ thành phần thứ i mảng Trờng thứ hai ghi số thành phần mảng lu giữ phần tử cuối danh sách (xem hình 3.1) Chóng ta cã c¸c khai b¸o nh sau : const maxlength = N ; type List = record element : array [1 maxlength] of Item ; count : 0) phÇn tư maxlength ; end ; var L : List ; phÇn tư thø nhÊt phÇn tử thứ hai danh sách Count phần tử cuối rỗng maxlength Hình 3.1 Mảng biểu diễn danh sách 34 Trong cách cài đặt danh sách mảng, phép toán danh sách đợc thực dễ dàng Để khởi tạo danh sách rỗng, gần lệnh gán : L.count : = 0) phần tử ; Độ dài danh sách L.count Danh sách đầy, L.count = maxlength Sau thủ tục thực phép toán xen phần tử vào danh sách loại phần tử khỏi danh sách Thủ tục loại bỏ procedure Delete (p : maxlength ; var L : List ; var OK : boolean) ; var i : maxlength ; begin OK : = false ; with L if p < = count then begin i : = p; while i < count begin element [i] : = element [i + 1] ; i: = i + end ; count : = count -1 ; OK : = true ; end ; end ; Thủ tục thực phép loại bỏ phần tử vị trí p khỏi danh sách Phép toán đợc thực danh sách không rỗng p vào phần tử danh sách Tham biến OK ghi lại phép toán có đợc thực thành công hay không Khi loại bỏ, phải dồn phần tử vị trí p+1, p + 2, lên vị trí Thủ tục xen vµo procedure InsertBefore (p : maxlength ; x : Item ; var L : List ; var OK : boolean) ; var i : maxlength ; 35 begin OK: = false ; with L if (count < maxlength) and ( p p begin element[i]:= element[i-1] ; i:=i-1 ; end ; element [p] : = x ; count : = count + ; OK : = true ; end ; end ; Thủ tục thực việc xen phần tử x vào trớc phần tử vị trí p danh sách Phép toán đợc thực danh sách cha đầy (count < maxlength) p vào phần tử danh sách (p L.element [m].key, ta tiÕp tơc t×m kiÕm nưa cuối danh sách từ vị trị m + đến vị trí n Nếu đến thời điểm đó, ta phải tìm x danh sách rỗng, điều có nghĩa danh sách phần tử với khoá x Chúng ta mô tả phơng pháp tìm kiếm nhị phân thđ tơc sau : procedure BinarySearch (var L : List ; x : key type ; var found : boolean ; p : max) ; Ký hiÖu a phần nguyên a, tức số nguyên lớn nhỏ a ; chẳng hạn = 5, 5.2 = a số nguyên nhỏ lớn chẳng hạn 6.3 = 7, = 38 var mid , bottom, top : integer ; begin (1) found : = false ; (2) bottom : = 1, (3) top : = L.count ; (4) while (not found) and (bottom