Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 242 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
242
Dung lượng
1,14 MB
Nội dung
HỌC VIỆN CƠNG NGHỆ BƯU CHÍNH VIỄN THƠNG KHOA CÔNG NGHỆ THÔNG TIN BÀI GIẢNG PT IT CÁC KỸ THUẬT LẬP TRÌNH Hà Nội 2013 LỜI NĨI ĐẦU Sự phát triển công nghệ thông tin năm vừa qua làm thay đổi mặt kinh tế xã hội tồn cầu, cơng nghệ phần mềm trở thành ngành công nghiệp quan trọng đầy tiềm Với hội tụ công nghệ viễn thông công nghệ thông tin, tỷ trọng giá trị phần mềm chiếm cao hệ thống viễn thơng thiết bị đầu cuối Chính lý đó, việc nghiên cứu, tìm hiểu, tiến tới phát triển làm chủ hệ thống phần mềm kỹ sư điện tử viễn thông cần thiết Mơn học Kỹ thuật lập trình môn học sở bắt buộc sinh viên chuyên ngành điện tử viễn thông công nghệ thông tin Học viện cơng nghệ Bưu Viễn thơng Cuốn giáo trình “Kỹ thuật lập trình”, hình thành sở kinh nghiệm đúc rút từ giảng mơn học Kỹ thuật lập trình cho sinh viên ngành nói năm học vừa qua với mục đích cung cấp cho sinh viên kiến thức nhất, có tính hệ thống liên quan tới môn học PT IT Khi học mơn Kỹ thuật lập trình, sinh viên cần học qua môn “Tin học sở” cần bạn có đủ kiến thức sở cần thiết để tiếp thu kiến thức Kỹ thuật lập trình Thơng qua giáo trình này, chúng tơi muốn giới thiệu với bạn đọc kỹ lập trình cấu trúc thơng qua số thuật tốn quan trọng, bao gồm: Đại cương lập trình cấu trúc; Con trỏ mảng; Duyệt đệ qui; Ngăn xếp, hàng đợi danh sách móc nối; Cây; Đồ thị cuối Sắp xếp tìm kiếm Phần phụ lục tập tổng hợp lại kiến thức đề cập giáo trình thể chương trình Tuy ý cẩn trọng trình biên soạn, giáo trình chắn khơng tránh khỏi thiếu sót hạn chế Chúng tơi xin chân thành mong bạn đọc đóng góp ý kiến để giáo trình ngày hồn thiện Mọi đóng góp ý kiến xin gửi Khoa Cơng nghệ thơng tin – Học viện Cơng nghệ Bưu Viễn thơng Chúng tơi xin tỏ lịng biết ơn tới TS Từ Minh Phương, giảng viên khoa Công nghệ thông tin – Học viện Cơng nghệ Bưu Viễn thơng đọc hiệu đính lại tồn thảo giáo trình Hà Nội, ngày 24 tháng năm 2002 Các tác giả MỤC LỤC CHƯƠNG MỞ ĐẦU .5 PT IT 1.1 Sơ lược lịch sử lập trình cấu trúc 1.2 Cấu trúc lệnh - Lệnh có cấu trúc- Cấu trúc liệu 1.2.1 Cấu trúc lệnh (cấu trúc điều khiển) 1.2.2 Lệnh có cấu trúc 1.2.3 Cấu trúc liệu 1.3 Nguyên lý tối thiểu .10 1.3.1 Tập phép toán 10 1.3.2 Tập lệnh vào 12 1.3.3 Thao tác kiểu liệu có cấu trúc 13 1.4 Nguyên lý địa phương 15 1.5 Nguyên lý quán 16 1.6 Nguyên lý an toàn 18 1.6 Phương pháp Top-Down 19 1.7 Phương pháp Bottom - Up 24 BÀI TẬP CHƯƠNG 28 CHƯƠNG MẢNG VÀ CON TRỎ 29 2.1 Cấu trúc lưu trữ mảng 29 2.1.1 Khái niệm mảng 29 2.1.2 Cấu trúc lưu trữ mảng chiều .29 2.1.3 Cấu trúc lưu trữ mảng nhiều chiều 31 2.2 Các thao tác mảng 32 2.3 Mảng đối hàm 34 2.4 Xâu kí tự (string) 36 2.5 Con trỏ (Pointer) 38 2.5.1 Các phép toán trỏ .38 2.5.2 Con trỏ đối hàm 39 2.5.3 Con trỏ mảng 40 BÀI TẬP CHƯƠNG 46 CHƯƠNG DUYỆT VÀ ĐỆ QUI 53 3.1 Định nghĩa đệ qui .53 3.2 Giải thuật đệ qui 54 3.3 Thuật toán sinh 55 3.3.1 Bài toán liệt kê tập tập n phần tử .56 3.3.2 Bài toán liệt kê tập m phần tử tập n phần tử 58 3.3.3 Bài toán liệt kê hoán vị tập n phần tử 60 3.3.4 Bài toán chia số tự nhiên n thành tổng số nhỏ 62 3.4 Thuật toán quay lui (Back track) 65 3.4.1 Thuật toán quay lui liệt kê xâu nhị phân độ dài n 66 3.4.2 Thuật toán quay lui liệt kê tập m phần tử tập n phần tử .67 3.4.3 Thuật toán quay lui liệt kê hoán vị tập n phần tử .69 3.4.4 Bài toán Xếp Hậu 70 3.5 Thuật toán nhánh cận 72 3.5.1 Thuật toán nhánh cận giải toán túi 74 3.5.2 Thuật toán nhánh cận giải toán người du lịch 78 BÀI TẬP CHƯƠNG 82 CHƯƠNG NGĂN XẾP, HÀNG ĐỢI, DANH SÁCH LIÊN KẾT .89 PT IT 4.1 Kiểu liệu ngăn xếp ứng dụng 89 4.1.1 Định nghĩa khai báo 89 4.1.2 Các thao tác với stack 90 4.1.3 ứng dụng stack 91 4.2 Hàng đợi (Queue) .96 4.2.1 Giới thiệu hàng đợi 96 4.2.2 ứng dụng hàng đợi .97 4.3 Danh sách liên kết đơn .103 4.3.1 Giới thiệu định nghĩa 103 4.3.2 Các thao tác danh sách móc nối 104 4.3.3 ứng dụng danh sách liên kết đơn 109 4.4 Danh sách liên kết kép 114 BÀI TẬP CHƯƠNG 128 CHƯƠNG CÂY NHỊ PHÂN .132 5.1 Định nghĩa khái niệm 132 5.2 Cây nhị phân 132 5.3 Biểu diễn nhị phân .134 5.3.1 Biểu diễn nhị phân danh sách tuyến tính .134 5.3.2 Biểu diễn nhị phân danh sách móc nối 135 5.4 Các thao tác nhị phân 135 5.4.1 Định nghĩa nhị phân danh sách tuyến tính 135 5.4.2 Định nghĩa nhị phân theo danh sách liên kết: 135 5.4.3 Các thao tác nhị phân .135 5.5 Ba phép duyệt nhị phân (Traversing Binary Tree) 139 5.5.1 Duyệt theo thứ tự trước (Preorder Travesal) 140 5.5.2 Duyệt theo thứ tự (Inorder Travesal) 140 5.5.3 Duyệt theo thứ tự sau (Postorder Travesal) 141 5.6 Cài đặt nhị phân danh sách tuyến tính 141 5.7 Cài đặt nhị phân hoàn toàn cân bằng link list .148 5.8 Cài đặt nhị phân tìm kiếm link list .153 BÀI TẬP CHƯƠNG 162 CHƯƠNG ĐỒ THỊ (Graph) .166 PT IT 6.1 Những khái niệm đồ thị 166 6.1.1 Các loại đồ thị .166 6.1.2 Các thuật ngữ 169 6.1.3 Đường đi, chu trình, đồ thị liên thông 170 6.2 Biểu diễn đồ thị máy tính 171 6.2.1 Ma trận kề, ma trận trọng số 171 6.2.2 Danh sách cạnh (cung ) 173 2.3 Danh sách kề 174 6.3 Các thuật tốn tìm kiếm đồ thị 174 6.3.1 Thuật tốn tìm kiếm theo chiều sâu 174 6.3.2 Thuật tốn tìm kiếm theo chiều rộng (Breadth First Search) 176 6.3.3 Kiểm tra tính liên thơng đồ thị .179 6.3.4 Tìm đường hai đỉnh đồ thị .182 6.4 Đường chu trình Euler .184 6.5 Đường chu trình Hamilton 192 6.6 Cây bao trùm 196 6.6.1 Tìm bao trùm đồ thị .197 6.6.2 Tìm bao trùm ngắn 200 6.6.3 Thuật toán Kruskal 203 6.6.4 Thuật toán Prim 206 6.7 Bài tốn tìm đường ngắn .209 6.7.1 Thuật toán gán nhãn 209 6.7 Thuật toán Dijkstra .210 6.7.3 Thuật toán Floy 213 BÀI TẬP CHƯƠNG 217 CHƯƠNG SẮP XẾP VÀ TÌM KIẾM 221 7.1 Đặt toán 221 7.2 Giải thuật Selection Sort 222 7.3 Giải thuật Insertion Sort .224 7.4 Giải thuật Bubble Sort 226 7.5 Giải thuật Shaker Sort 227 7.6 Giải thuật Quick Sort 229 7.7 Giải thuật Heap Sort 231 7.8 Giải thuật Merge Sort 234 7.9 Tìm kiếm (Searching) .236 BÀI TẬP CHƯƠNG 241 CHƯƠNG MỞ ĐẦU 1.1 Sơ lược lịch sử lập trình cấu trúc PT IT Lập trình công việc nặng nhọc khoa học máy tính Có thể nói, suất xây dựng sản phẩm phần mềm thấp so với hoạt động trí tuệ khác Một sản phẩm phần mềm thiết kế cài đặt vịng tháng với lao động Nhưng để kiểm tra tìm lỗi tiếp tục hồn thiện sản phẩm phải thêm chừng năm Đây tượng phổ biến tin học năm 1960 xây dựng sản phẩm phần mềm kỹ thuật lập trình tuyến tính Để khắc phục tình trạng lỗi sản phẩm, người ta che chắn mành che mang tính chất thương mại gọi Version Thực chất, Version việc thay sản phẩm cũ cách sửa đổi cơng bố dạng Version mới, giống như: MS-DOS 4.0 tồn thời gian vài tháng thay đổi thành MS-DOS 5.0, MS-DOS 5.5, MS-DOS 6.0 Đây sản phẩm ta tưởng mà cịn tồn lỗi khơng thể bỏ qua được, MS-DOS 6.0 khắc phục hạn chế MS-DOS 3.3 ban đầu Trong thời kỳ đầu tin học, lập trình viên xây dựng chương trình ngơn ngữ lập trình bậc thấp, trình nạp theo dõi hoạt động chương trình cách trực tiếp chế độ trực tuyến (on-line) Việc tìm sửa lỗi (debbugging) ngày thực Do vậy, trước năm 1960, người ta coi việc lập trình giống hoạt động nghệ thuật nhuộm màu sắc cá nhân khoa học Một số người nắm vài ngơn ngữ lập trình, số mẹo vặt tận dụng cấu hình vật lý cụ thể hệ thống máy tính, tạo nên số lạ phần mềm coi chuyên gia nắm bắt bí ẩn nghệ thuật lập trình Các hệ thống máy tính giai đoạn có cấu hình yếu, nhớ nhỏ, tốc độ thiết bị vào thấp làm chậm trình nạp thực chương trình Chương trình xây dựng kỹ thuật lập trình tuyến tính mà bật ngơn ngữ lập trình Assembler Fortran Với phương pháp lập trình tuyến tính, lập trình viên phép thể chương trình hai cấu trúc lệnh, cấu trúc lệnh (sequential) nhảy không điều kiện (goto) Hệ thống thư viện vào nghèo nàn làm cho việc lập trình trở nên khó khăn, chi phí cho sản phẩm phần mềm lớn, độ tin cậy sản phẩm phần mềm không cao dẫn tới hàng loạt dự án tin học bị thất bại, đặc biệt hệ thống tin học có tầm cỡ lớn Năm 1973, Hoare khẳng định, nguyên nhân thất bại mà người Mỹ gặp phải phóng vệ tinh nhân tạo phía Vệ nữ ( Sao Kim) lỗi chương trình điều khiển viết Fortran Thay viết: DO 50 I = 12, 523 ( thực số 50 với I 12, 13, , 523) Lập trình viên (hoặc thao tác viên đục bìa) viết thành: DO 50 I = 12.523 (Dấu phảy thay dấu chấm) Gặp câu lệnh này, chương trình dịch Fortran hiểu gán giá trị thực 12.523 cho biến DO50I làm cho kết chương trình sai PT IT Để giải vướng mắc kỹ thuật lập trình, nhà tin học lý thuyết sâu vào nghiên cứu tìm hiểu chất ngơn ngữ, thuật tốn hoạt động lập trình, nâng nội dung kỹ thuật lập trình lên thành nguyên lý khoa học ngày Kết bật giai đoạn Knuth xuất tập sách mang tên “Nghệ thuật lập trình” giới thiệu tỉ mỉ sở lý thuyết đảm bảo toán học thuật toán xử lý liệu nửa số, xếp tìm kiếm Năm 1968, Dijkstra cơng bố thư “ Về nguy hại toán tử goto” Trong cơng trình này, Dijkstra khẳng định, có số lỗi goto gây nên xác định điểm bắt đầu lỗi Dijkstra khẳng định thêm: “Tay nghề lập trình viên tỉ lệ nghịch với số lượng toán tử goto mà sử dụng chương trình”, đồng thời kêu gọi huỷ bỏ triệt để tốn tử goto ngơn ngữ lập trình ngoại trừ ngơn ngữ lập trình bậc thấp Dijkstra cịn đưa khẳng định, động thái chương trình đánh giá tường minh qua cấu trúc lặp, rẽ nhánh, gọi đệ qui sở lập trình cấu trúc ngày Những kết Dijikstra công bố tạo nên cách mạng kỹ thuật lập trình, Knuth liệt kê số trường hợp có lợi goto vịng lặp kết thúc chừng, bắt lỗi , Dijkstra, Hoare, Knuth tiếp tục phát triển tư tưởng coi chương trình máy tính với lập trình viên đối tượng nghiên cứu kỹ thuật lập trình phương pháp làm chủ phức tạp hoạt động lập trình Năm 1969, Hoare phát biểu tiên đề phục vụ cho việc chứng minh tính đắn chương trình, phát tính bất biến vịng lặp cách coi chương trình vừa mã hố thuật tốn đồng thời chứng minh tính đắn chương trình Sau Dahl, Hoare, Dijiksta phát triển thành ngơn ngữ lập trình cấu trúc Để triển khai nguyên lý lập trình cấu trúc, L Wirth thiết kế cài đặt ngôn ngữ ALGOL W biến thể ALGOL 60 Sau này, L Wirth tiếp tục hồn thiện để trở thành ngơn ngữ lập trình Pascal Đây ngơn ngữ lập trình giản dị, sáng sủa cú pháp, dễ minh họa vấn đề phức tạp lập trình đại coi chuẩn mực giảng dạy lập trình Năm 1978, Brian Barninghan Denit Ritche thiết kế ngơn ngữ lập trình C với tối thiểu cấu trúc lệnh hàm phù hợp với tư tâm lý của người lập trình Đồng thời, hai tác giả phát hành phiên hệ điều hành UNIX viết chủ yếu ngôn ngữ C, khẳng định thêm uy C lập trình hệ thống 1.2 Cấu trúc lệnh - Lệnh có cấu trúc- Cấu trúc liệu 1.2.1 Cấu trúc lệnh (cấu trúc điều khiển) Mỗi chương trình máy tính chất mã hoá thuật toán Thuật toán coi dãy hữu hạn thao tác sơ cấp tập đối tượng vào (Input) nhằm thu kết (output) Các thao tác ngơn ngữ lập trình cụ thể điều khiển lệnh hay cấu trúc điều khiển, đối tượng chịu thao tác mơ tả biểu diễn thông qua cấu trúc liệu Trong ngơn ngữ lập trình cấu trúc, cấu trúc lệnh sau sử dụng để xây dựng chương trình Dĩ nhiên, không bàn tới cấu trúc nhảy không điều kiện goto ngôn ngữ lập trình cấu trúc trang bị cấu trúc lệnh goto Cấu trúc câu A; lệnh GOTO Cấu trúc rẽ nhánh dạng đầy đủ If (E) A; S Else B; A E Đ A B B; B Sau thực lệnh A thực lệnh B PT IT Nếu biểu thức E có giá trị (khác 0) thực A; Nếu E sai thực B; Cấu trúc lặp với điều kiện trước While (E) A; Cấu trúc lặp với điều kiện sau S E A; while (E); Đ A S E Thực A E đúng; A Trong biểu thức E cịn có giá trị thực A; Cấu trúc lặp FOR For (E1; E2;E3) A; E1 E3 S E2 Đ A Thực E1; kiểm tra E2 E2 có giá trị thực A; Quá trình lặp lại việc thực E3 kiểm tra E2; Đ A, B : ký hiệu cho câu lệnh đơn lệnh hợp thành Mỗi lệnh đơn lẻ gọi lệnh đơn, lệnh hợp thành lệnh hay cấu trúc lệnh ghép lại với theo qui định ngôn ngữ, Pascal tập lệnh hay cấu trúc lệnh bao thân begin end; C tập lệnh hay cấu trúc lệnh bao hai ký hiệu { } E, E1, E2, E3 biểu thức số học logic Một số ngôn ngữ lập trình coi giá trị biểu thức logic (TRUE) sai (FALSE), số ngôn ngữ lập trình khác C coi giá trị biểu thức logic có giá trị khác 0, ngược lại biểu thức logic có giá trị sai Cần lưu ý rằng, chương trình thể cấu trúc điều khiển lệnh : tuần tự, tuyển chọn if else, switch case default, lặp với điều kiện trước while , lặp với điều kiện sau while, vòng lặp for chuyển chương trình, sử dụng tối thiểu hai cấu trúc lệnh lặp với điều kiện trước while Phuơng pháp lập trình cịn gọi phương pháp lập trình hạn chế PT IT 1.2.2 Lệnh có cấu trúc Lệnh có cấu trúc lệnh cho phép chứa cấu trúc điều khiển Khi tìm hiểu cấu trúc điều khiển cần xác định rõ vị trí phép đặt cấu trúc điều khiển nó, phần cấu trúc điều khiển Điều tưởng tầm thường có ý nghĩa quan trọng xây dựng kiểm tra lỗi xảy chương trình Ngun tắc viết chương trình theo cấu trúc: Cấu trúc phải viết lọt cấu trúc cha, điểm vào điểm cấu trúc phải nằm hàng dọc Ví dụ sau minh họa cho nguyên tắc viết chương trình: if (E) while (E1) A; else B; while(E2); Trong ví dụ trên, while (E1) A; cấu trúc nằm thân cấu trúc cha if (E) ; B while(E2); cấu trúc thân else Do vậy, câu lệnh while(E1); while(E2) có cấp với nên phải nằm cột, tương tự với A, B if với else 1.2.3 Cấu trúc liệu Các ngơn ngữ lập trình cấu trúc nói chung giống cấu trúc lệnh cấu trúc liệu Điểm khác ngôn ngữ lập trình cấu trúc phương pháp đặt tên, cách khai báo, cú pháp câu lệnh tập phép toán phép thực cấu trúc liệu cụ thể Nắm bắt nguyên tắc này, dễ dàng chuyển đổi cách thể chương trình từ ngơn ngữ lập trình sang ngơn ngữ lập trình khác cánh nhanh chóng mà khơng tốn q nhiều thời gian cho việc học tập ngôn ngữ lập trình Thơng thường, cấu trúc liệu phân thành hai loại: cấu trúc liệu có kiểu (Base type) cấu trúc liệu có kiểu người dùng định nghĩa (User type) hay gọi kiểu liệu có cấu trúc Kiểu liệu bao gồm: Kiểu kí tự (char), kiểu số ngun có dấu (signed int), kiểu số ngun khơng dấu (unsigned int), kiểu số nguyên dài có dấu (signed long), kiểu số nguyên dài không dấu (unsigned long ), kiểu số thực (float) kiểu số thực có độ xác gấp đôi (double) PT IT Kiểu liệu người dùng định nghĩa bao gồm kiểu xâu kí tự (string), kiểu mảng (array), kiểu tập hợp (union), kiểu cấu trúc (struct), kiểu file, kiểu trỏ (pointer) kiểu liệu định nghĩa hoàn toàn kiểu danh sách móc nối (link list), kiểu (tree) Kích cỡ kiểu đồng nghĩa với miền xác định kiểu với biểu diễn nhị phân nó, phụ thuộc vào hệ thống máy tính cụ thể Để xác định kích cỡ kiểu nên dùng tốn tử sizeof( type) Chương trình sau liệt kê kích cỡ kiểu Ví dụ 1.1 kiểm tra kích cỡ kiểu #include #include void main(void) { printf(“\n Kích cỡ kiểu kí tự:%d”, sizeof(char)); printf(“\n Kích cỡ kiểu kí tự khơng dấu:%d”, sizeof(unsigned char)); printf(“\n Kích cỡ kiểu số ngun khơng dấu:%d”, sizeof(unsigned int)); printf(“\n Kích cỡ kiểu số ngun có dấu:%d”, sizeof(signed int)); printf(“\n Kích cỡ kiểu số ngun dài khơng dấu:%d”, sizeof(unsigned long )); printf(“\n Kích cỡ kiểu số ngun dài có dấu:%d”, sizeof(signed long )); printf(“\n Kích cỡ kiểu số thực có độ xác đơn:%d”, sizeof(float )); printf(“\n Kích cỡ kiểu số thực có độ xác kép:%d”, sizeof(double )); getch(); } Kích cỡ kiểu liệu người dùng định nghĩa tổng kích cỡ kiểu thành viên Chúng ta dùng toán tử sizeof(tên kiểu) để xác định độ lớn tính theo byte kiểu liệu Một điểm đặc biệt ý lập trình cấu trúc liệu cấu trúc liệu phải kèm theo phép tốn đó, biến gọi thuộc kiểu liệu for (i=1; i=i; j ){ if (A[j-1]>A[j]){ temp=A[j-1]; A[j-1]=A[j]; A[j]=temp; } } printf("\n Ket qua lan:%d", i); In(A,n); } PT IT } void In(int *A, int n){ register int i; for(i=0;iA[i]){ temp=A[i-1]; A[i-1]=A[i]; A[i]=temp; exchange=1; } } for(j=1; jA[j]){ temp=A[j-1]; A[j-1]=A[j]; A[j]=temp; exchange=1; } } printf("\n Ket qua lan:"); In(A,n); }while(exchange); } void In(int *A, int n){ register int i; for(i=0;i42 Duyệt phần tử thứ kj với 42 kj > 42 j giảm một, gặp phần tử thứ kj j) 11 23 36 42 65 58 94 74 99 87 229 Như vậy, kết thúc lần thứ nhất, hai đoạn phân biệt khoá 42 sau: (11 23 36) [42] (65 58 94 74 99 87) Quá trình lặp lại tương tự cho phân đoạn dãy xếp hồn tồn Chúng ta cài đặt giải thuật việc sử dụng stack đệ qui Độ phức tạp tính tốn giải thuật Quick Sort: Trường hợp tốt Cmax = Ctb = O (n log2n) Truờng hợp xấu Cmin= k.O(n2) Sau chương trình cài đặt giải thuật Quick Sort phương pháp đệ qui PT IT #include #include #include #include #include void qs(int *, int ,int); void Quick(int *,int ); void Init(int *, int); void In(int *, int); void Init(int *A, int n){ int i; printf("\n Tao lap day so:"); for (i=0; i