(TOP - DOWN STRUCTURED PROGRAMMING)
Nếu các bạn là một người mới bắt đầu khởi sự thực hành lập trình một bài toán nào đó, các bạn sẽ thường tự hỏi: Ta phải bắt đầu bằng việc gì đây? Ðây là một câu hỏi không phải ai cũng trả lời chung được. Tuy nhiên, dựa vào kinh nghiệm thu thập được của những người lập trình tài tử và của những lập trình viên chuyên nghiệp, tác giả Francis Scheid, trong tác phẩm Computer and Programming của mình, đã cho một số lời khuyên sau :
1. Ôn lại những kinh nghiệm đã qua để xem coi vấn đề của bạn có chút gì tương tự đến các vấn đề mà bạn đã từng chạm trán trước đây không;
2. Trước tiên, thử làm một phiên bản đơn giản. Nếu có thể, đưa ngay vào một số trường hợp đặc biệt mà bạn có, nhằm tạo chương trình bạn có một vẻ gì sâu sắc.
3. Chia bài toán ra thành những bài nhỏ, rồi tiếp tục chẻ những bài nhỏ này thành những phần nhỏ hơn, nếu được, chẻ tiếp những phần nhỏ này thành những mảnh nhỏ hơn nữa, sau đó giải quyế từng phần hay mảnh nhỏ này.
Mỗi thuật toán có thể thể hiện bằng lưu đồ (flow chart). Lưu đồ chính là bản đồ lộ trình của thuật toán. Không hẳn tất cả những chuyên viên máy tính phải thực
hiện lưu đồ trước khi lập trình nhưng nhờ có lưu đồ mà công việc của bạn trở nên rõ ràng và mang tính logic hơn. Bạn sẽ không cảm thấy bối rối khi cần phải trình bày tiến trình giải toán của bạn cho người khác hiểu. Bạn có thể mất một ít thời gian cho lưu đồ nhưng nó có giá trị hơn cả ngàn từ nếu phải cắt nghĩa thuật toán. Chúng ta hãy tưởng tượng bài toán to lớn của chúng ta như một cây cổ thụ nhiều cành lá rậm rạp. Ta muốn đốn cây này về nhà làm củi chụm và dĩ nhiên, ta không thể nào chặt ngang gốc cây mà vác về nhà (thí dụ này không có ý khuyến khích phá hoại môi trường đâu nhé ! ). Vậy tại sao ta không tỉa từng cành nhỏ rồi dần dần thanh toán luôn cả cây ? Giải quyết vấn đề của chúng ta cũng vậy. Bạn cứ xem bài toán của chúng ta như một gốc cây lộn ngược đầu. Chia nhỏ bài toán ra thành những vấn đề nhỏ hơn, rồi nhỏ hơn nữa nếu nó còn phức tạp, như minh họa ở hình sau đây:
Trong hình vẽ trên, bài toán được phân thành 4 vấn đề nhỏ hơn là A, B, C và D. Vấn đề B và D có thể giải quyết được ngay. Riêng vấn đề A và C thì lại tiếp tục chia nhỏ hơn nữa để thành những mảnh nhỏ có thể giải quyết được. Ở đây các nhánh cây không dài ngắn như nhau, dễ hiểu bởi vì mức độ phức tạp của mỗi vấn đề không thể như nhau và tùy theo thuật toán cần giải quyết mà ta phân nhỏ nó ra. Bài toán của chúng ta sẽ đi từ vấn đề trừu tượng đến cụ thể. Cách giải quyết như vậy giống như hệ thống phân quyền trong tổ chức chính phủ:
Lập trình cấu trúc là một trường phái lập trình xuất hiện vào thập niên 1970 và đã nhanh chóng được nhiều người hưởng ứng. Ðiểm cơ bản trong lập trình cấu trúc là tổ chức chương trình thành một hệ phân cấp (hierarchy) và phải điều khiển sao cho các mối tương tác giữa các thành phần trong hệ là tối thiểu. Ðây chính là ý tưởng của một phép tinh chế từng bước (stepwise refinement) hay phương pháp chia để trị trong giải bài toán theo cách top-down. Một khi ta đã thực hiện việc phân tích top-down xong, những mảnh bài toán chi tiết nhất sẽ được giải theo cách của 1 trong 3 thành phần thuật toán sau :
* Dòng tuần tự (Sequential Flow) : Trong thuật giải này, các bước giải được thể hiện ở trong một luồng lệnh tuần tự như hình vẽ sau:
* Dòng điều kiện (Conditional Flow): Trong thực tế ở nhiều bài toán máy tính, ta sẽ đi đến việc chọn lựa một trong hai điều kiện. Mỗi điều kiện (Ðúng hoặc Sai) sẽ dẫn đến một quyết định khác nhau. Minh họa ở hình sau:
* Dòng lặp (Repetitive Flow) : Trong nhiều trường hợp, ta cần thực hiện nhiều lần liên tiếp một hay nhiều thao tác cho để khi một điều kiện được thỏa.
Cha đẻ của ngôn ngữ lập trình Pascal là N.Wirth đã phát triển phương pháp tinh chế từng bước, xem nó như một phương pháp khoa học cần thiết cho việc phân tích vấn đề và lập trình.
Khởi đầu, chương trình phải được thể hiện khái quát vấn đề, nêu bậc sự phân tích tổng thể bài toán. Ở từng bước kế tiếp sau đó, sẽ có các giải pháp giải quyết vấn đề một cách chi tiết hơn, mỗi giải pháp như vậy là một sự đặc tả (specification) công việc. Như vậy, từng bước một, ta dần dần tinh chế bài toán. Sự tinh chế này phải hướng đến các thuật toán của ngôn ngữ lập trình. Nếu các bài toán nhỏ trở nên đơn giản thì ta thay nó bằng các câu lệnh. Nếu nó tỏ ra còn phức tạp thì ta xem đó như một thủ tục và tiếp tục tìm cách tinh chế nó.
Trong quá trình tinh chế, cần thiết đưa ra những cách biểu diễn dữ liệu đi song song với cách chi tiết hoá việc giải quyết bài toán. Ðây là một phương pháp khoa học nhưng cũng mang một phần tính nghệ thuật thể hiện sự nhạy bén trong tư duy của người lập trình.
CHƯƠNG III
MỘT SỐ CẤU TRÚC DỮ LIỆU CƠ SỞ