Professional Documents
Culture Documents
Tổng quan
Một số giải thuật
Một số cấu trúc dữ liệu
1. Tổng quan
Bài toán thực tế thường phức tạp
Để xây dựng chương trình - giải quyết bài toán
Phải xác định được
• Các dữ liệu liên quan
• Các thao tác cần thiết để giải quyết bài toán
Một số công cụ nâng cao
Con trỏ
Quản lý bộ nhớ
Hàm và tham số
Overloading
Con trỏ - Pointer
• Địa chỉ
• Đánh địa chỉ:
• địa chỉ tuyệt đối,
• tương đối
• Bộ nhớ thực
• Bộ nhớ ảo
Con trỏ - Pointer
Khái niệm
• Biến
• Giá trị các biến được lưu trữ trong bộ nhớ máy tính .Có thể truy cập tới
các giá trị đó qua tên biến, đồng thời cũng có thể qua địa chỉ của chúng
trong bộ nhớ
Con trỏ
• Thực chất là 1 biến mà nội dung của nó là địa chỉ của 1 đối tượng khác
(biến, hàm, nhưng không phải 1 hằng số)
• Có nhiều kiểu biến với
kích thước khác nhau =>
nên có nhiều kiểu con trỏ
VD: Con trỏ int => biến hay hàm kiểu int
Con trỏ - Pointer
• Để truy cập nội dung do biến con trỏ trỏ tới => toán tử lấy nội dung *
Con trỏ - Pointer
Ví dụ
Con trỏ - Pointer
Chú ý về biến con trỏ
Một con trỏ chỉ có thể trỏ tới 1 đối tượng cùng kiểu
Toán tử 1 ngôi * và & có độ ưu tiên cao hơn các toán tử số học
Có thể viết *p cho mọi nơi có đối tượng mà nó trỏ tới xuất hiện
Có thể gán nội dung 2 con trỏ cho nhau => cả hai con trỏ cùng
trỏ tới 1 đối tượng
Con trỏ - Pointer
Phép toán trên con trỏ
Cộng hoặc trừ con trỏ p với 1 số nguyên n
=> trả về 1 con trỏ cùng kiểu, là địa chỉ mới trỏ tới 1 đối tượng khác nằm
cách đối tượng đang bị trỏ n phần tử
Trừ 2 con trỏ => cho ta khoảng cách (số phần tử) giữa 2 con trỏ
KHÔNG có phép cộng, nhân, chia 2 con trỏ
Có thể dùng các phép gán, so sánh các con trỏ
=> Chú ý đến sự tương thích về kiểu
Con trỏ - Pointer
Phép toán trên con trỏ
Ví dụ
• Giả sử các địa chỉ ban đầu tương ứng của 3 con trỏ là 100, 200 và 300
=> kết quả ?
Chú ý
• ++ và -- có độ ưu tiên cao hơn * nên *p++ tương đương với *(p++)
Con trỏ - Pointer
Con trỏ void*
Là con trỏ không định kiểu => Nó có thể trỏ tới bất kì một loại
biến nào.
Thực chất một con trỏ void chỉ chứa một địa chỉ bộ nhớ mà
không biết rằng tại địa chỉ đó có đối tượng kiểu dữ liệu gì
=> không thể truy cập nội dung của một đối tượng thông qua con
trỏ void.
Để truy cập được đối tượng thì trước hết phải ép kiểu biến trỏ
void thành biến trỏ có định kiểu của kiểu đối tượng
Con trỏ - Pointer
Con trỏ void*
Con trỏ - Pointer
Con trỏ và mảng array
Chú ý:
• Nhiều ngôn ngữ không khuyến cáo dùng con trỏ
Quản lý bộ nhớ
Bộ nhớ động
Bộ nhớ tĩnh: khai báo mảng, biến và các đối tượng khác một
cách tường minh trước khi thực hiện chương trình.
Trong thực tế gặp các tình huống:
• không thể xác định trước được kích thước bộ nhớ cần thiết để làm việc
• đối tượng có kích thước thay đổi linh hoạt
Chương trình thường được cấu trúc thông qua các hàm. Mỗi
hàm là một module nhỏ trong chương trình,có thể được gọ
Ví dụ
• Mô tả tập số tự nhiên N
• 1 là số tự nhiên
• số tự nhiên cộng 1 cũng là số tự nhiên
• Giai thừa n!
• Không đệ quy: int factorial(int n)
n! = n * (n-1) * … * 1 {
• Đệ quy: if (n==0)
n! = 1 nếu n=0 return 1;
n*(n-1)! nếu n>0 else
return (n * factorial(n - 1));
}
Đệ quy
Thực hiện
Đệ quy
Các thành phần của giải thuật
Phần neo/dừng: trường hợp suy biến của đối tượng
• Ví dụ: 1 là số tự nhiên
cấu trúc rỗng là danh sách kiểu T,
0!=1,
Phần qui nạp: mô tả đối tượng (giải thuật) thông qua chính đối
tượng (giải thuật) đó một cách trực tiếp hoặc gián tiếp
• Ví dụ: n! = n * (n –1)!
Đệ quy
Các loại giải thuật
Đệ quy trực tiếp
• đệ quy tuyến tính
• đệ quy nhị phân
• đệ quy phi tuyến
Đệ quy gián tiếp
• đệ quy tương hỗ
Đệ quy
2. Tìm các trường hợp neo cùng giải thuật giải tương ứng
• Trường hợp suy biến của bài toán tổng quát
• Các trường hợp tương ứng với các gía trị biên của các biến điều khiển
• VD: FAC(1) =1
• USCLN(a,0) = a
3. Tìm giải thuật giải trong trường hợp tổng quát bằng phân rã bài
toán theo kiểu đệ quy
VD: Bài toán Tháp Hà Nội
Luật:
• Di chuyển mỗi lần một đĩa
• Không được đặt đĩa lớn lên trên đĩa nhỏ
VD: Bài toán Tháp Hà Nội
Bài toán THN (k,A,B,C): chuyển k đĩa từ cột A sang cột C lấy cột
B làm trung gian
1. Chuyển (k -1) đĩa từ cột A sang cột B lấy cột C làm trung gian
THN (k -1,A,C,B) (bài toán THN với n = k-1,A= A , B = C , C = B )
2. Chuyển 1 đĩa từ cột A sang cột C : Move ( A, C ) (thao tác cơ bản ).
3. Chuyển (k - 1 ) đĩa từ cột B sang cột C lấy cột A làm trung gian
THN( k -1,B,A,C) ( bài toán THN với n = k-1 , A = B , B = A , C = C )
Với n>1
THN(n,A,B,C) ≡
{
THN (n -1,A,C,B) ;
Move ( A, C ) ;
THN (n -1,B,A,C) ;
}
Khử đệ quy
Đệ quy
• Ưu điểm: gọn gàng, dễ hiểu, dễ viết code
• Nhược điểm: tốn không gian bộ nhớ và thời gian xử lý
=> Khử đệ quy ~ Thay thế bằng giải thuật không đệ quy
Một số giải thuật khác
Quay lui
Nhánh cận
Quy hoạch động
3. Cấu trúc dữ liệu
Các bài toán thực tế thường rất phức tạp
Phải xác định được
• Các dữ liệu liên quan đến bài toán => cấu trúc dữ liệu
• Các thao tác cần thiết để giải quyết bài toán => giải thuật
Cấu trúc dữ liệu
Số
Ngày tháng
Ký tự, xâu