CHƯƠNG 1: TỔNG QUAN VỀ CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT Mã chương: Mh17-01 Giới thiệu: Tổng quan về giải thuật. Đầu tiên là cách phân tích 1 vấn đề, từ thực tiễn cho tới chương trình, cách thiết kế một giải pháp cho vấn đề theo cách giải quyết bằng máy tính. Tiếp theo, các phương pháp phân tích, đánh giá độ phức tạp và thời gian thực hiện giải thuật cũng được xem xét trong chương. Mục tiêu: - Mô tả được khái niệm giải thuật, mối quan hệ giữa cấu trúc dữ liệu và giải thuật.
Trình bày được các tiêu chuẩn để đánh giá độ phức tạp của giải thuật. - Ghi nhớ được các kiểu dữ liệu cơ bản, kiểu dữ liệu trừu tượng và các cấu trúc dữ liệu cơ bản. - Thực hiện các thao tác an toàn với máy tính. Nội dung chính: 1.Khái niệm giải thuật và đánh giá độ phức tạp của giải thuật Mục tiêu: Mô tả được khái niệm giải thuật, mối quan hệ giữa cấu trúc dữ liệu và giải thuật.
Trình bày được các tiêu chuẩn để đánh giá độ phức tạp của giải thuật. Khái niệm giải thuật ❖ Khái niệm: Giải thuật, còn gọi là thuật toán (algorithm) là một trong những khái niệm quan trọng nhất trong tin học. Thuật ngữ thuật toán xuất phát từ nhà toán học Arập Abu Ja'far Mohammed ibn Musa al Khowarizmi (khoảng năm 825). Giải thuật thể hiện một giải pháp cụ thể, thực hiện từng bước một để đưa tới lời giải cho một bài toán.
Nói cách khác, giải thuật là một tập hữu hạn các phép toán cơ sở, được sắp đặt theo những quy tắc chính xác, nhằm giải một bài toán, hay là một bộ các qui tắc hay qui trình cụ thể nhằm giải quyết một vấn đề trong một số bước hữu hạn, nhằm cung cấp một kết quả từ một tập hợp của các dữ kiện đưa vào. Các phép toán cơ sở là những phép toán đơn giãn mà thời gian thực hiện nó là hữu hạn và không phụ thuộc vào kích thước của dữ liệu. Các phép toán trong giải thuật phải được xác định rỏ ràng, dễ hiểu, không mập mờ. Với mọi bộ dữ liệu vào thoả mãn các điều kiện của bài toán, thuật toán phải dừng lại sau một số hữu hạn các bước cần thực hiện Giáo trình Cấu trúc dữ liệu và giải thuật Trang 9 / 92 ❖ Các đặc trưng của giải thuật: • Dữ liệu vào: Mỗi thuật toán đều có một số giá trị nhập vào, chúng được gọi là Input data.
• Dữ liệu ra: Mỗi thuật toán có một số giá trị đưa ra, chúng được gọi là Output data. • Tính xác định: Mọi bước của một thuật toán bao giờ cũng được xác định rõ ràng, chính xác và do đó luôn thực hiện được. • Tính dừng: Sau một số hữu hạn các bước bài toán luôn được giải quyết. • Tính phổ dụng: Thuật toán có thể làm việc với các kiểu dữ liệu khác nhau trong miền xác định và luôn dẫn đến kết quả mong muốn.
• Tính hiệu quả: Được thể hiện ở sự đúng đắn của thuật toán và độ phức tạp của thuật toán. Tính hiệu quả được thể hiện bởi khả năng thực thi các bước của thuật toán để đạt được kết quả mong muốn và tổng thời gian thực hiện thuật toán phải đủ nhỏ. Chú ý: Trên thực tế để đánh giá tính hiệu quả của các thuật toán, người ta thường qui về các đơn vị tính sơ cấp. Tính hiệu quả của một thuật giải được đo bởi số lượng các đơn vị tính sơ cấp mà thuật toán này yêu cần thực hiện.
Ví dụ cho các phép tính sơ cấp đó là phép +, -, *, : các số tự nhiên nhỏ hơn 10 1. Ngôn ngữ diễn đạt giải thuật • Sử dụng ngôn ngữ tự nhiên: Sử dụng ngôn ngữ thường ngày để biểu diễn các bước của thuật toán. Phương pháp biểu diễn này không yêu cầu người viết thuật toán cũng như người đọc thuật toán phải nắm các quy tắc. Tuy vậy, cách biểu diễn này thường dài dòng, không thể hiện rõ cấu trúc của thuật toán, đôi lúc gây hiểu lầm hoặc khó hiểu cho người đọc.
• Sử dụng sơ đồ khối (flowchart): Lưu đồ hay sơ đồ khối là một công cụ trực quan để diễn đạt các thuật toán. Giáo trình Cấu trúc dữ liệu và giải thuật Trang 10 / 92 Biểu diễn thuật toán bằng lưu đồ sẽ giúp người đọc theo dõi được sự phân cấp các trường hợp và quá trình xử lý của thuật toán. Phương pháp lưu đồ thường được dùng trong những thuật toán có tính rắc rối, khó theo dõi được quá trình xử lý. Ðể biểu diễn thuật toán theo sơ đồ khối, ta phải phân biệt hai loại thao tác: - Thao tác chọn lựa (decision): dựa theo một điều kiện nào đó.
Chẳng hạn : thao tác "nếu a = b thì thực hiện thao tác B2, ngược lại thực hiện B4" là thao tác chọn lựa. Thao tác chọn lựa được biểu diễn bằng một hình thoi, bên trong chứa biểu thức điều kiện. - Thao tác xử lý (process): Các thao tác còn lại không thuộc loại chọn lựa được xếp vào loại hành động. Chẳng hạn, "Chọn một hộp bất kỳ và để lên dĩa cân còn trống." là một thao tác thuộc loại hành động.
Thao tác xử lý được biểu diễn bằng một hình chữ nhật, bên trong chứa nội dung xử lý • Sử dụng mã giả(pseudocode): Tuy sơ đồ khối thể hiện rõ quá trình xử lý và sự phân cấp các trường hợp của thuật toán nhưng lại cồng kềnh. Ðể mô tả một thuật toán nhỏ ta phải dùng một không gian rất lớn. Hơn nữa, lưu đồ chỉ phân biệt hai thao tác là rẽ nhánh (chọn lựa có điều kiện) và xử lý mà trong thực tế, các thuật toán còn có thêm các thao tác lặp. Khi thể hiện thuật toán bằng mã giả, ta sẽ vay mượn các cú pháp của một ngôn ngữ lập trình nào đó để thể hiện thuật toán.
Tất nhiên, mọi ngôn ngữ lập trình đều có những thao tác cơ bản là xử lý, rẽ nhánh và lặp. Dùng mã giả vừa tận dụng được các khái niệm trong ngôn ngữ lập trình, vừa giúp người cài đặt dễ dàng nắm bắt nội dung thuật toán. Tất nhiên là trong mã giả ta vẫn dùng một phần ngôn ngữ tự nhiên. Một khi đã vay mượn cú pháp và khái niệm của ngôn ngữ lập trình thì chắc chắn mã giả sẽ bị phụ thuộc vào ngôn ngữ lập trình đó.
Chính vì lý do này, chúng ta chưa vội tìm hiểu về mã giả trong bài này. • Sử dụng ngôn ngữ lập trình(code):Pascal, C, C++, C#,. Giáo trình Cấu trúc dữ liệu và giải thuật Trang 11 / 92 1. Quy cách về cấu trúc chương trình Mỗi chương trình đều được gán một tên để phân biệt, tên này được viết bằng chữ in hoa, có thể có thêm dấu gạch nối và bắt đầu bằng từ khoá Program Ví dụ : Prorgram NHAN-MA-TRAN Độ dài tên không hạn chế.
Sau tên có thể kèm theo lời thuyết minh (ở đây ta quy ước dùng Tiếng Việt) để giới thiệu tóm tắt nhiệm vụ của giải thuật hoặc một số chi tiết cần thiết. Phần thuyết minh được đặt giữa hai dấu {. Chương trình bao gồm nhiều bước, mỗi bước được phân biệt bởi số thứ tự, có thể kèm theo những lời thuyết minh. Kí tự và biểu thức Kí tự dùng ở đây cũng giống như trong các ngôn ngữ chuẩn, nghĩa là gồm : 26 chữ cái Latinh in hoa hoặc in thường 10 chữ số thập phân Các dấu phép toán số học: +, - , *, /, (lũy thừa) Các dấu phép toán quan hệ: <, =, >, , , #.
Giá trị logic: true, false Dấu phép toán logic: and, or, not Tên biến là dãy chữ cái và chữ số, bắt đầu bằng chữ cái Biến chỉ số có dạng :A[i], B[ij] v. Còn biểu thức cũng như thứ tự ưu tiên của các phép toán trong biểu thức cũng theo quy tắc như trong PASCAL hay các ngôn ngữ chuẩn khác. Các câu lệnh Các câu lệnh trong chương trình được viết cách nhau bởi dấu chấm phảy chúng bao gổm : Câu lệnh gán Có dạng Tên biến/ Tên hàm : = Biểu thức Ở đây cho phép dùng phép gán chung. Ví dụ : X : = Y : = 5 Câu lệnh ghép Có dạng : begin Câu lệnh 1 ; Câu lệnh 2 ;.
; Câu lệnh n end Nó cho phép ghép nhiều câu lệnh lại để được coi như một câu lệnh. Câu lệnh điều kiện Có dạng : if < Điều kiện > then < Câu lệnh > Giáo trình Cấu trúc dữ liệu và giải thuật Trang 12 / 92 Có thể diễn tả bởi sơ đồ : Điều kiện true Câu lệnh1 false Câu lệnh2 Hoặc if < Điều kiện > then <Câu lệnh1>else< Câu lệnh2> Điều kiện true Câu lệnh false Câu lệnh tuyến Case Điều kiện1: Câu lệnh1; Điều kiện2: Câu lệnh2; …… …… Điều kiệnn: Câu lệnhn; Else: Câu lệnhn+1 End case Câu lệnh này cho phân biệt các tình huống xử lí khác nhau trong các điều kiện khác nhau mà không phải tới các câu lệnh if – then – else khác nhau. Có thể diễn tả bởi sở đồ : false false false B1 B2 Bn Sn+1 tru tru tru Chú thích: e Bi: Điều kiện e e Si: Câu lệnh S1 S2 Sn Giáo trình Cấu trúc dữ liệu và giải thuật Trang 13 / 92 Vài điểm linh động esle có thể không có mặt Câu lệnhi(i = 1, 2, …, n) có thể được thay thế bằng một dãy các câu lệnh mà không cần phải đặt giữa : begin và end. Câu lệnh lặp Với số lần lặp biết trước : for i : = m to n do < Câu lệnh>.
nhằm thực hiện < Câu lệnh > với i lấy giá trị nguyên từ m tới n ( n m) với bước nhảy tăng bằng 1, hoặc : for i := n down to m do < Câu lệnh> tương tự như câu lệnh trên vơi bước nhảy giảm bằng 1. Với số lần lặp không biết trước: While < Điều kiện >do < Câu lệnh> true Điều kiện Câu lệnh false Chừng nào mà < Điều kiện > có giá trị bằng true thì thực hiện < Câu lệnh> Hoặc : repeat < Câu lệnh>until < Điều kiện > Lặp lại < Câu lệnh> cho tới khi < Điều kiện > có giá trị true. fasle Câu lệnh Điều kiện true Câu lệnh nhập: read (<danh sách biến>) Câu lệnh xuất: write(<danh sách biến hoặc dòng kí tự>) các biến trong danh sách cách nhau bởi dấu phẩy. Giáo trình Cấu trúc dữ liệu và giải thuật Trang 14 / 92 Dòng kí tự là một dãy các kí tự đặt giữa hai dấu nháy’ ‘.
Câu lệnh kết thúc chương trình: End 1. Chương trình con Chương trình con hàm Có dạng : Function <tên hàm> (<danh sách tham số>) S1; S2; … ; Sn.