Bài giảng Phân tích thiết kế giải thuật và cấu trúc dữ liệu: Phần 2 - ĐH CNTT&TT

36 8 0
Bài giảng Phân tích thiết kế giải thuật và cấu trúc dữ liệu: Phần 2 - ĐH CNTT&TT

Đ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

Phần 2 của bài giảng Phân tích thiết kế giải thuật và cấu trúc dữ liệu đi sâu tìm hiểu các cách tổ chức dữ liệu và thuật toán trên kiểu dữ liệu đó. Với mục đích cung cấp cho các bạn sinh viên một cái nhìn toàn thể và cơ bản. Tác giả kỳ vọng kết thúc môn học người học sẽ nắm được những cách tổ chức và cấu trúc dữ liệu. Từ đó áp dụng một phần kiến thức ấy vào nghiên cứu những mảng khác hiệu quả, tối ưu hơn.

Chương CÁC THUẬT TOÁN SẮP XẾP 4.1 Các thuật toán xếp 4.1.1 Sắp xếp chọn (Selection Sort) Giải thuật Ðây phương pháp xếp đơn giản tiến hành sau: • Ðầu tiên chọn phần tử có khóa nhỏ n phần tử từ a[1] đến a[n] hốn vị với phần tử a[1] • Chọn phần tử có khóa nhỏ n-1phần tử từ a[2] đến a[n] hoán vị với a[2] • Tổng qt bước thứ i, chọn phần tử có khố nhỏ n-i+1 phần tử từ a[i] đến a[n] hốn vị với a[i] • Sau n-1 bước mảng xếp Phương pháp gọi phương pháp chọn lặp lại q trình chọn phần tử nhỏ số phần tử chưa Ví dụ 2-1: Sắp xếp mảng gồm 10 mẩu tin có khóa số nguyên: 5, 6, 2, 2, 10, 12, 9, 10, Bước 1: Ta chọn phần tử có khố nhỏ (bằng 2) phần tử từ a[1] đến a[10] a[3], hoán đổi a[1] a[3] cho Sau bước a[1] có khố nhỏ Bước 2: Ta chọn phần tử có khố nhỏ (bằng 2) phần tử từ a[2] đến a[10] a[4], hoán đổi a[2] a[4] cho Tiếp tục trình sau bước kết thúc 57 Bảng sau ghi lại giá trị khoá tương ứng với bước Bảng 4.1: Các bước thực xếp chọn Chương trình: PROCEDURE SelectionSort; VAR i,j,LowIndex: integer; LowKey: KeyType; BEGIN {1} FOR i := TO n-1 DO BEGIN {2} LowIndex := i; {3} LowKey := a[i].key; {4} FOR j := i+1 TO n DO {5} IF a[j].key < LowKey THEN BEGIN {6} LowKey := a[j].key; {7} LowIndex := j; END; {8} Swap(a[i],a[LowIndex]); END; 58 END; Ðánh giá: Phương pháp xếp chọn lấy O(n) để xếp n phần tử Trước hết ta có thủ tục Swap lấy thời gian nói mục 2.2.3 Các lệnh {2}, {3} lấy O(1) thời gian Vòng lặp for {4} – {7} thực n-i lần, j chạy từ i+1 đến n, lần lấy O(1), nên lấy O(n-i) thời gian Do thời gian tổng cộng là: O(n ) 4.1.2 Sắp xếp chèn (Insert Sort) Giải thuật Trước hết ta xem phần tử a[1] dãy có thứ tự Bước 1, xen phần tử a[2] vào danh sách có thứ tự a[1] cho a[1], a[2] danh sách có thứ tự Bước 2, xen phần tử a[3] vào danh sách có thứ tự a[1], a[2] cho a[1], a[2], a[3] danh sách có thứ tự Tổng quát, bước i, xen phần tử a[i+1] vào danh sách có thứ tự a[1],a[2], a[i] cho a[1], a[2], a[i+1] danh sách có thứ tự Phần tử xét a[j] xen vào vị trí thích hợp danh sách phần tử trước a[1],a[2], a[j-1] cách so sánh khoá a[j] với khoá a[j-1] đứng trước Nếu khố a[j] nhỏ khố a[j-1] hốn đổi a[j-1] a[j] cho tiếp tục so sánh khoá a[j1] (lúc a[j-1] chứa nội dung a[j]) với khoá a[j-2] đứng trước Ví dụ 2-2: Sắp xếp mảng gồm 10 mẩu tin cho ví dụ 2-1 Bước 1: Xen a[2] vào dãy có phần tử a[1] ta dãy hai phần tử a[1] a[2] có thứ tự Việc xen thực khơng phải làm hai phần tử a[1], a[2] có khố tương ứng có thứ tự Bước 2: Xen a[3] vào dãy a[1] a[2] ta dãy ba phần tử a[1] a[3] có thứ tự Việc xen thực cách : so sánh khoá a[3] với khoá a[2], khoá a[3] nhỏ khoá a[2] (2 R Khi L điểm phân hoạch, cụ thể a[L] phần tử mảng “bên phải” Giải thuật QuickSort Ðể xếp mảng a[i] a[j] ta tiến hành bước sau: • Xác định chốt • Phân hoạch mảng cho thành hai mảng a[i] a[k-1] a[k] a[j] • Sắp xếp mảng a[i] a[k-1] (Ðệ quy) • Sắp xếp mảng a[k] a[j] (Ðệ quy) Q trình đệ quy dừng khơng cịn tìm thấy chốt Procedure quicksoft(t,p:integer); var i,j,x,m:integer; 64 begin i:=t;j:=p; m:=a[(i+j) div 2]; While (i $ 78 begin Inorder (B) ; B : = NextSibling (B) end ; end ; procedure Postorder (A : Node) ; {Thủ tục đệ qui qua gốc A theo thứ tự Postorder} var B : Node ; begin B : = EldestChild (A) ; while B < > $ begin Postorder (B) ; B : = NextSibling (B) end ; Visit (A) end ; Chúng ta viết thủ tục không đệ qui qua theo thứ tự Preordor, Inorder Postorder Chúng ta viết ba thủ tục (các thủ tục khác giành lại cho độc giả) Tư tưởng thuật toán không đệ qui qua theo thứ tự Preorder sau Chúng ta sử dụng stack S để lưu giữ đỉnh Nếu thời điểm ta thăm đỉnh x stack lưu giữ đường từ gốc đến x, gốc đáy stack x đỉnh stack Chẳng hạn, với hình 4.1, ta thăm đỉnh i, stack lưu (a, b, e, i) i đỉnh stack procedure Preorder ( A : Node) ; 79 {Thủ tục không đệ qui qua theo thứ tự Preorder} var B : Node ; S : Stack ; begin Intealize (S) ; {khởi tạo stack rỗng} B:=A; while B < > $ begin Visit (B) ; Push (B, S) ; {đẩy B vào stack} B : = EldestChild (B) end ; while not Empty (S) begin Pop (S,B) ;{loại phần tử đỉnh stack gán cho B] B : = NexSibling (B) ; if B < > $ then while B < > $ begin Visit (B) ; Push (B, S) ; B : = EldestChild (B) end ; end ; end ; 80 Sau trình bày thuật tốn qua theo bề rộng, sử dụng hàng Q để lưu giữ đỉnh theo thứ tự thăm, đầu hàng đỉnh bên trái mà ta chưa thăm nó, cịn cuối hàng đỉnh ta thăm Chẳng hạn, với hình 4.1, ta thăm đỉnh i hàng chứa đỉnh (f, g, h, i) f đầu hàng i cuối hàng Khi loại phần tử đầu hàng, thăm (nếu có) thăm đỉnh đưa đỉnh vào cuối hàng Chúng ta có thủ tục sau procedure BreadthTraverse ( A : Node) ; {Thủ tục qua gốc A theo bề rộng } var B : node ; Q : Queue ; begin Initialize (Q) ; {khởi tạo hàng rỗng} Visit (A) ; Add (A, Q) ; {đưa gốc A vào hàng Q} while not Empty (Q) begin Delete (Q, B) ; {loại phần tử đầu hàng gán cho B} B : = EldestChild (B) ; while B < > $ begin Visit (B) ; Add (B, Q) ; B : = NextSibling (B) end ; end ; end ; 81 5.4 Cây nhị phân 5.4.1 Định nghĩa Cây nhị phân tập hợp hữu hạn đỉnh xác định đệ qui sau Một tập trống nhị phân Giả sử T1 T2 hai nhị phân không cắt (T1T2 = ) r đỉnh không thuộc T1, T2 Khi ta thành lập nhị phân T với gốc r có T1 bên trái, T2 bên phải gốc Cây nhị phân T biểu diễn hình 5.9 Cần lưu ý rằng, (cây có gốc) nhị phân hai khái niệm khác Cây không trống, ln ln chứa đỉnh, đỉnh khơng có, có hay nhiều Cịn nhị phân trống, đỉnh ln ln có hai phân biệt bên trái bên phải Chẳng hạn, hình 4.10 minh hoạ hai nhị phân khác Cây nhị phân hình 4.10a có trái gốc gồm đỉnh, phải trống Cây nhị phân hình 5.10b có trái gốc trống, phải gồm đỉnh Song ta có : mà gốc có gồm đỉnh 82 Từ định nghĩa nhị phân, ta suy rằng, đỉnh nhị phân có nhiều hai đỉnh con, đỉnh bên trái (đó gốc trái) đỉnh bên phải (đó gốc phải) 5.4.2 Mô tả Cài đặt nhị phân Phương pháp tự nhiên để biểu diễn nhị phân đỉnh trái đỉnh phải đỉnh Ta sử dụng mảng để lưu giữ đỉnh nhị phân Mỗi đỉnh biểu diễn ghi gồm ba trường : trường infor mô tả thông tin gắn với đỉnh, truờng left đỉnh trái, trường right đỉnh phải Giả sử đỉnh đánh số từ đến max, cấu trúc liệu biểu diễn nhị phân khai báo sau const max = N ; type Node = record infor : Item ; 83 left : max ; right : max end ; Tree = array [1 max] of Node ; 5.4.3 Cây tìm kiếm nhị phân Cây nhị phân sử dụng nhiều mục đích khác Tuy nhiên việc sử dụng nhị phân để lưu giữ tìm kiếm thơng tin áp dụng quan trọng nhị phân Trong mục xét lớp nhị phân đặc biệt, phục vụ cho việc tìm kiếm thơng tin, tìm kiếm nhị phân Trong thực tiễn, lớp đối tượng mơ tả kiểu ghi, trường ghi biểu diễn thuộc tính đối tượng Trong tốn tìm kiếm thơng tin, thường quan tâm đến nhóm thuộc tính đối tượng hoàn toàn xác định đối tượng Chúng ta gọi thuộc tính khố Như vậy, khố nhóm thuộc tính lớp đối tượng cho hai đối tượng khác cần phải có giá trị khác nhóm thuộc tính Từ sau ta giả thiết rằng, thơng tin gắn với đỉnh nhị phân khố đối tượng Do đỉnh nhị phân biểu diễn ghi kiểu Node có cấu trúc sau type pointer = ^Node ; Node = record key : keytype ; left : pointer ; right : pointer ; end ; Giả sử kiểu khố (keytype) kiểu có thứ tự, chẳng hạn kiểu nguyên, thực, ký tự, xâu ký tự Khi tìm kiếm nhị phân định nghĩa 84 sau Cây tìm kiếm nhị phân nhị phân trống, thoả mãn điều kiện sau Khoá đỉnh thuộc trái nhỏ khoá gốc Khoá gốc nhỏ khoá đỉnh thuộc phải gốc Cây trái phải gốc tìm kiếm nhị phân Hình 5.15 biểu diễn tìm kiếm nhị phân, khố đỉnh số ngun 85 Chương TÌM KIẾM 6.1 Tìm kiếm Tìm kiếm thông tin vấn đề quan trọng tin học Cho trước số điện thoại, cần tìm biết người có số điện thoại đó, địa anh ta, thơng tin khác gắn với số điện thoại Thơng thường thông tin đối tượng biểu diễn dạng ghi, thuộc tính đối tượng trường ghi Trong toán tìm kiếm, tiến hành tìm kiếm đối tượng dựa số thuộc tính biết đối tượng, gọi thuộc tính khoá Như vậy, khoá ghi hiểu trường ghi Với giá trị cho trước khoá, có nhiều ghi có khố Cũng xảy ra, khơng có ghi có giá trị khố cho Thời gian tìm kiếm phụ thuộc vào cách tổ chức thông tin phương pháp tìm kiếm sử dụng Chúng ta tổ chức đối tượng để tìm kiếm dạng danh sách, tìm kiếm nhị phân, Với cách cài đặt (Chẳng hạn, cài đặt danh sách mảng, danh sách liên kết), có phương pháp tìm kiếm thích hợp Người ta phân biệt hai loại tìm kiếm : tìm kiếm tìm kiếm ngồi Nếu khối lượng thơng tin lớn cần lưu giữ dạng file nhớ ngồi, đĩa từ băng từ, tìm kiếm gọi tìm kiếm ngồi Trong trường hợp thông tin lưu giữ nhớ trong, ta nói đến tìm kiếm Trong chương chương sau, đề cập tìm kiếm Sau nghiên cứu phương pháp tìm kiếm danh sách biểu diễn mảng Giả sử keytype kiểu khoá Trong nhiều trường hợp keytype integer, real, string Các phần tử danh sách có kiểu Item - ghi có chứa trường key kiểu keytype type keytype = ; 86 Item = record key : keytype ; các trường khác end ; List = record element : array 1 max of Item ; count : max ; end ; Tìm kiếm (hay tìm kiếm tuyến tính) phương pháp tìm kiếm đơn giản nhất: xuất phát từ đầu danh sách, danh sách tìm phần tử có khố cho dừng lại, đến hết danh sách mà khơng tìm thấy Ta có thủ tục tìm kiếm sau procedure SeqSearch (var L : List ; x : keytype ; var found : boolean ; var p : max) ; begin found : = false ; p:=1; with L while (not found) and ( p = count) if element p key = x then found : = true else p : = p + ; end ; Thủ tục để tìm xem danh sách L có chứa phần tử với khố x hay khơng Nếu có giá trị tham biến found true Trong trường hợp có, biến p ghi lại vị trí phần tử có khố x 87 Phân tích tìm kiếm Giả sử độ dài danh sách n (count = n) Dễ dàng thấy rằng, thời gian thực tìm kiếm thời gian thực lệnh while Mỗi lần lặp cần thực phép so sánh khoá x với khoá phần tử danh sách, số lớn lần lặp n, thời gian tìm kiếm (n) 6.2 Tìm kiếm nhị phân Giả sử L danh sách có độ dài n biểu diễn mảng, phần tử có kiểu Item mơ tả mục 3.3.2 Giả sử kiểu khố keytype kiểu có thứ tự, tức với hai giá trị v1 v2, ta ln ln có v1 v2, v1 v2 ;  quan hệ thứ tự xác định keytype Giả sử phần tử danh sách L xếp theo thứ tự khố khơng giảm : L element 1 key  L element 2.key   L element n.key Trong trường hợp này, áp dụng phương pháp tìm kiếm khác, hiệu phương pháp tìm kiếm Đó kỹ thuật tìm kiếm nhị phân Tư tưởng tìm kiếm nhị phân sau : Đầu tiên ta so sánh khố x với khóa phần tử danh sách, tức phần tử vị trí m=(1+n)/2  Nếu chúng x = L.element [m].key, ta tìm thấy Nếu x < L.element [m].key, ta tiếp tục tìm kiếm nửa đầu danh sách từ vị trí đến vị trị m-1 Cịn x > 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 khơng có phần tử với khố 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) ; var mid , bottom, top : integer ; begin 88 (1) found : = false ; (2) bottom : = 1, (3) top : = L.count ; (4) while (not found) and (bottom p^.info then search (p^.Right, x, p) End; 6.3.2 Giải thuật lặp Trong thủ tục này, ta sử dụng biến địa phương found có kiểu boolean để điều khiển vịng lặp, có giá trị ban đầu false Nếu tìm kiếm thành cơng found nhận giá trị true, vịng lặp kết thúc đồng thời p trỏ đến nút có trường khố x Cịn khơng tìm thấy giá trị found false giá trị p NULL 90 Procedure search (Root : Tree; x:keytype; var p : Tree); Var Found : boolean; Begin Found:=False; P:=Root; while (pNULL) and( not Found ) if x > p^.info then p := p^.right else if x < p^.info then p := p^.left else Found = True; End; 91 TÀI LIỆU THAM KHẢO [1] Đỗ Xuân Lôi, (1995), Cấu trúc liệu giải thuật Nhà xuất khoa học kỹ thuật Hà Nội [2] Nguyễn Trung Trực, (1990), Cấu trúc liệu NXB BK HCM, [3] Lê Minh Trung, (1997), Lập trình nâng cao Pascal với cấu trúc liệu NXB Khoa học Kỹ thuật, Hà Nội [6] Ngô Trung Việt, (2000), Ngơn ngữ lập trình C C++ Bài giảng- Bài tập – Lời giải mẫu NXB Giao thông vận tải, Hà Nội [7] Nguyễn Đình Tê, Hồng Đức Hải, (1998), Giáo trình lý thuyết tập ngơn ngữ C NXB Giáo dục, Hà Nội [8] Lê Xuân Trường, (1999), Giáo trình cấu trúc liệu ngơn ngữ C++ NXB thống kê, Hà Nội [9] Nguyễn Thanh Thủy, Nguyễn Quang Huy, (1999), Bài tập lập trình ngơn ngữ C NXB Khoa học kỹ thuật, Hà Nội 92 ... a[j1] (lúc a[j-1] chứa nội dung a[j]) với khoá a[j -2 ] đứng trước Ví dụ 2- 2: Sắp xếp mảng gồm 10 mẩu tin cho ví dụ 2- 1 Bước 1: Xen a [2] vào dãy có phần tử a[1] ta dãy hai phần tử a[1] a [2] có thứ... 4.1 .2 Sắp xếp chèn (Insert Sort) Giải thuật Trước hết ta xem phần tử a[1] dãy có thứ tự Bước 1, xen phần tử a [2] vào danh sách có thứ tự a[1] cho a[1], a [2] danh sách có thứ tự Bước 2, xen phần. .. sánh khố với khố phần tử a[j-1] đứng trước Nếu khố a[j] nhỏ khố a[j-1] hốn đổi a[j] a[j-1] cho Bước 2: Xét phần tử từ a[n] đến a[3], làm tương tự Sau n-1 bước kết thúc Ví dụ 2- 3: Sắp xếp mảng

Ngày đăng: 09/05/2021, 21:58

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

  • Đang cập nhật ...

Tài liệu liên quan