Gọi t(n) là thời gian thực hiện của thuật toán
A (thông thường là chu kỳcủa CPU), t(n)
sẽlà một trong các loại:
a.O(1): độ phức tạp là một hằng số.
VD: for (int i=1; i<= 10 ; i++)
printf (“%d”, i );
Phép so sánh: i = 1.10 và i =11 (đểdừng) = 11.
Phép gán: i = 1 + (i = 1.10) = 11
54 trang |
Chia sẻ: lylyngoc | Lượt xem: 1626 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Bài giảng Cấu trúc dữ liệu - Nguyễn Thị Thúy Loan, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
BÀI GIẢNG
CẤU TRÚC DỮ LIỆU
ThS. Nguyễn Thị Thúy Loan
6/8/2010 Nguyễn Thị Thúy Loan 2
Cách đánh giá
Thực hành: 30%
Bài tập: 20%
Lý thuyết: 50%
6/8/2010 Nguyễn Thị Thúy Loan 3
Tài liệu tham khảo
1. Bài giảng: ThS. Nguyễn Hà Giang
2. Cấu trúc dữ liệu & giải thuật, Dương Anh Đức, Trần
Hạnh Nhi, NXB ĐHQG Tp.HCM, 2008.
3. Cấu trúc dữ liệu, Nguyễn Trung Trực, ĐHBK, 1992.
4. Giải thuật & lập trình, Lê Minh Hoàng, ĐHSPHN,
1999-2002.
5. Cấu trúc dữ liệu + giải thuật = chương trình, Nguyễn
Quốc Cường – Hoàng Đức Hải, NXB Giáo dục.
6. Fundamentals of Data Structures, Ellis Horowitz,
Sartaj Sahni.
6/8/2010 Nguyễn Thị Thúy Loan 4
NỘI DUNG CHƯƠNG TRÌNH
Độ phức tạp thuật toán.
Tìm kiếm và sắp xếp.
Danh sách liên kết.
Stack & Queue.
Cây.
ĐỘ PHỨC TẠP THUẬT
TOÁN
ThS. Nguyễn Thị Thúy Loan
Chương I
6/8/2010 Nguyễn Thị Thúy Loan 6
NỘI DUNG
I. ĐO THỜI GIAN
II. DỰA VÀO ĐỘ LỚN CỦA DỮ LIỆU
III. MỘT SỐ CÔNG THỨC THƯỜNG DÙNG
IV. CÁCH TÍNH ĐỘ PHỨC TẠP
6/8/2010 Nguyễn Thị Thúy Loan 7
Đo thời gian
6/8/2010 Nguyễn Thị Thúy Loan 8
Dựa vào độ lớn của dữ liệu
Gọi t(n) là thời gian thực hiện của thuật toán
A (thông thường là chu kỳ của CPU), t(n)
sẽ là một trong các loại:
a. O(1): độ phức tạp là một hằng số.
VD: for (int i=1; i<= 10 ; i++)
printf (“%d”, i );
Phép so sánh: i = 1..10 và i =11 (để dừng) = 11.
Phép gán: i = 1 + (i = 1..10) = 11.
6/8/2010 Nguyễn Thị Thúy Loan 9
Dựa vào độ lớn của dữ liệu
b. O(log2n): Tìm nhị phân.
c. O(√n): Kiểm tra một số có phải là số
nguyên tố?
VD: Kiểm tra số nguyên tố, xét i=2 → (n/2),
nếu i là ước số của n n không phải là
số nguyên tố, ngược lại n là nguyên tố.
6/8/2010 Nguyễn Thị Thúy Loan 10
Dựa vào độ lớn của dữ liệu
Nhận xét
Trừ số 2, tất cả các số chẵn không phải
là số nguyên tố.
Các số lẻ không có ước số chẵn.
i là ước số của n → (n/i) là ước số của n.
6/8/2010 Nguyễn Thị Thúy Loan 11
d. O(n): Độ phức tạp tuyến tính (áp dụng
duyệt mảng, dãy).
e. O(nlog2n): “thuật toán Logarit” (áp dụng
sắp xếp mảng).
f. O(nα) (α>1): đa thức.
g. O(2n), O(n!): mũ (áp dụng liệt kê tất cả
các tập con của tập gồm n phần tử).
Dựa vào độ lớn của dữ liệu
6/8/2010 Nguyễn Thị Thúy Loan 12
Một số công thức thường dùng
n
i
nnib
1 2
)1(.
n
i
na
1
1.
b
ai
b
i
a
i
Nbaab
1
1
1
)(1111
n
ai
aanni
2
)11)(1()1(
2
1
22
2
)1(n
i
nni
6/8/2010 Nguyễn Thị Thúy Loan 13
n
i
nnnic
1
2
6
)12)(1(.
n
ai
aaannni
6
)12)(1()12)(1(2
n
i
n
i
nniid
1
222
1
3
4
)1(.
Một số công thức thường dùng
6/8/2010 Nguyễn Thị Thúy Loan 14
Cách tính độ phức tạp
Ví dụ 1: Cho thuật toán tính tổng như sau:
long Tong (int n)
{ long s = 0;
for (int i = 1 ; i <= n ; i ++)
s += i;
return s;
}
a. Tính độ phức tạp của thuật toán.
b. Cải tiến để thuật toán có độ phức tạp nhỏ hơn.
6/8/2010 Nguyễn Thị Thúy Loan 15
Cách tính độ phức tạp
GIẢI
a) Số phép so sánh:
Số phép gán:
Độ phức tạp là O(n).
n
i
n
1
111
n
i
n
1
22)11(11
6/8/2010 Nguyễn Thị Thúy Loan 16
Cách tính độ phức tạp
b) Thực chất là tính:
Cải tiến: long Tong (int n)
{ return (n * (n + 1))/2;
}
Không phép so sánh, không phép gán
O(1).
n
i
nnis
1 2
)1(
6/8/2010 Nguyễn Thị Thúy Loan 17
Cách tính độ phức tạp
Vd2: Cho thuật toán sau:
long Tong (int n)
{ long s = 0;
for (int i = 1 ; i <= n ; i ++)
for (int j = i ; j<= n ; j ++)
s += j;
return s;
}
a. Tính độ phức tạp của thuật toán.
b. Cải tiến để thuật toán có độ phức tạp nhỏ hơn.
6/8/2010 Nguyễn Thị Thúy Loan 18
Cách tính độ phức tạp
Vd3: Cho thuật toán sau:
long Tong (int n)
{ long s = 0;
for (int i = 1 ; i <= n ; i ++)
for (int j = 1 ; j<= i*i ; j ++)
s += j;
return s;
}
a. Tính độ phức tạp của thuật toán.
b. Cải tiến để thuật toán có độ phức tạp nhỏ hơn.
TÌM KIẾM VÀ SẮP
XẾP
ThS. Nguyễn Thị Thúy Loan
Chương II
Tham khảo bài giảng ThS. Nguyễn Hà Giang 6/8/2010 Nguyễn Thị Thúy Loan 20
Nội dung trình bày
TÌM KIẾM
SẮP XẾP
6/8/2010 Nguyễn Thị Thúy Loan 21
Tìm kiếm là thao tác quan trọng & thường
được sử dụng trong tin học.
o Tìm kiếm một nhân viên trong danh sách
nhân viên.
o Tìm một sinh viên trong danh sách sinh viên
của một lớp…
o Tìm kiếm một tên sách trong thư viện.
Tìm kiếm
6/8/2010 Nguyễn Thị Thúy Loan 22
Tìm kiếm là quá trình xác định một đối
tượng nào đó trong một tập các đối tượng.
Kết quả trả về là đối tượng tìm được (nếu
có) hoặc một chỉ số (nếu có) xác định vị trí
của đối tượng trong tập đó.
Việc tìm kiếm dựa theo một trường nào đó
của đối tượng, trường này là khóa (key)
của việc tìm kiếm.
Tìm kiếm
6/8/2010 Nguyễn Thị Thúy Loan 23
VD: Muốn tìm sinh viên tên Nguyễn Văn A
có trong lớp hay không?
Ta có hai cách tìm kiếm như sau:
Tìm kiếm
6/8/2010 Nguyễn Thị Thúy Loan 24
Tìm kiếm
Tìm kiếm tuyến tính Tìm kiếm nhị phân
Tập dữ liệu đã
được sắp xếp
Tập dữ liệu
bất kỳ
Tìm kiếm
6/8/2010 Nguyễn Thị Thúy Loan 25
Bài toán được mô tả như sau:
Tập dữ liệu được lưu trữ là dãy a0, a2,..,
an-1. Giả sử chọn cấu trúc dữ liệu mảng để
lưu trữ dãy số này trong bộ nhớ chính, có
khai báo: int a[MAX];
Khóa cần tìm là x, có kiểu nguyên: int x;
Tìm kiếm
6/8/2010 Nguyễn Thị Thúy Loan 26
Ý tưởng chính: duyệt tuần tự từ phần tử
đầu tiên, lần lượt so sánh khóa tìm kiếm
với khoá tương ứng của các phần tử
trong danh sách. Cho đến khi gặp phần
tử cần tìm hoặc đến khi duyệt hết danh
sách.
Tìm kiếm tuyến tính
6/8/2010 Nguyễn Thị Thúy Loan 27
Bước 1: i = 0;
Bước 2: So sánh a[i] với x, có hai t.hợp:
o a[i] = x: Tìm thấy Trả về vị trí i
o a[i] x: Sang bước 3
Bước 3: i = i + 1// xét phần tử kế tiếp
o Nếu i≥N:Hết mảng không thấyTrả về -1
o Nếu i N: Quay lại bước 2
Các bước thực hiện
6/8/2010 Nguyễn Thị Thúy Loan 28
12 2 5 8 1 6 4
x = 8
Tìm được
Ví dụ: Cho dãy số a, giá trị tìm x = 8:
12 2 5 8 1 6 4
Tìm kiếm tuyến tính
6/8/2010 Nguyễn Thị Thúy Loan 29
1. Cài đặt bình thường.
2. Cải tiến lại bằng cách sử dụng phần tử
cầm canh.
Tìm kiếm tuyến tính
6/8/2010 Nguyễn Thị Thúy Loan 30
Nhận xét:
Giải thuật tìm kiếm tuyến tính không phụ
thuộc vào thứ tự của các phần tử trong
mảng, do vậy đây là phương pháp tổng
quát nhất để tìm kiếm trên một dãy bất kỳ.
Tìm kiếm tuyến tính
6/8/2010 Nguyễn Thị Thúy Loan 31
Một thuật toán có thể được cài đặt theo
nhiều cách khác nhau, kỹ thuật cài đặt
ảnh hưởng nhiều đến tốc độ thực hiện.
Ví dụ như thuật toán cải tiến sẽ chạy
nhanh hơn thuật toán trước do vòng lặp
while chỉ so sánh một điều kiện...
Tìm kiếm tuyến tính
6/8/2010 Nguyễn Thị Thúy Loan 32
Khái niệm:
Phép tìm kiếm nhị phân được áp dụng trên dãy
khóa đã có thứ tự: k[0] k[0]... k[n-1].
Phương pháp này dựa trên ý tưởng sau:
Giả sử ta cần tìm trong đoạn a[left..right] với khoá
tìm kiếm là x, trước hết ta xét phần tử giữa
a[mid], với mid = (left + right)/2.
Tìm kiếm nhị phân
6/8/2010 Nguyễn Thị Thúy Loan 33
Nếu a[mid] < x thì có nghĩa là đoạn a[left] đến
a[mid] chỉ chứa khóa < x, ta tiến hành tìm kiếm
từ a[mid+1] đến a[right].
Nếu a[mid] > x thì có nghĩa là đoạn a[mid] đến
a[right] chỉ chứa khoá > x, ta tiến hành tìm
kiếm từ a[left] đến a[mid-1].
Nếu a[mid]=x thì việc tìm kiếm thành công.
Quá trình tìm kiếm thất bại nếu left > right.
Tìm kiếm nhị phân
6/8/2010 Nguyễn Thị Thúy Loan 34
B1: left =0, right = n-1
B2: mid = (left + right)/2// lấy mốc so sánh
So sánh a[mid] với x, có 3 khả năng
o a[mid] = x: Tìm thấy Trả về vị trí mid
o a[mid] >x: right = mid -1;
o a[mid] < x: left = mid +1
B3:
o Nếu left right // còn phần tử Lặp B2
o Ngược lại: Trả về -1// đã xét hết các phần tử
Các bước thực hiện
6/8/2010 Nguyễn Thị Thúy Loan 35
Ví dụ: cho dãy số gồm 8 phần tử bên dưới và x = 8:
1 2 4 5 6 8 12 15
1 2 4 5 6 8 12 15
Left = 0
X = 8
Right = 7Mid = 3
1 2 4 5 6 8 12 15
Left = 4
X = 8
Right = 7Mid = 5
Đoạn tìm kiếm
Đoạn tìm kiếm
=
Tìm kiếm nhị phân
6/8/2010 Nguyễn Thị Thúy Loan 36
Nhận xét:
Thuật giải nhị phân dựa vào quan hệ giá trị
của các phần tử trong mảng để định hướng
trong quá trình tìm kiếm, do vậy chỉ áp dụng
được với dãy đã có thứ tự.
Thuật giải nhị phân tìm kiếm nhanh hơn tìm
kiếm tuyến tính.
Tìm kiếm nhị phân
6/8/2010 Nguyễn Thị Thúy Loan 37
Tuy nhiên khi áp dụng thuật giải nhị
phân thì cần phải quan tâm đến chi phí
cho việc sắp xếp mảng. Vì khi mảng
được sắp thứ tự rồi thì mới tìm kiếm nhị
phân.
Tìm kiếm nhị phân
6/8/2010 Nguyễn Thị Thúy Loan 38
Sắp xếp
Sắp xếp là quá trình bố trí lại các phần tử
của một tập đối tượng theo một thứ tự
nhất định.
Ví dụ: {1, 2, 5, 7, 9, 12}, {14, 12, 7, 5, 2, 1}
{“An” “Binh” “Dương” “Hương”}
6/8/2010 Nguyễn Thị Thúy Loan 39
Việc sắp xếp là một bài toán phổ biến
trong tin học. Do các yêu cầu tìm kiếm
thuận lợi, sắp xếp kết xuất cho các bảng
biểu...
Sắp xếp
6/8/2010 Nguyễn Thị Thúy Loan 40
Dữ liệu thường được tổ chức thành mảng
các mẫu tin.
Mỗi mẫu tin thường có một số các trường
dữ liệu khác nhau.
Trường tham gia quá trình tìm kiếm gọi là
khóa (key).
Việc sắp xếp sẽ được tiến hành dựa vào
giá trị khoá này.
Sắp xếp
6/8/2010 Nguyễn Thị Thúy Loan 41
1. Đổi chỗ trực tiếp (interchange Sort)
2. Chèn trực tiếp (insertion Sort)
3. Chọn trực tiếp (Selection Sort)
4. Nổi bọt (Bubble Sort )
5. Shell sort
6. Quick sort
Các phương pháp sắp xếp
6/8/2010 Nguyễn Thị Thúy Loan 42
Để tiện cho việc minh họa các thuật toán
sắp xếp ta mô tả bài toán như sau:
Cho một mảng a gồm các phần tử, mỗi
phần tử trong mảng có một thuộc tính
khóa. Hãy sắp xếp tăng hoặc giảm các
phần tử trong mảng theo giá trị khóa này.
Mô tả bài toán
6/8/2010 Nguyễn Thị Thúy Loan 43
Do mỗi phần tử có giá trị khóa nên ta gọi
k[0..n-1] là mảng các khóa của các phần
tử trong e.
Yêu cầu: sắp xếp các giá trị này sao cho
mảng k có thứ tự tăng hoặc giảm.
Mô tả bài toán
6/8/2010 Nguyễn Thị Thúy Loan 44
Ý tưởng:
Xuất phát từ đầu dãy, lần lượt tìm những
phần tử còn lại không thỏa thứ tự với
phần tử đang xét. Với mỗi phần tử tìm
được mà không thoả thứ tự
• Thực hiện hoán vị để thỏa thứ tự
Lặp lại tương tự với các phần tử tiếp theo
Interchange Sort
6/8/2010 Nguyễn Thị Thúy Loan 45
B1: i = 0; // đầu dãy
B2: j = i +1; // duyệt qua các phần tử sau i
B3: while j < n do
o if a[j] < a[i] then Swap(a[i], a[j]);
o j = j +1;
B4: i = i +1;
o if i < n then B2;
o else Kết thúc!
Các bước thực hiện
6/8/2010 Nguyễn Thị Thúy Loan 46
10 3 7 6 2 5 4 16
i
j
Ví dụ minh họa
6/8/2010 Nguyễn Thị Thúy Loan 47
Cài đặt
6/8/2010 Nguyễn Thị Thúy Loan 48
Ý tưởng:
Cho dãy ban đầu a[0], a[2],.., a[n-1], ta có
thể xem dãy con gồm một phần tử a[0] đã
được sắp.
Sau đó thêm a[1] vào đoạn a[0] sao cho
a[0] a[1] được sắp.
Insertion Sort
6/8/2010 Nguyễn Thị Thúy Loan 49
Tiếp tục thêm a[2] vào để có a[0] a[1] a[2]
được sắp....
Cho đến khi thêm xong a[n-1] vào đoạn
a[0] a[1]...a[n-2] đoạn a[0] a[1]...a[n-2]
a[n-1] được sắp.
Insertion Sort
6/8/2010 Nguyễn Thị Thúy Loan 50
B1: i = 1;//giả sử có đoạn a[0] đã được sắp
B2: x= a[i];
o Tìm được vị trí cần chèn x vào là pos
B3: Dời chỗ các phần tử từ a[pos] a[i-1]
sang phải một vị trí để dành chỗ cho a[i].
B4: a[pos] = x;// có a[0]...a[i] được sắp.
B5: i = i +1;
o Nếu i < n: Lặp lại B2
o Ngược lại: Dừng Dãy đã được sắp
Các bước thực hiện
6/8/2010 Nguyễn Thị Thúy Loan 51
Ý tưởng:
Lượt thứ nhất, chọn trong dãy khoá k[0..n-1] ra
khóa nhỏ nhất và đổi giá trị với k[0], khi đó k[0]
sẽ trở thành khoá nhỏ nhất.
Lượt thứ hai, chọn trong dãy khoá k[1..n-1] ra
khóa nhỏ nhất và đổi giá trị với k[1]….
Lượt n-2, chọn giá trị nhỏ nhất trong k[n-2] và
k[n-1] ra khoá nhỏ nhất và đổi giá trị với k[n-2].
Selection Sort
6/8/2010 Nguyễn Thị Thúy Loan 52
B1: i = 0
B2: Tìm phần tử a[min] nhỏ nhất trong dãy
hiện hành từ a[i] đến a[n-1]
B3: Hoán vị a[i] và a[min]
B4: Nếu i < n -1 thì i= i+1 Lặp B2
Ngược lại Dừng
Ví dụ: Cho dãy số như sau:
12 2 8 5 1 6 4 1
Các bước thực hiện
6/8/2010 Nguyễn Thị Thúy Loan 53
Ý tưởng:
Xuất phát từ cuối dãy, đổi chỗ các cặp phần
tử kế cận để đưa phần tử nhỏ hơn về đầu.
Sau đó ở bước tiếp theo không xét phần tử
đó nữa. Do vậy lần xử lý thứ i sẽ có vị trí
đầu dãy là i.
Lặp lại xử lý trên cho đến khi không còn
cặp phần tử nào được xét.
Bubble Sort
6/8/2010 Nguyễn Thị Thúy Loan 54
B1: i=0; // lần xử lý đầu tiên
B2: j=n-1; // duyệt từ cuối ngược về i
Trong khi (j>i) thực hiện:
o Nếu a[j] < a[j-1]: Hoán đổi a[j] và a[j-1]
o j = j -1;
B3: i = i+1; // lần xử lý kế tiếp
oNếu i > n-1: Hết dãy Dừng
o Ngược lại: quay lại B2
Các bước thực hiện
6/8/2010 Nguyễn Thị Thúy Loan 55
ShellSort
Ý tưởng:
Cải tiến insertion sort
o Hạn chế phương pháp chèn: khi luôn
chèn 1 phần tử vào đầu dãy!
ShellSort cải tiến bằng cách chia làm
nhiều dãy con và thực hiện phương pháp
chèn trên từng dãy con.
6/8/2010 Nguyễn Thị Thúy Loan 56
Xét một dãy a[0]...a[n-1], cho một số
nguyên h (1 h n), chia dãy thành h dãy
con như sau:
o Dãy con 1: a[1], a[1+h], a[1+2h]...
o Dãy con 2: a[2], a[2+h], a[2+2h]...
o Dãy con 3: a[3], a[3+h], a[3+2h]...
o Dãy con h: a[h], a[2h], a[3h]...
ShellSort
6/8/2010 Nguyễn Thị Thúy Loan 57
VD: cho dãy n = 8, h = 3
10 3 7 6 2 5 4 16
Dãy chính 10 3 7 6 2 5 4 16
Dãy con 1 10 6 4
Dãy con 2 3 2 16
Dãy con 3 7 5
Ví dụ minh họa
6/8/2010 Nguyễn Thị Thúy Loan 58
Với mỗi bước h, áp dụng Insertion Sort
trên từng dãy con độc lập để làm mịn dần
các phần tử trong dãy chính.
Tiếp tục làm tương tự đối với bước h div
2... cho đến h = 1.
Khi h =1 thực hiện Insertion Sort trên 1
dãy duy nhất là dãy chính
Kết quả được dãy phần tử được sắp.
Ý tưởng
6/8/2010 Nguyễn Thị Thúy Loan 59
Các bước thực hiện
B1: chọn k khoảng cách h[0], h[1],..,h[k-1], và
i = 0;
B2: Chia dãy ban đầu thành các dãy con có
bước nhảy là h[i].
o Thực hiện sắp xếp từng dãy con bằng
insertion sort.
B3: i = i+1
o Nếu i ≥ k: Dừng
o Ngược lại: Bước 2.
6/8/2010 Nguyễn Thị Thúy Loan 60
QuickSort
Thuật toán do Hoare đề xuất
o Tốc độ trung bình nhanh hơn thuật toán
khác.
o Do đó Hoare dùng “quick” để đặt tên
Ý tưởng chính: QS phân hoạch dãy ban
đầu thành hai phần dựa vào một giá trị x.
o Dãy 1: gồm các phần tử a[i] nhỏ hơn x
o Dãy 2: gồm các phần tử a[i] lớn hơn x
6/8/2010 Nguyễn Thị Thúy Loan 61
Phân hoạch dãy cần sắp a[l] .. a[r] thành
ba phần:
o a[k] < x, với k = 0...i
o a[k] = x, với k = i..j
o a[k] > x, với k = j..n-1
Trong đó x là một giá trị nào đó trong
dãy a[k] x
QuickSort
6/8/2010 Nguyễn Thị Thúy Loan 62
B1: Phân hoạch dãy a[l]...a[r] thành các
dãy con:
o Dãy con 1: a[l]...a[j] < x
o Dãy con 2: a[j+1]...a[i-1] = x
o Dãy con 3: a[i]...a[r] > x
B2:
o Nếu (l < j): Phân hoạch dãy a[l]..a[j]
o Nếu (i<r): Phân hoạch dãy a[i]...a[r]
Các bước thực hiện
B1: Chọn tùy ý một phần tử a[k] trong dãy là
giá trị mốc, l k r,
o Cho x = a[k], i = l, j = r;
B2: Tìm và hoán vị cặp phần tử a[i] và a[j]
không đúng thứ tự đang sắp:
o Trong khi a[i] < x i++;
o Trong khi a[j] > x j--;
o Nếu i <= j Swap(a[i], a[j])
B3: Nếu i <= j Bước 2;
o Ngược lại Dừng.
Ý tưởng
DANH SÁCH LIÊN
KẾT
ThS. Nguyễn Thị Thúy Loan
Chương III
Tham khảo bài giảng ThS. Nguyễn Hà Giang
6/8/2010 Nguyễn Thị Thúy Loan 65
Nội dung
Danh sách liên kết đơn
o Giới thiệu
o Cài đặt
o Thao tác
o Ứng dụng
Danh sách vòng
Danh sách liên kết kép
6/8/2010 Nguyễn Thị Thúy Loan 66
DSLK đơn - Giới thiệu
Mảng 1 chiều
o Kích thước cố định
o Chèn 1 phần tử vào mảng rất khó
o Các phần tử tuần tự theo chỉ số 0 n-1
o Truy cập ngẫu nhiên
0 1 2 3 4 n-2 n-1
chèn
6/8/2010 Nguyễn Thị Thúy Loan 67
Giới thiệu
Danh sách liên kết
Cấp phát động lúc chạy chương trình
Các phần tử nằm rải rác ở nhiều nơi trong bộ
nhớ
Kích thước danh sách chỉ bị giới hạn do RAM
Thao tác thêm Xóa đơn giản
6/8/2010 Nguyễn Thị Thúy Loan 68
Giới thiệu
Insert,
Delete
6/8/2010 Nguyễn Thị Thúy Loan 69
Định nghĩa
Danh sách liên kết đơn là chuỗi các Node,
được tổ chức theo thứ tự tuyến tính
Mỗi Node gồm 2 phần:
o Phần Data, information
o Phần link hay con trỏ trỏ đến Node kế tiếp
6/8/2010 Nguyễn Thị Thúy Loan 70
Ôn pointer
Nhắc lại pointer
int i, *pi; i pi
1FF0 1FF4
? ?
pi = &i;
i
pi
1FF0 1FF4
? 1FF0*pi
i = 10 or *pi = 10
i
pi
1FF0 1FF4
10 1FF0*pi
6/8/2010 Nguyễn Thị Thúy Loan 71
Minh họa
Mô tả danh sách
A1 A2 A3 An
Head Node Node Tail Node
null
Data Link
6/8/2010 Nguyễn Thị Thúy Loan 72
Minh họa
Ví dụ:
‘D’ 500 ‘S’ 600
‘L’ 300 ‘D’ null
700 500
600 300
Địa chỉ
pHead
6/8/2010 Nguyễn Thị Thúy Loan 73
Khai báo phần data
Khai báo danh sáchLK
Data
o Kiểu dữ liệu định nghĩa trước
o Chứa dữ liệu, thông tin của từng Node
Typedef struct Node
{ DATA info ;
Node * next ;
};
Data: int, long, float, SV,
NV,…. 6/8/2010 Nguyễn Thị Thúy Loan 74
typedef struct Node
{
Data info;
Node * next;
};
typedef struct Node
{
int info;
Node * next;
};
typedef struct Node
{
SinhVien info;
Node * next;
};
Cấu trúc
Node
Khai báo phần data
6/8/2010 Nguyễn Thị Thúy Loan 75
Khai báo và khởi tạo
typedef struct Node
{
Data info;
Node * next;
};
Node* h;
Node* h = NULL;
h quản lý danh sách
Khởi tạo danh sách
6/8/2010 Nguyễn Thị Thúy Loan 76
Thao tác cơ bản
Tạo một nút mới
Thêm phần tử vào đầu danh sách
Thêm phần tử vào cuối danh sách
Thêm phần tử vào sau q
Xóa phần tử đầu.
Xóa phần tử sau q
Tìm kiếm.
Sắp xếp.
Phần minh
họa sẽ dùng
Data là int
6/8/2010 Nguyễn Thị Thúy Loan 77
Tạo nút mới
Node * Getnode (Data x)
{ Node * p = new Node;
if ( p == NULL ) return NULL;
p info = x;
p next = NULL;
return p ;
}
6/8/2010 Nguyễn Thị Thúy Loan 78
Thêm vào đầu danh sách
h h
p new
h
p
h
p
Thêm phần tử vào đầu DS
6/8/2010 Nguyễn Thị Thúy Loan 79
Thêm phần tử vào đầu DS
6/8/2010 Nguyễn Thị Thúy Loan 80
Thêm phần tử vào cuối DS
6/8/2010 Nguyễn Thị Thúy Loan 81
Thêm vào sau phần tử q
Thêm vào sau Node q trong danh sách
q q
p new
q
p
q
p
6/8/2010 Nguyễn Thị Thúy Loan 82
Xóa phần tử đầu
Xóa phần tử đầu danh sách
h h
h h
p
p
6/8/2010 Nguyễn Thị Thúy Loan 83
Xóa phần tử sau q
Xóa phần tử sau Node q trong danh sách
q p
pq
q
6/8/2010 Nguyễn Thị Thúy Loan 84
Xóa toàn bộ danh sách
h
p
h
p
6/8/2010 Nguyễn Thị Thúy Loan 85
Xóa toàn bộ danh sách
6/8/2010 Nguyễn Thị Thúy Loan 86
Tìm kiếm
Tìm phần tử lớn nhất.
Tìm vị trí phần tử lớn nhất.
Tìm phần tử có giá trị bằng x.
6/8/2010 Nguyễn Thị Thúy Loan 87
Sắp xếp
void Interchange_sort (Node * h)
{
}
6/8/2010 Nguyễn Thị Thúy Loan 88
void Selection_sort (Node* h)
{
}
Sắp xếp
6/8/2010 Nguyễn Thị Thúy Loan 89
Duyệt danh sách
void Duyet (Node* h [, Node * t] )
{ for (Node* p = h; p ; p = p next)
;
}
6/8/2010 Nguyễn Thị Thúy Loan 90
Minh họa in danh sách
p = h;
while (p!=NULL)
{
printf(“ %5d”, p info);
p = p next;
}
3000 4 5000 10 4000 5 NULL
3000 5000 4000h
p
6/8/2010 Nguyễn Thị Thúy Loan 91
p = h;
while (p!=NULL)
{
printf(“ %5d”, p info);
p = p next;
}
3000 4 5000 10 4000 5 NULL
3000 5000 4000
3000
h
p
Minh họa in danh sách
6/8/2010 Nguyễn Thị Thúy Loan 92
p = h;
while (p!=NULL)
{
printf(“ %5d”, p info);
p = p next;
}
3000 4 5000 10 4000 5 NULL
3000 5000 4000
3000
h
p
Minh họa in danh sách
6/8/2010 Nguyễn Thị Thúy Loan 93
p = h;
while (p!=NULL)
{
printf(“ %5d”, p info);
p = p next;
}
3000 4 5000 10 4000 5 NULL
3000 5000 4000
3000
h
p
Minh họa in danh sách
6/8/2010 Nguyễn Thị Thúy Loan 94
In danh sách
void Indanhsach(Node *h)
{ for (Node *p = h; p; p = p next)
printf(“%5d”, p info);
} void Indanhsach (