– Vận dụng được các kiểu dữ liệu trừu tượng để giải quyết bài toán đơn giản trong thực tế... Kiểu dữ liệu có thể là kiểu cơ bản hay kiểu trừu tượng • Cấu trúc dữ liệu là sự sắp xếp có lo
Trang 2bảng băm, đồ thị bằng một ngôn ngữ lập trình căn bản
– Vận dụng được các kiểu dữ liệu trừu tượng để giải quyết bài toán đơn giản trong thực tế
– Mã giả (pseudocode)
– C++
Trang 4– Kiến thức về kỹ thuật lập trình.
– Sử dụng thành thạo ngôn ngữ C++
Trang 5[2] Robert L.Kruse, Alexander J.Ryba, Data Structures And Program Design In C++, Prentice-Hall International Inc., 1999.
[3] Bài giảng & Bài thực hành CTDL - Trường ĐHCN.
– Tài liệu tham khảo:
[1] Giáo trình Cấu trúc dữ liệu 1, Trần Hạnh Nhi – Dương Anh Đức, Trường DHKHTN – DHQG TP.HCM.
[2] Cấu trúc dữ liệu, Nguyễn Trung Trực, Trường DHBK – DHQG TP.HCM
[3] Nguyễn Ngô Bảo Trân, Giáo trình cấu trúc dữ liệu và giải thuật – Trường Đại học Bách Khoa TP.HCM, 2005.
Trang 6Thi cuối kỳ 50% Tuần 9
Yêu cầu đối với sinh viên:
• Dự lớp: lý thuyết trên 80% , thực hành bắt buộc 100%
• Bài tập: hoàn thành các bài tập trên lớp và ở nhà
• Tham gia đầy đủ các buổi thảo luận của nhóm
Trang 7Địa chỉ download tài liệu:
• http://kimchidhcn.wordpress.com
Trang 9Độ phức tạp của thuật toán
3
1
Câu hỏi và bài tập
Thực hiện và hiệu chỉnh chương trình
Trang 10liệu trung gian hoặc dữ liệu đưa ra (output data) Mỗi dữ liệu có một kiểu dữ liệu riêng Kiểu dữ liệu
có thể là kiểu cơ bản hay kiểu trừu tượng
• Cấu trúc dữ liệu là sự sắp xếp có logic của thành phần dữ liệu được kết hợp với nhau và là tập hợp các thao tác chúng ta cần để truy xuất các thành phần dữ liệu.
Trang 11Một cấu trúc dữ liệu tốt phải thỏa mãn:
• Phản ánh đúng thực tế: Cần xem xét kỹ lưỡng cũng như dự trù các trạng thái biến đổi của dữ liệu trong chu trình sống để có thể chọn CTDL lưu trữ thể hiện chính xác đối tượng thực tế.
• Phù hợp với các thao tác trên đó: Tăng tính hiệu quả của đề án, việc phát triển các thuật toán đơn giản, tự nhiên hơn => chương trình đạt hiệu quả cao hơn về tốc độ xử lý.
• Tiết kiệm tài nguyên hệ thống: CTDL chỉ nên sử dụng tài nguyên hệ thống vừa đủ để đảm nhiệm được chức năng của nó Loại tài nguyên cần quan tâm là : CPU
và bộ nhớ.
Trang 12• Các cấu trúc bao gồm
– Danh sách liên kết (linked lists)
– Ngăn xếp (Stack), Hàng đợi (Queue)
– Cây nhị phân (binary trees)
– …
Trang 13• Giải thuật (Algorithm):
– Còn gọi là thuật toán là tập các bước có thể tính toán
được để đạt được kết quả mong muốn ( A
computable set of steps to achieve a desired result)
– Giải thuật được xây dựng trên cơ sở của cấu trúc dữ liệu đã được chọn.
– Giải thuật có thể được minh họa bằng ngôn ngữ tự nhiên (natural language), bằng sơ đồ (flow chart) hoặc bằng mã giả (pseudo code)
7
Trang 14 Nhanh hơn.
Nhiều hơn.
Giải quyết những bài toán mà con người không thể hoàn thành được.
• Làm sao đạt được những mục tiêu đó?
Nhờ vào sự tiến bộ của kỹ thuật: tăng cấu hình máy chi phí cao
Nhờ vào các thuật toán hiệu quả: thông minh và chi phí thấp
“Một máy tính siêu hạng vẫn không thể cứu vãn một thuật toán tồi!”
Trang 15• Giải thuật (Algorithm):
• Ví dụ: Tính tổng các số nguyên lẻ từ 1 n Input: n
Trang 16– Hữu hạn (finiteness): giải thuật phải luôn luôn kết thúc sau một số hữu hạn bước
– Xác định (definiteness): mỗi bước của giải thuật phải được xác định rõ ràng và phải được thực hiện chính xác, nhất quán
– Hiệu quả (effectiveness): các thao tác trong giải thuật phải được thực hiện trong một lượng thời gian hữu hạn
– Ngoài ra một giải thuật còn phải có đầu vào (input) và đầu ra (output).
Trang 17Tầm quan trọng của CTDL & giải thuật :
•Thực hiện một đề án tin học là chuyển bài toán thực tế thành bài toán có thể giải quyết trên máy tính
•Một bài toán thực tế bất kỳ đều bao gồm dữ liệu và các yêu cầu xử lý trên dữ liệu đó để xây dựng một mô hình tin học phản ánh được bài toán thực tế cần chú trọng đến hai vấn đề:
•Tổ chức biểu diễn các đối tượng thực tế: Mô hình tin học của bài toán, cần phải tổ chức sao cho
– vừa phản ánh chính xác dữ liệu thực tế,
– vừa dễ dàng dùng máy tính để xử lý
xây dựng cấu trúc dữ liệu
•Xây dựng các thao tác xử lý dữ liệu : Từ những yêu cầu thực tế, cần tìm ra các giải thuật tương ứng để xác định trình tự các thao tác máy tính phải thi hành để cho ra kết quả mong muốn đây là bước xây dựng giải thuật cho bài toán.
Trang 18CTDL + Thuật toán = Chương trình
Trang 19Các tiêu chuẩn đánh giá cấu trúc dữ liệu
• Để đánh giá một cấu trúc dữ liệu chúng ta thường dựa vào một số tiêu chí sau:
– Cấu trúc dữ liệu phải tiết kiệm tài nguyên (bộ nhớ trong),
– Cấu trúc dữ liệu phải phản ảnh đúng thực tế của bài toán,
– Cấu trúc dữ liệu phải dễ dàng trong việc thao tác dữ liệu.
Trang 20của thuật toán để so sánh tương đối các thuật toán với nhau
• Trong thực tế, thời gian thực hiện còn phụ thuộc cấu hình máy, dữ liệu đưa vào, tài nguyên…
• Để ước lượng thời gian thực hiện thuật toán xem xét 2 trường hợp
– Trường hợp tốt nhất: Tmin
– Trường hợp xấu nhất: Tmax
• Với Tmin và Tmax thời gian thực hiện trung bình của thuật toán Tavg
Làm thế nào đánh giá?
Trang 21• Để đánh giá hiệu quả của một thuật toán, có thể tính số lượng các phép tính phải thực hiện của thuật toán này:
Trang 22– Nếu i < n, quay lại bước 2.
– Ngược lại, dừng thuật toán.
• Số phép gán của thuật toán là bao nhiêu?
Trang 23Các độ phức tạp thường gặp
• Độ phức tạp hằng số: O(1) – thời gian chạy
không phụ thuộc vào độ lớn đầu vào
• Độ phức tạp tuyến tính: O(n) – thời gian chạy
tỉ lệ thuận với độ lớn đầu vào
• Độ phức tạp logarit: O(logn)
• Độ phức tạp đa thức : O(P(n)) , với P là đa thức có
bậc từ 2 trở lên
• Độ phức tạp hàm mũ: O(2n)
Trang 25Thứ tự độ phức tạp của các thuật toán
Trang 26Qui tắc cộng:
• Nếu T1(n) và T2(n) là thời gian thực hiện của hai đoạn chương trình P1 và P2; và T1(n)=O(f(n)), T2(n)=O(g(n) thì thời gian thực hiện của đoạn hai chương trình đó nối tiếp nhau là T(n)=O(max(f(n),g(n)))
• Ví dụ 1-6:
– Lệnh gán x=15 tốn một hằng thời gian hay O(1)
– Lệnh đọc dữ liệu scanf(“%d”, x) tốn một hằng thời gian hay O(1)– Vậy thời gian thực hiện cả hai lệnh trên nối tiếp nhau là O(max(1,1))=O(1)
Trang 28• Thời gian thực hiện của mỗi lệnh gán, Scanf, Printf là O(1)
• Thời gian thực hiện của một chuỗi tuần tự các lệnh được xác định bằng qui tắc cộng Như vậy thời gian này là thời gian thi hành một lệnh nào đó lâu nhất trong chuỗi lệnh.
• Thời gian thực hiện cấu trúc IF là thời gian lớn nhất thực hiện lệnh sau IF hoặc sau ELSE và thời gian kiểm tra điều kiện Thường thời gian kiểm tra điều kiện là O(1).
• Thời gian thực hiện vòng lặp là tổng (trên tất cả các lần lặp) thời gian thực hiện thân vòng lặp Nếu thời gian thực hiện thân vòng lặp không đổi thì thời gian thực hiện vòng lặp là tích của số lần lặp với thời gian thực hiện thân vòng lặp.
Trang 29Qui tắc tổng quát để phân tích một chương trình:
Ví dụ : Tính thời gian thực hiện của đoạn chương trình
• void BubleSort(int a[], int N )
{ int i, j, temp;
{1} for (i = 0 ; i<N-1 ; i++) {2} for (j =N-1; j >i ; j ) {3} if(a[j]< a[j-1]) // nếu sai vị trí thì đổi chỗ
Trang 30• Phương pháp thực nghiệm.
• Phương pháp xấp xỉ toán học.
Trang 31 Chịu sự hạn chế của ngôn ngữ lập trình.
Ảnh hưởng bởi trình độ của người lập trình.
Chọn được các bộ dữ liệu thử đặc trưng cho tất cả tập các
dữ liệu vào của thuật toán: khó khăn và tốn nhiều chi phí
Phụ thuộc vào phần cứng.
Trang 32tiệm xấp xỉ tiệm cận qua các khái niệm O().
• Ưu điểm: Ít phụ thuộc môi trường cũng như phần cứng hơn.
• Nhược điểm: Phức tạp.
• Các trường hợp độ phức tạp quan tâm:
– Trường hợp tốt nhất (phân tích chính xác)
– Trường hợp xấu nhất (phân tích chính xác)
– Trường hợp trung bình (mang tích dự đoán)
Trang 33yêu cầu (mới).
Trang 34 Giải thuật + Kiểm tra cài đặt
Trang 36• Bước 1: Xác định yêu cầu (Requirements
Specification).
• Bước 2: Phân tích (Analysis).
• Bước 3: Thiết kế (Design).
• Bước 4: Cài đặt (Implementation).
• Bước 5: Thử nghiệm (Testing).
• Bước 6: Vận hành, theo dõi và bảo dưỡng (Operation, follow-up and Maintenance).
Trang 376 Mảng con trỏ ( Pointer array )
7 Mảng hai chiều ( Two-dimensional array )
Trang 38• Lệnh nhập và xuất dữ liệu
– Using scanf, prinf (C standard)
– Using cin, cout (Cpp)
Ví dụ: Tìm số lớn nhất trong ba số nhập vào từ bàn phím
cout<<“Nhap 3 so: “; cin>>a>>b>>c;
cout <<“max = “<<max;
C++
#include <iostream.h>
C
Trang 391 Cấu trúc chương trình C/C++
• Qui cách viết chương trình
– Các dòng trong cùng một khối thẳng cột – Khối con của một khối lùi vào ít nhất một TAB – Ghi chú thích ở những chỗ cần thiết
Chương 1: Ôn tập C/C++
Trang 402 Biến, Hằng, Kiểu dữ liệu và Các cú
pháp cơ bản
3 Địa chỉ ( Address )
4 Con trỏ ( Pointer )
5 Mảng ( Array )
6 Mảng con trỏ ( Pointer array )
7 Mảng hai chiều ( Two-dimensional
Trang 412 Biến
• Là định danh của một vùng trong bộ nhớ
dùng để giữ một giá trị mà có thể bị thay đổi bởi chương trình Tất cả các biến phải được khai báo trước khi được sử dụng
• Khai báo biến:
• Khai báo và khởi tạo biến:
Kiểu_dữ_liệu tên_biến;
Kiểu_dữ_liệu tên_biến = giá trị;
Chương 1: Ôn tập C/C++
Ví dụ: int i, j, k;
unsigned char dem;
float ketqua, delta;
Trang 42 Hằng là những giá trị cố định (fixed values) mà chương trình không thể thay đổi
Trang 432 Kiểu dữ liệu cơ sở
Trang 44• Kiểu ký tự:
– Có thể có các kích thước sau:
+ Kiểu ký tự 1 byte + Kiểu ký tự 2 bytes
– Các phép toán: O = {+, -, <, >, <=, >=, =, ORD, CHR, …}
• Kiểu chuỗi ký tự:
– Có kích thước tùy thuộc vào từng ngôn ngữ lập trình
– Các phép toán: O = {+, &, <, >, <=, >=, =, Length, Trunc, …}
• Kiểu luận lý:
– Thường có kích thước 1 byte
– Kiểu luận lý thường được thực hiện với các phép toán: O = {NOT, AND, OR, XOR, <, >, <=, >=, =, …}
Trang 452 Các phép toán
• Chuyển đổi kiểu:
– Trong biểu thức: kiểu thấp hơn sẽ được nâng thành kiểu cao hơn trước khi thực hiện phép toán
Ví dụ: 7 + 3.5 – Trong phép gán: Giá trị của biểu thức vế phải được chuyển sang kiểu của biến vế trái
Ví dụ:
Chương 1: Ôn tập C/C++
Trang 48Chương 1: Ôn tập C/C++
• Cho 2 số nguyên M, N
Hãy mô tả các vị từ logic sau bằng các biểu thức logic (theo M, N) tương ứng trong NNLT “C/C+
Trang 49Câu hỏi
Chương 1: Ôn tập C/C++
3) Cho a, b, c là 3 số tự nhiên đại diện cho 3 cạnh của tam
giác T Hãy mô tả các mệnh đề dưới đây bằng biểu thức logic (theo a, b, c) tương ứng trong NNLT “C/C++”:
• T là tam giác thường.
• T là tam giác cân.
• T là tam giác vuông.
• T là tam giác vuông cân.
• T là tam giác đều.
Trang 50Chương 1: Ôn tập C/C++
4) Gọi N là số tự nhiên chỉ năm Hãy mô tả mệnh đề định nghĩa năm nhuần bằng biểu thức logic (theo N) tương ứng trong NNLT “C/C++” như sau: “Năm nhuần là năm chia chẵn cho 400 hoặc nếu nó chia chẳn cho 4 thì đồng thời không được chia chẳn cho 100”.
Trang 51Câu hỏi
Chương 1: Ôn tập C/C++
6) Viết chương trình làm calculator đơn giản (+, -, *, /, %)
7) Viết chương trình tính chu vi, diện tích hình tròn.
8) Viết chương trình tính chu vi, diện tích hình tam giác
theo 3 cạnh.
9) Viết chương trình in trị đảo ngược của số nguyên gồm 3
chữ số (chữ số hàng đơn vị khác 0) Ví dụ, nếu nhập vào
483 thì in ra 384.
10) Viết chương trình hoán đổi trị của 2 số nguyên.
Trang 52− Kí tự đứng sau và mã ASCII của kí tự đó.
− Kí tự đứng trước và mã ASCII của kí tự đó
13) Viết chương trình nhập vào 1 kí tự Sau đó in ra kí tự hoa/thường tương ứng ngược lại.
14) Viết chương trình thử nghiệm toán tử ++, .
Trang 56switch ( biểu_thức_nguyên ) {
case hằng_1 :
các_câu_lệnh_1 [ break; ]
case hằng_2 :
các_câu_lệnh_2 [ break; ]
Trang 572 Các cú pháp cơ bản
Chương 1: Ôn tập C/C++
NMLT - Câu lệnh điều kiện và rẽ nhánh
Trang 58Chương 1: Ôn tập C/C++
giây sau ? / 1 giây trước ?
16) Viết chương trình tính tiền điện khi biết chỉ số cũ, chỉ số mới, và công thức tính như sau: nếu số kw dưới 100 thì đơn giá là 1200, dưới 150 thì đơn giá là 1500 cho số kw
từ 100 đến 150, đơn giá là 2000 cho những kw từ 200 trở đi?
17) Viết chương trình nhập tháng m, năm y In ra cho biết tháng m, năm y có tối đa bao nhiêu ngày ?
18) Viết chương trình nhập ngày d, tháng m, năm y In ra cho biết ngày vừa nhập có hợp
lệ hay không ?
19) Viết chương trình nhập vào 1 bộ ngày tháng năm In ra ngày hôm sau là ngày mấy?
20) Viết chương trình nhập vào 1 bộ ngày tháng năm In ra ngày hôm trước là ngày mấy?
Trang 59for ( bt_khởi_tạo ; bt_kiểm_tra ; bt_tăng )
{ khối_lệnh [continue]
khối_lệnh [continue]
Trang 60Chương 1: Ôn tập C/C++
NMLT - Câu lệnh lặp
int n = 10 ; for (int i = 1 ; i <= n ; i++)
cout<<“\n”<< i;
int i = 1 ; while ( i <= n ) {
cout<<“\n”<<i; i++ ; }
int i = 1 ;
do {
cout<<“\n”<< i; i++;
} while ( i <= n );
Trang 62Chương 1: Ôn tập C/C++
NMLT - Câu lệnh lặp
7 Nhập một số nguyên dương n Xuất ra số ngược lại
Ví dụ: Nhập 1706 Xuất 6071.
8 Tìm và in lên màn hình tất cả các số nguyên trong
phạm vi từ 10 đến 99 sao cho tích của 2 chữ số bằng 2 lần tổng của 2 chữ số đó.
9 Tìm ước số chung lớn nhất của 2 số nguyên dương a
và b nhập từ bàn phím.
10 Nhập n In n số đầu tiên trong dãy Fibonacy.
a a0 = a1 = 1
b an = an – 1 + an – 2
Trang 636 Mảng con trỏ ( Pointer array )
7 Mảng hai chiều ( Two-dimensional
Trang 64 Mỗi biến có hai thuộc tính:
Địa chỉ (address) và giá trị (value )
Biến phải được khai báo trước khi sử dụng
Ví dụ: int y=0;
char kytu;
cout << “Giá trị của 'y' là: " << y << "\n";
cout << “Địa chỉ của 'y' là: " << &y << "\n\n";
Bộ nhớ tại địa chỉ 3: giá trị: 45
Bộ nhớ tại địa chỉ 2: giá trị "Dave"
Trang 656 Mảng con trỏ ( Pointer array )
7 Mảng hai chiều ( Two-dimensional
Trang 66• Là một kiểu dữ liệu đặc biệt, có giá trị là một địa chỉ vùng nhớ của một đối tượng (biến, hàm).
• Cho phép truy xuất một đối tượng một cách gián tiếp, nghĩa là tham chiếu 1 đối tượng khác thông qua địa chỉ của nó.
• Việc cấp phát động cho mảng được thực hiện thông qua con trỏ.
• Tùy theo hệ máy mà kiểu dữ liệu con trỏ có các kích thước khác nhau:
+ Hệ máy PC: 2 bytes+ Hệ máy tính lớn: 4 bytesInt i; giá trị của biến Int *p = &i; //p chứa địa chỉ của i
*p = 10 ; //gán i=10
Ví dụ
Trang 67• Khai báo kiểu con trỏ:
• Khai báo biến con trỏ:
– Mẫu 1: tênkiểucontrỏ tênbiếncontrỏ;
– Mẫu 2: kiểucơsởT *tênbiếncontrỏ;
• Ví dụ: typedef int *intpointer;
intpointer pt;
hay Ví dụ int *pt;
4 Con trỏ ( Pointer )
Trang 68Các thao tác trên biến con trỏ
1 Gán 1 địa chỉ cho biến con trỏ:
– tênbiếncontrỏ = &tênbiếncầnlấyđịachỉ;– tênbiếncontrỏ = NULL;
• Chứa địa chỉ của 1 biến cấu trúc:
– struct HocSinh *P, hs; P = &hs
Trang 69Các thao tác trên biến con trỏ
2 Truy xuất nội dung 1 biến do biến con trỏ trỏ đến:
*tênbiếncontrỏ
• Lưu ý: Toán tử * và & cùng độ ưu tiên
3 Phép toán số học trên kiểu con trỏ:
• Chỉ có ý nghĩa khi thực hiện trên mảng
– pt + i ==> Cộng địa chỉ vùng nhớ lưu trong pt với i*sizeof(T)
– pt1 – pt2 ==> Số phần tử có kích thước sizeof(T) giữa 2 địa chỉ
• Phép so sánh con trỏ: so sánh địa chỉ lưu trong 2 biến con trỏ: ==, !=
• Tăng, giảm
– Ví dụ: int *p; p=p+2; // tăng 2 kích thước bộ nhớ int
4 Con trỏ ( Pointer )
Trang 70cout<<" The address of i is "<< ia <<" \n ";
cout<<" The value at that location is "<< i <<" \n "; cout<<" The value at that location is "<< *ia <<" \n ";
*ia = 50;
cout<<" The value of i is "<<i;
}
Chương 1: Ôn tập C/C++