Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 12 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
12
Dung lượng
592,61 KB
Nội dung
1 Danh sách móc nối đơn gì? 1.1 Khái niệm Danh sách móc nối đơn (Singly-linked list) gồm nút nối với theo chiều Mỗi nút ghi (record) gồm hai trường: - Trường info chứa giá trị lưu nút - Trường link chứa liên kết (con trỏ) tới nút kế tiếp, tức chứa thông tin đủ để biết nút nút danh sách nút Với nút cuối (không có nút kế tiếp), trường liên kết gắn với giá trị đặc biệt, chẳng hạn trỏ nil Cấu trúc nút danh sách móc nối đơn Code Type PNode=^Node; {Kiểu trỏ tới nút} Node=Record {Kiểu biến động chứa thông tin nút} info: ; link: PNode; End; Nút (head) đóng vai trò quan trọng danh sách nối đơn Để duyệt danh sách nối đơn Để duyệt danh sách nối đơn, ta nút đầu tiên, dựa vào trường liên kết để sang nút kế tiếp, đến gặp giá trị đặc biệt (duyệt qua nút cuối) dừng lại Danh sách nối đơn 1.2 Truy cập phần tử danh sách móc nối đơn Bản thân danh sách móc nối đơn kiểu liệu trừu tượng Để cài đặt kiểu liệu trừu tượng này, dùng mảng nút (trường link chứa số nút kế tiếp) biến cấp phát động (trường link chứa trỏ trỏ tới nút kế tiếp) Tuy nhiên, việc xác định phần tử đứng thứ p danh sách bắt buộc phải duyệt từ đầu danh sách qua p nút, việc thời gian trung bình O(n) tỏ không hiệu thao tác mảng Nói cách khác, danh sách nối đơn tiện cho việc truy cập không hiệu thực nhiều phép truy cập ngẫu nhiên Tạo danh sách móc nối đơn 2.1 Ý tưởng Chúng ta bắt đầu tạo dần danh sách từ trái phải qua được, cách đề cập tới từ trái qua phải: - Đầu tiên ta tạo nút đầu tiên, nút đóng vai trò vừa nút Head - Sau từ nút thứ trở đi, lần tạo thêm nút ta gán nút trung gian nút vừa tạo Gán trường Link hợp lí theo định nghĩa danh sách nối đơn 2.2 Code {Thủ tục tạo danh sách} Procedure Readf; Var P:PNode; Begin Assign(f,fi);Reset(f); Readln(f,N,K); New(P); Read(f,P^.info); Head:=P; Q:=P; For i:=2 to n Begin New(P); P^.Next:=Nil; Read(f,P^.Info); Q^.Next:=P; Q:=P; End; Close(f); End; Chèn phần tử vào danh sách nối đơn 3.1 Ý tưởng Để chèn thêm nút chứa giá trị v vào vị trí nút p danh sách nối đơn, trước hết ta tạo nút Newnode chứa giá trị v cho nút liên kết tới p Nếu p nút danh sách (head) cập nhật head NewNode, p nút danh sách, ta tìm nút q nút đứng liền trước nút p chỉnh lại liên kết: q liên kết tới NewNode thay liên kết thẳng tới p Chèn phần tử vào danh sách nối đơn 3.2 Code {Thủ tục chèn phần tử V vào vị trí nút P} Procedure Insert(p: Pnode; const v: ); Var NewNode, q, head: Pnode; Begin New(NewNode); NewNode^.info := v; NewNode^.link := p; If head = p then head := NewNode Else Begin q := head; while q^.link q q:=q^.link; q^.link := NewNode; End; End; Việc chỉnh lại liên kết thủ tục chèn phần tử vào danh sách nối đơn thời gian O(1) Tuy nhiên, việc tìm nút đứng liền trước nút p yêu cầu phải duyệt từ đầu danh sách, việc thời gian trung bình O(n) Vậy thủ tục chèn phần tử vào danh sách nối đơn thời gian thực trung bình O(n) Xóa phần tử khỏi danh sách móc nối đơn 4.1 Ý tưởng Để xóa nút p khỏi danh sách nối đơn, gọi next nút đứng liền sau p danh sách Xét hai trường hợp: - Nếu p nút danh sách head = p ta đặt lại head = next - Nếu p nút danh sách, tìm q nút đứng liền trước nút p lại liên kết: q liên kết tới next thay liên kết tới p Việc cuối hủy nút p 4.2 Code {Thủ tục xóa nút P} Procedure Delete(p:PNode); Var next, q, head: PNode Begin Next := p^.link; If p = head then head := next Else Begin Q:= head; While q^.link p q := q^.link; Q^.link:= next; End; Dispose(P); End; Xóa phần tử khỏi danh sách nối đơn Cũng giống thủ tục chèn, thủ tục xóa phần tử khỏi danh sách nối đơn thời gian thực trung bình O(n) Biểu diễn ngăn xếp (Stack) danh sách nối đơn kiểu LIFO 5.1 Khái niệm: Ngăn xếp dạng đặc biệt danh sách mà việc bổ sung hay loại bỏ phần tử thực đầu danh sách gọi đỉnh Nói cách khác, ngăn xếp cấu trúc liệu có thao tác bản: bổ sung (push) loại bỏ phần tử (pop), việc loại bỏ tiến hành loại phần tử đưa vào danh sách Chính tính chất mà ngăn xếp gọi kiểu liệu có nguyên tắc LIFO (Last In First Out - Vào sau trước) Ta trình bày cách cài đặt ngăn xếp danh sách nối đơn biến động trỏ - Lối vào lối đỉnh Stack quản lí nút Top - Không xét trường hợp tràn Stack phụ thuộc vào nhiều thứ khác - Stack rỗng nút Top trống (nil) 5.2 Code Type PNode=^Node; Node=Record Info: ; Link: PNode; End; Var Top:PNode; Procedure StackInit; Begin Top:=Nil; End; {Nộp phần tử vào Stack đỉnh danh sách} Procedure SPUSH(V: ); Var P:PNode; Begin New(P); P^.Info:= V; P^.Link:= top; Top := p; End; {Lấy phần tử khỏi stack đỉnh danh sách} Procedure SPOP: ; Var P:PNode; Begin If Top=Nil then Writeln(‘Stack is empty’) Else Begin SPOP:=Top^.Info; P:=Top^.Next; Dispose(Top); Top:=P; End; End; BEGIN StackInit; ; END Biểu diễn hàng đợi (Queue) danh sách nối đơn kiểu FIFO: 6.1 Khái niệm: Hàng đợi cấu trúc liệu gần giống với ngăn xếp, khác với ngăn xếp nguyên tắc chọn phần tử cần lấy khỏi tập phần tử Trái ngược với ngăn xếp, phần tử lấy khỏi hàng đợi phần tử đưa vào mà phần tử lưu hàng đợi lâu Điều nghe hợp với quy luật thực tế ngăn xếp ! Quy luật hàng đợi gọi Vào trước trước (FIFO - First In First Out) Ví dụ hàng đợi có nhiều thực tế Một dòng người xếp hàng chờ cắt tóc tiệm hớt tóc, chờ vào rạp chiếu phim, hay siêu thị ví dụ hàng đợi Trong lĩnh vực máy tính có nhiều ví dụ hàng đợi Một tập tác vụ chờ phục vụ hệ điều hành máy tính tuân theo nguyên tắc hàng đợi Hàng đợi khác với ngăn xếp chỗ: phần tử đưa vào hàng đợi nằm phía cuối hàng, phần tử đưa vào ngăn xếp lại nằm đỉnh ngăn xếp Như vậy, ta định nghĩa hàng đợi dạng đặc biệt danh sách mà việc lấy phần tử, get, thực đầu (gọi đầu hàng), việc bổ sung phần tử, put, thực đầu lại (gọi cuối hàng) - Lối vào phía bên phải Queue quản lí nút L - Lối phía bên trái Queue quản lí nút R - Không xét trường hợp tràn Queue phụ thuộc vào nhiều thứ khác - Queue rỗng nút L R trống 6.2 Code Type Pnode = ^Node; Node = Record Info: ; Link: PNode; End; Var L,R: PNode; Procedure QueueInit; Begin L := Nil; End; {Lấy giá trị phần tử vị trí đầu danh sách} Function Get: ; Begin If (L=R) and (R=Nil) then Writeln(‘Queue is empty’) Else Get := L^.info; End; {Nộp phần tử vào Queue vị trí cuối cùng} Procedure QPUSH(V: ); Var P:PNode; Begin New(P); P^.Info := V; P^.Link := Nil; If L=Nil then L := P Else R^.link := P; R := P; End; {Lấy phần tử khỏi Queue đầu danh sách} Procedure QPOP: ; Var P:PNode; Begin If (L=R) and (R=Nil) then Writeln(‘Queue is empty’) Else Begin QPOP:=L^.Info; P:=L^.Link; L^.Link:=Nil; Dispose(L); L:=P; End; End; BEGIN QueueInit; ; END Bài tập ứng dụng 7.1 Bài tập minh họa Viết chương trình Dslk.pas minh hoạ cách làm việc với danh sách liên kết thuận Phần liệu phần tử slà thông tin sinh viên Type SVienPtr = ^SVien; SVien = record maso: string[6]; hoten: string[23]; next : SvienPtr; end; var L, R: SVienPtr; chon: byte; traloi: char; Procedure Bosung; var p: SVienPtr; ans: integer; Begin while true begin new(p); with p^ begin write('Ma sinh vien : '); readln(maso); write('Ho va ten : '); readln(Hoten); write('Diem trung binh: '); readln(dtb); end; p^.next:=NIL; if L=NIL then begin L:= p; R:= p end else begin R^.next:= p; R:= p end; write('Co tiep tuc khong 1/0 ? '); readln(ans); if ans=0 then break; end; end; procedure DuyetXuoi; var p: SVienPtr; begin if L = NIL then begin writeln('D.sach rong'); exit; end; p := L; while p NIL begin with p^ writeln(maso:5,' ',Hoten:25,' ',dtb:5:2); p := p^.Next; end; End; procedure ChenSau; var q,p: SVienPtr; found: boolean; masv: string[6]; begin if L NIL then begin write('Ma so SV can tim de chen : '); readln(masv); p:= L; found:= false; while (pNIL) and (not found) if p^.maso=masv then found := true else p:=p^.next; if found then begin new(q); with q^ begin write('Ma so : '); readln(maso); write('Ho ten : '); readln(Hoten); write('Diem TB :'); readln(dtb); end; q^.next:= p^.next; p^.next:= q; end else begin write('Khong tim thay '); readln; end; end; end; Procedure TimXoa; 10 var masv: string[6]; found: boolean; p,q: SVienPtr; begin write('Ma so SV can loai khoi danh sach : '); readln(masv); p:= L; if pNIL then begin found:= false; while (pNIL) and (not found) if p^.maso=masv then found := true else begin q:=p; p:=p^.next end; if found then begin if p=L then L :=p^.next else q^.next:=p^.next; if p^.next=NIL then R:=q; dispose(p) end else begin write('Khong tim thay '); readln; end; end; End; BEGIN L := NIL; repeat writeln; writeln('1 Bo sung mot sinh vien'); writeln('2 Duyet danh sach sinh vien'); writeln('3 Tim kiem mot phan tu va chen vao sau'); writeln('4 Tim kiem mot phan tu va xoa'); writeln('5 Ket thuc chuong trinh'); writeln; write('Chon chuc nang: '); readln(chon); writeln; case chon of 11 1: Bosung; 2: DuyetXuoi; 3: ChenSau; 4: TimXoa; End; Until chon=5; while LNIL Begin R:= L; L:= L^.next; Dispose(R); End; End 7.2 Bài tập tự giải Bài tập 1: Viết hàm để xác định xem danh sách liên kết cho có thứ tự tăng dần hay không theo cách: Không đệ qui đệ qui Bài tập 2: Cho danh sách liên kết đơn đại diện cho tập hợp trỏ L1 L2 Viết chương trình để hiển thị: Phần giao danh sách Phần hợp danh sách Phần hiệu danh sách Bài tập 3: Cho danh sách liên kết L1 L2 Sắp xếp lại danh sách theo thứ tự tăng dần Trộn danh sách lại thành danh sách L3 cho L3 có thứ tự tăng dần - - 12 [...]... xác định xem một danh sách liên kết đã cho có thứ tự tăng dần hay không theo 2 cách: Không đệ qui và đệ qui Bài tập 2: Cho 2 danh sách liên kết đơn đại diện cho 2 tập hợp được trỏ bởi L1 và L2 Viết chương trình để hiển thị: 1 Phần giao của 2 danh sách trên 2 Phần hợp của 2 danh sách trên 3 Phần hiệu của 2 danh sách trên Bài tập 3: Cho 2 danh sách liên kết L1 và L2 1 Sắp xếp lại 2 danh sách đó theo thứ... của 2 danh sách trên 2 Phần hợp của 2 danh sách trên 3 Phần hiệu của 2 danh sách trên Bài tập 3: Cho 2 danh sách liên kết L1 và L2 1 Sắp xếp lại 2 danh sách đó theo thứ tự tăng dần Trộn 2 danh sách đó lại thành danh sách L3 sao cho L3 vẫn có thứ tự tăng dần - - 12 ...var masv: string[6]; found: boolean; p,q: SVienPtr; begin write('Ma so SV can loai khoi danh sach : '); readln(masv); p:= L; if pNIL then begin found:= false; while (pNIL) and (not found) do if p^.maso=masv then found := true else begin q:=p; p:=p^.next end; if found then begin if p=L... q^.next:=p^.next; if p^.next=NIL then R:=q; dispose(p) end else begin write('Khong tim thay '); readln; end; end; End; BEGIN L := NIL; repeat writeln; writeln('1 Bo sung mot sinh vien'); writeln('2 Duyet danh sach sinh vien'); writeln('3 Tim kiem mot phan tu va chen vao sau'); writeln('4 Tim kiem mot phan tu va xoa'); writeln('5 Ket thuc chuong trinh'); writeln; write('Chon chuc nang: '); readln(chon);