154
Mục Lục MỤC LỤC. MỤC LỤC.................................................. 1 CHƯƠNG I: TỔNG QUAN..................................8 1. Giới thiệu............................................ 8 2. Vai trò cấu trúc dữ liệu trong tin học................9 3. Các tiêu chuẩn đánh giá cấu trúc dữ liệu.............12 4. Kiểu dữ liệu......................................... 13 4.1. Định nghĩa kiểu dữ liệu...........................13 4.2. Các kiểu dữ liệu cơ bản...........................13 4.3. Các kiểu dữ liệu có cấu trúc cơ bản...............14 4.3.1. Kiểu chuỗi ký tự..............................14 4.3.2. Kiểu mảng.....................................14 4.4. Các kiểu dữ liệu có cấu trúc......................14 5. Khái niệm giải thuật.................................15 5.1. Giải thuật là gì?.................................15 5.2. Tính chất giải thuật..............................15 6. Tổng quan về đánh giá độ phức tạp giải thuật.........17 6.1. Khái niệm “O”.....................................19 6.2. Quy tắc xác định O(?).............................20 6.3. Ví dụ về cách đánh giá thuật toán.................20 6.4. Sự phân lớp của độ phức tạp.......................21 7. Bài tập.............................................. 22 7.1. Lý thuyết.........................................22 7.2. Thực hành.........................................23 CHƯƠNG II: CÁC GIẢI THUẬT TÌM KIẾM VÀ SẮP XẾP..........24 1. Giới thiệu........................................... 24 2. Nhu cầu tìm kiếm và sắp xếp dữ liệu trong 1 hệ thống thông tin............................................... 25 3. Các giải thuật tìm kiếm..............................25 3.1. Tìm kiếm tuyến tính...............................26 3.1.1. Ý tưởng giải thuật............................26 3.1.2. Lưu đồ........................................26 3.1.3. Ví dụ.........................................26 3.1.4. Cài đặt.......................................27 1

data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Embed Size (px)

Citation preview

Page 1: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Mục Lục

MỤC LỤC.

MỤC LỤC.........................................................................................................................1CHƯƠNG I: TỔNG QUAN....................................................................................81. Giới thiệu...................................................................................................................82. Vai trò cấu trúc dữ liệu trong tin học........................................................................93. Các tiêu chuẩn đánh giá cấu trúc dữ liệu.................................................................124. Kiểu dữ liệu.............................................................................................................13

4.1. Định nghĩa kiểu dữ liệu...................................................................................134.2. Các kiểu dữ liệu cơ bản...................................................................................134.3. Các kiểu dữ liệu có cấu trúc cơ bản.................................................................14

4.3.1. Kiểu chuỗi ký tự......................................................................................144.3.2. Kiểu mảng...............................................................................................14

4.4. Các kiểu dữ liệu có cấu trúc............................................................................145. Khái niệm giải thuật................................................................................................15

5.1. Giải thuật là gì?...............................................................................................155.2. Tính chất giải thuật..........................................................................................15

6. Tổng quan về đánh giá độ phức tạp giải thuật.........................................................176.1. Khái niệm “O”.................................................................................................196.2. Quy tắc xác định O(?)......................................................................................206.3. Ví dụ về cách đánh giá thuật toán...................................................................206.4. Sự phân lớp của độ phức tạp...........................................................................21

7. Bài tập......................................................................................................................227.1. Lý thuyết..........................................................................................................227.2. Thực hành........................................................................................................23

CHƯƠNG II: CÁC GIẢI THUẬT TÌM KIẾM VÀ SẮP XẾP.................................241. Giới thiệu.................................................................................................................242. Nhu cầu tìm kiếm và sắp xếp dữ liệu trong 1 hệ thống thông tin............................253. Các giải thuật tìm kiếm...........................................................................................25

3.1. Tìm kiếm tuyến tính........................................................................................263.1.1. Ý tưởng giải thuật....................................................................................263.1.2. Lưu đồ.....................................................................................................263.1.3. Ví dụ........................................................................................................263.1.4. Cài đặt......................................................................................................273.1.5. Đánh giá giải thuật...................................................................................283.1.6. Nhận xét...................................................................................................28

3.2. Tìm kiếm nhị phân...........................................................................................283.2.1. Ý tưởng giải thuật....................................................................................283.2.2. Lưu đồ.....................................................................................................293.2.3. Ví dụ........................................................................................................29

1

Page 2: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Mục Lục

3.2.4. Cài đặt......................................................................................................303.2.5. Đánh giá giải thuật...................................................................................303.2.6. Nhận xét...................................................................................................31

4. Các giải thuật sắp xếp..............................................................................................314.1. Định nghĩa sắp xếp..........................................................................................314.2. Các phương pháp sắp xếp................................................................................314.3. Phương pháp đổi chỗ trực tiếp (InterchangeSort)...........................................32

4.3.1. Ý tưởng giải thuật....................................................................................324.3.2. Ví dụ........................................................................................................324.3.3. Cài đặt......................................................................................................344.3.4. Đánh giá giải thuật...................................................................................35

4.4. Phương pháp chèn trực tiếp (InsertionSort)....................................................354.4.1. Ý tưởng giải thuật....................................................................................354.4.2. Ví dụ........................................................................................................354.4.3. Cài đặt......................................................................................................374.4.4. Đánh giá giải thuật...................................................................................374.4.5. Nhận xét...................................................................................................37

4.5. Phương pháp chọn trực tiếp (SelectionSort)...................................................384.5.1. Ý tưởng giải thuật....................................................................................384.5.2. Ví dụ........................................................................................................394.5.3. Cài đặt......................................................................................................404.5.4. Đánh giá giải thuật...................................................................................41

4.6. Phương pháp nổi bọt (BubbleSort)..................................................................414.6.1. Ý tưởng giải thuật....................................................................................414.6.2. Ví dụ........................................................................................................414.6.3. Cài đặt......................................................................................................444.6.4. Đánh giá giải thuật...................................................................................444.6.5. Nhận xét...................................................................................................44

4.7. Phương pháp HeapSort....................................................................................454.7.1. Định nghĩa Heap......................................................................................454.7.2. Ý tưởng giải thuật....................................................................................464.7.3. Ví dụ........................................................................................................464.7.4. Cài đặt......................................................................................................504.7.5. Đánh giá giải thuật...................................................................................51

4.8. Phương pháp ShellSort (sắp xếp với độ dài bước giảm dần)..........................514.8.1. Ý tưởng giải thuật....................................................................................514.8.2. Ví dụ........................................................................................................514.8.3. Cài đặt......................................................................................................544.8.4. Đánh giá giải thuật...................................................................................554.8.5. Nhận xét...................................................................................................55

4.9. Phương pháp sắp xếp dựa trên phân hoạch (QuickSort).................................554.9.1. Ý tưởng giải thuật....................................................................................554.9.2. Ví dụ........................................................................................................55

2

Page 3: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Mục Lục

4.9.3. Cài đặt......................................................................................................594.9.4. Đánh giá giải thuật...................................................................................604.9.5. Nhận xét...................................................................................................60

4.10. Sắp xếp theo phương pháp trộn trực tiếp (MergeSort)....................................604.10.1. Ý tưởng giải thuật....................................................................................604.10.2. Ví dụ........................................................................................................614.10.3. Cài đặt......................................................................................................624.10.4. Đánh giá giải thuật...................................................................................644.10.5. Nhận xét...................................................................................................64

5. Bài tập......................................................................................................................695.1. Lý thuyết..........................................................................................................695.2. Thực hành........................................................................................................70

CHƯƠNG III: CẤU TRÚC DỮ LIỆU......................................................................711. Giới thiệu.................................................................................................................712. Định nghĩa...............................................................................................................723. Các loại danh sách liên kết......................................................................................724. Danh sách liên kết đơn............................................................................................72

4.1. Khái niệm node................................................................................................724.1.1. Cấu tạo node............................................................................................724.1.2. Khai báo node..........................................................................................734.1.3. Tạo node..................................................................................................734.1.4. Xóa node..................................................................................................73

4.2. Khái niệm danh sách liên kết đơn...................................................................744.3. Một số phương thức thiết lập trong danh sách liên kết đơn............................74

4.3.1. Khởi tạo danh sách liên kết đơn..............................................................744.3.2. Tìm kiếm 1 phần tử trong danh sách liên kết đơn...................................764.3.3. Thêm 1 phần tử vào danh sách liên kết đơn............................................774.3.4. Bỏ 1 phần tử của danh sách liên kết đơn.................................................814.3.5. Xóa danh sách liên kết đơn......................................................................86

4.4. Các loại danh sách liên kết đơn đặc biệt.........................................................884.4.1. Stack........................................................................................................884.4.2. Hàng đợi(Queue).....................................................................................89

5. Danh sách liên kết đôi.............................................................................................915.1. Khái niệm node................................................................................................91

5.1.1. Cấu tạo node............................................................................................915.1.2. Khai báo node..........................................................................................915.1.3. Tạo node..................................................................................................915.1.4. Xóa node..................................................................................................92

5.2. Khái niệm danh sách liên kết đôi....................................................................925.3. Một số phương thức thiết lập trong danh sách liên kết đôi.............................93

5.3.1. Khởi tạo danh sách liên kết đôi...............................................................935.3.2. Thêm 1 phần tử vào danh sách liên kết đôi.............................................94

3

Page 4: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Mục Lục

5.3.3. Bỏ 1 phần tử ra khỏi danh sách liên kết đôi............................................965.3.4. Xóa danh sách liên kết đôi.......................................................................98

6. Danh sách liên kết vòng........................................................................................1006.1. Khái niệm danh sách liên kết vòng................................................................1006.2. Một số phương thức thiết lập trong danh sách liên kết vòng........................101

6.2.1. Khởi tạo danh sách liên kết vòng..........................................................1016.2.2. Thêm 1 phần tử vào danh sách liên kết vòng........................................1036.2.3. Bỏ 1 phần tử của danh sách liên kết vòng.............................................1046.2.4. Xóa danh sách liên kết vòng..................................................................106

7. Bài tập....................................................................................................................1087.1. Lý thuyết........................................................................................................1087.2. Thực hành......................................................................................................109

CHƯƠNG IV: CÂY...............................................................................................1111. Giới thiệu...............................................................................................................1112. Giới thiệu về cây...................................................................................................1123. Cấu trúc cây...........................................................................................................112

3.1. Định nghĩa cây...............................................................................................1123.2. Một số khái niệm cơ bản về cây....................................................................113

4. Cây nhị phân..........................................................................................................1144.1. Định nghĩa cây nhị phân................................................................................1144.2. Khai báo cây nhị phân...................................................................................1154.3. Khởi tạo cây rỗng..........................................................................................1154.4. Tạo node........................................................................................................1154.5. Xóa node........................................................................................................1164.6. Các phép duyệt trên cây nhị phân..................................................................116

4.6.1. NLR.......................................................................................................1174.6.2. LNR.......................................................................................................1184.6.3. LRN.......................................................................................................119

5. Cây nhị phân tìm kiếm..........................................................................................1195.1. Định nghĩa.....................................................................................................1195.2. Các thao tác trên cây nhị phân tìm kiếm.......................................................120

5.2.1. Tìm kiếm 1 phần tử...............................................................................1205.2.2. Thêm 1 phân tử vào cây........................................................................1225.2.3. Xóa 1 phần tử trong cây........................................................................1235.2.4. Xóa cây..................................................................................................129

5.3. Nhận xét.........................................................................................................1306. Cây nhị phân cân bằng ( AVL Tree).....................................................................131

6.1. Cây nhị phân cân bằng hoàn toàn..................................................................1316.1.1. Định nghĩa.............................................................................................1316.1.2. Nhận xét.................................................................................................131

6.2. Cây nhị phân cân bằng..................................................................................132

4

Page 5: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Mục Lục

6.2.1. Định nghĩa.............................................................................................1326.2.2. Các trường hợp mất cân bằng................................................................1326.2.3. Các thao tác cân bằng lại cây................................................................1346.2.4. Thêm và hủy 1 phần tử trên cây AVL...................................................1436.2.5. Tạo cây nhị phân cân bằng AVL...........................................................151

6.3. Nhận xét.........................................................................................................1547. Bài tập....................................................................................................................154

7.1. Lý thuyết........................................................................................................1547.2. Thực hành......................................................................................................155

PHỤ LỤC......................................................................................................................1571. Sinh dữ liệu vào / ra...............................................................................................157

1.1. Các phương pháp sinh dữ liệu vào / ra:.........................................................1571.2. Bài tập............................................................................................................157

2. Các bước để giải bài toán tin học..........................................................................1583. Đệ quy...................................................................................................................160

3.1. Khái niệm đệ quy...........................................................................................1603.2. Nhận xét.........................................................................................................1613.3. Bài tập............................................................................................................161

4. Khử đệ quy............................................................................................................1625. Khử đệ quy đuôi....................................................................................................1626. Hướng dẫn sử dụng phần mềm môn học cấu trúc dữ liệu.....................................163

6.1. Hướng dẫn cài đặt phần mềm........................................................................1636.2. Cách sử dụng.................................................................................................1636.3. Hình ảnh một số thuật toán............................................................................164

TÀI LIỆU THAM KHẢO.............................................................................................169

5

Page 6: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

CHƯƠNG I: TỔNG QUAN.

Mục tiêu.

Giới thiệu vai trò của việc tổ chức dữ liệu trong tin học, mối quan hệ giữa giải thuật và cấu trúc dữ liệu.

Trừu tượng hóa dữ liệu.

Tổng quan về đánh giá độ phức tạp giải thuật.

1. Giới thiệu.

Trong chương này, chúng ta xem xét các khái niệm về cấu trúc dữ liệu, kiểu dữ liệu. Thông thường ngôn ngữ lập trình luôn định nghĩa sẵn một số kiểu dữ liệu cơ bản. Các kiểu dữ liệu này thường có cấu trúc đơn giản. Để chúng ta thể hiện được các đối tượng muôn hình trong thế giới thực, chỉ dùng các cấu trúc dữ liệu này là không đủ. Do đó, ta cần phải xây dựng các kiểu dữ liệu mới phù hợp với đối tượng để biểu diễn. Vì vậy, việc thiết kế các cấu trúc dữ liệu tốt là một vế quan trọng trong mọi chương trình.

Bên cạnh đó, một chương trình tốt không chỉ có cấu trúc dữ liệu phù hợp mà còn có các thuật toán hiệu quả. Khi khảo sát các thuật toán, chúng ta quan tâm đến chi phí thực hiện thuật toán. Chi phí này bao gồm: chi phí về thời gian và tài nguyên để thực hiện thuật toán. Nếu như những đòi hỏi về tài nguyên có thể xác định thì việc ước lượng về thời gian thực hiện không đơn giản. Do đó, cách tiếp cận theo hướng xấp xỉ là hợp lý nhất, hướng này không phụ thuộc vào ngôn ngữ và môi trường cài đặt cũng như trình độ của lập trình viên. Do việc đánh giá chi phí thực hiện trung bình của thuật toán thường phức tạp nên người ta thường đánh giá chi phí thực hiện thuật toán trong trường hợp xấu nhất, việc xác định trường hợp xấu nhất rất quan trọng trong thực tế.

2. Vai trò cấu trúc dữ liệu trong tin học.

Thực hiện một đề án tin học là chuyển một 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 các đối tượng dữ liệu và các yêu cầu xử lý trên những đối tượng đó. Do đó, cần phải chú ý tới hai vấn đề sau:

Tổ chức biểu diễn các đối tượng thực tế:

Các thành phần dữ liệu thực tế đa dạng, phong phú và thường chứa đựng những quan hệ nào đó với nhau. Do đó, trong mô hình tin học của bài toán cần phải tổ chức và xây dựng các cấu trúc dữ liệu thích hợp nhất sao cho vừa có thể phản ánh chính xác các yêu cầu và các mối quan hệ, vừa có thể dễ dàng dùng máy tính để xử lý.

6

Page 7: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

Ví dụ: Để biểu diễn điểm số của sinh viên người ta dùng số thực thay vì dùng chuỗi kí tự để biểu diễn vì còn phải thực hiện thao tác tính điểm trung bình.

Xây dựng các thao tác xử lý dữ liệu:

Từ những yêu cầu và thao tác xử lý thực tế, chúng ta tìm ra các giải pháp, lựa chọn giải pháp tốt nhất. Sau đó, từ giải pháp này chúng ta xây dựng các giải thuật tương ứng để máy tính thi hành. Đôi khi 1 giải thuật giải quyết cho bài toán có thể là chưa tối ưu bởi vì nếu dùng tối ưu thì khó hiện thực và chi phí lớn.

Ví dụ: Một chương trình quản lý điểm thi của sinh viên cần lưu trữ các điểm số sinh viên. Mỗi sinh viên có 3 điểm số tương ứng với 3 môn học khác nhau nên dữ liệu có dạng bảng như sau:

Sinh viên Môn 1 Môn 2 Môn 3

SV1 7 5 9

SV2 3 8 5

SV3 8 4 6

Chỉ xét thao tác xử lý xuất điểm số các môn của từng sinh viên.

Giả sử có các phương án tổ chức lưu trữ sau:

Phương án 1: Sử dụng mảng một chiều.

Có tất cả 3(SV)*3(Môn) = 9 điểm số cần lưu trữ, do đó khai báo mảng a như sau:

int a[9]={7,5,9,3,8,5,8,4,6};

Và truy xuất điểm số môn j của sinh viên i – là phần tử tại (dòng i, cột j) trong bảng – phải sử dụng một công thức xác định chỉ số tương ứng trong mảng a:

Bảngđiểm(dòng i,cột j) a[(i*sốcột)+j].

Với phương án này, thao tác xử lý được cài đặt như sau:

void XuatDiem(int a[]){

int sv,mon;for(int i=0;i<9;i++){

sv=i/3; mon=i%3;printf(“Điểm môn %d của sv%d là:%d“,mon,sv,a[i]);

7

Page 8: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

}}

Phương án 2: Sử dụng mảng 2 chiều.

Có tất cả 3(SV)*3(Môn) = 9 điểm số cần lưu trữ, do đó khai báo mảng a như sau:

int a[3][3]={{7,5,9},{3,8,5},{8,4,6}};

Và truy xuất điểm số môn j của sinh viên i – là phần tử tại (dòng i, cột j) trong bảng – phải sử dụng một công thức xác định chỉ số tương ứng trong mảng a:

Bảngđiểm(dòng i,cột j) a[i,j].

Với phương án này, thao tác xử lý được cài đặt như sau:

void XuatDiem(int a[3][3]){

for(int i=0;i<3;i++)for(int j=0;j<3;j++)

printf(“Điểm môn %d của sv %d là:%d“,j,i,a[i][j]);}

Nhận xét: Có thể thấy phương án 2 cung cấp cấu trúc lưu trữ phù hợp với dữ liệu thực tế hơn phương án 1, và giải thuật xử lý trên cấu trúc dữ liệu của phương án 2 cũng đơn giản, tự nhiên hơn.

Tuy nhiên, khi giải quyết một bài toán trên máy tính, chúng ta thường chỉ chú trọng đến việc xây dựng giải thuật mà quên đi tầm quan trọng của việc tổ chức dữ liệu trong bài toán. Giải thuật phản ánh các phép xử lý, còn các đối tượng xử lý của giải thuật lại là dữ liệu, chính dữ liệu chứa đựng các thông tin cần thiết để thực hiện giải thuật.

Như vậy trong 1 đề án tin học, giải thuật và cấu trúc dữ liệu có mối quan hệ chặt chẽ với nhau.

3. Các tiêu chuẩn đánh giá cấu trúc dữ liệu.

Phản ánh đúng thực tế: đây là tiêu chuẩn quan trọng nhất, quyết định tính đúng đắn của bài toán.

Ví dụ: Tình huống chọn cấu trúc dữ liệu sai:

- Chọn một kiểu số nguyên int để lưu trữ tiền thưởng bán hàng (được tính theo công thức tiền thưởng bán hàng = trị giá hàng * 5%), điều này sẽ làm tròn mọi

8

Page 9: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

giá trị tiền thưởng gây thiệt hại cho nhân viên bán hàng. Trường hợp này phải sử dụng biến số thực phản ánh đúng kết quả của công thức tính thực tế.

- Chọn một biến số nguyên int để lưu trữ điểm trung bình của sinh viên trong một học kỳ. Kết quả là nếu có một sinh viên có điểm trung bình là 7,99 thì điểm trung bình trở thành 7. Trường hợp này phải sử dụng biến số thực phản ánh đúng kết quả điểm trung bình thực tế của sinh viên.

Phù hợp với các thao tác trên đó: tiêu chuẩn này giúp cho việc tăng tính hiệu quả của đề án.

Ví dụ: Chọn cấu trúc lưu trữ không phù hợp:

- Cần xây dựng điểm môn học của từng sinh viên nếu ta chọn cấu trúc lưu trữ kiểu mảng 1 chiều thì sẽ gây khó khăn khi xây dựng việc chèn, xoá điểm của sinh viên.

Tiết kiệm tài nguyên hệ thống.

Ví dụ: Chọn cấu trúc lưu trữ lãng phí:

- Sử dụng biến long (4 byte) để lưu trữ một giá trị cho biết tháng hiện hành. Biết rằng tháng chỉ có thể nhận các giá trị từ 112, nên sử dụng kiểu unsign (2 byte) là đủ.

4. Kiểu dữ liệu.

4.1. Định nghĩa kiểu dữ liệu.

Kiểu dữ liệu T được xác định bởi một bộ <V,O>, với:V: tập các giá trị hợp lệ mà một đối tượng kiểu T có thể lưu trữ.O: tập các thao tác xử lý có thể thi hành trên đối tượng kiểu T.

Ví dụ: Giả sử có kiểu dữ liệu số nguyên = <V,O> với

V={-32768…32767}.O={+,-,*,/,%}.

4.2. Các kiểu dữ liệu cơ bản.

Là các kiểu dữ liệu đơn giản không có cấu trúc. Thường được các ngôn ngữ lập trình cấp cao xây dựng sẵn như một thành phần của ngôn ngữ để giảm nhẹ công việc cho người lập trình.

Các kiểu dữ liệu định sẵn trong C gồm các kiểu sau:

9

Page 10: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

Tên kiểu Kích thước Miền giá trị Ghi chú

char 1 byte -128 đến 127Có thể dùng như số

nguyên 1 byte có dấu hoặc kiểu ký tự.

unsign char 1 byte 0 đến 255 Số nguyên 1 byte không dấu.

int 2 byte -32768 đến 32767unsign int 2 byte 0 đến 65335 Có thể viết: unsign.

long 4 byte -232 đến 231-1unsign long 4 byte 0 đến 232-1

float 4 byte 3.4E-38..3.4E38double 8 byte 1.7E-308..1.7E308

long double 10 byte 3.4E-4932..1.1E4932

4.3. Các kiểu dữ liệu có cấu trúc cơ bản.

4.3.1. Kiểu chuỗi ký tự.

Là kiểu dữ liệu đơn giản và thường được ngôn ngữ định nghĩa.

Ví dụ: char S[10]; //khai báo 1 chuỗi ký tự có 10 phần tử.

4.3.2. Kiểu mảng.

Là một tập hợp có thứ tự các giá trị có cùng cấu trúc được lưu trữ liên tiếp nhau trong bộ nhớ.

Ví dụ: int a[10]; // khai báo 1 mảng có 10 phần tử, mỗi phần tử có kiểu nguyên.

4.4. Các kiểu dữ liệu có cấu trúc.

Trong thực tế các kiểu dữ liệu cơ bản không đủ để phản ánh tự nhiên và đẩy đủ bản chất của sự vật thực tế, dẫn đến nhu cầu phải xây dựng kiểu dữ liệu mới dựa trên việc tổ chức, liên kết các thành phần dữ liệu có kiểu dữ liệu đã được định nghĩa. Những kiểu dữ liệu được xây dựng như thế gọi là kiểu dữ liệu có cấu trúc.

Ví dụ: Để mô tả 1 đối tượng sinh viên, cần quan tâm đến các thông tin sau:

-Mã sinh viên: chuỗi ký tự.-Tên sinh viên: chuỗi ký tự.-Ngày sinh: kiểu ngày tháng.-Nơi sinh: chuỗi ký tự.-Điểm thi: số nguyên.

Để thể hiện các thông tin về ngày tháng năm sinh cần phải xây dựng 1 cấu trúc:

typedef struct Date{

10

Page 11: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

char ngay[2];char thang[[2];char nam[10];

};

Ta xây dựng kiểu dữ liệu thể hiện thông tin mỗi sinh viên:

typedef struct Sinhvien{

char masv[20];char tensv[20];char noisinh[20];Date ngaysinh;int diemthi;

};

5. Khái niệm giải thuật.

5.1. Giải thuật là gì?

Giải thuật là một chương trình được thiết kế để giải quyết bài toán đặt ra.

Lưu ý giải thuật và thuật toán có ý nghĩa giống nhau.

5.2. Tính chất giải thuật.

Dữ liệu.

Ví dụ: Bài toán: Cho 1 mảng a có n phần tử kiểu nguyên. Hãy sắp xếp mảng a tăng dần.

Dữ liệu gồm: Dữ liệu vào mảng a chưa sắp thứ tự, có n phần tử.

Dữ liệu ra: mảng a đã có thứ tự.

Tính xác định.

Ví dụ: Với bài toán trên.

Tính xác định được thể hiện ở việc xác định được giải thuật nào áp dụng vào bài toán trên.

Tính dừng.

Ví dụ: Với bài toán trên.

11

Page 12: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

void SapXep(inta[],int n){

for(int i=0;i<n-1;i++)for(int j=i+1;j<n){

if(a[j]<a[i]) Swap(a[i],a[j]);}

}Thuật toán trên lặp vô tận; không cho ra kết quả. Do không tăng biến j.

Tính đúng đắn.

Ví dụ: Với bài toán trên.

void SapXep(int a[],int n){

for(int i=0;i<n-1;i++){

for(int j=i+2;j<n;j++){

if(a[j]<a[i]) Swap(a[i],a[j]);j=j+1;

}i=i+1;

}}

Bài toán này không đúng đắn thể hiện ở việc gắn j=i+2.

Tính khả thi.

Ví dụ: Với bài toán trên.

void SapXep(int a[];int n){

int min;for(int i=0;i<n-1;i++){

min=a[i];for(int j=i+1;j<n;j++)

if(min>a[j]) min=a[j];printf(“%d ”, min);

}}

Thuật toán trên không khả thi, tuy viết thuật toán có in ra kết quả sắp xếp tăng nhưng không trả về mảng a sắp xếp tăng.

12

Page 13: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

6. Tổng quan về đánh giá độ phức tạp giải thuật.

Hầu hết các bài toán đều có nhiều thuật toán khác nhau để giải quyết chúng. Như vậy, làm thế nào để chọn được thuật toán? Vậy một thuật toán được gọi là tốt khi nói đến tính hiệu quả của một thuật toán. Người ta thường quan tâm đến chi phí cần dùng để thực hiện nó. Chi phí này thể hiện qua việc sử dụng tài nguyên như bộ nhớ, thời gian sử dụng CPU,….

Ở đây khi nói đến chi phí sẽ hiểu là chi phí về thời gian.

Ta có thể đánh giá thuật toán bằng phương pháp thực nghiệm thông qua việc cài đặt thuật toán rồi chọn các bộ dữ liệu thử nghiệm. Thống kê các thông số nhận được khi chạy các dữ liệu này ta sẽ có một đánh giá về thuật toán.

Tuy nhiên, phương pháp thực nghiệm có một số nhược điểm sau khiến cho nó khó có khả năng áp dụng trên thực tế:

- Do phải cài đặt bằng một ngôn ngữ lập trình cụ thể nên thuật toán sẽ chịu sự hạn chế của ngôn ngữ lập trình này.

- Hiệu quả của thuật toán sẽ bị ảnh hưởng bởi trình độ của người cài đặt.

- Việc 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 là rất khó khăn và tốn nhiều chi phí.

- Các số liệu thu nhận được phụ thuộc nhiều vào phần cứng mà thuật toán được thử nghiệm trên đó. Ðiều này khiến cho việc so sánh các thuật toán khó khăn nếu chúng được thử nghiệm ở những nơi khác nhau.

Vì những lý do trên, người ta đã tìm kiếm những phương pháp đánh giá thuật toán hình thức hơn, ít phụ thuộc môi trường cũng như phần cứng hơn. Một phương pháp như vậy là phương pháp đánh giá thuật toán theo hướng xấp xỉ tiệm cận qua các khái niệm toán học.

13

Page 14: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

6.1. Khái niệm “O”.

Cho f(n) và g(n) ta nói:

khi và chỉ khi , n a với c và a là hằng số, và f(n), g(n) là các hàm trên miền số tự nhiên.

Biểu đồ thể hiện 2 hàm f và hàm g.

Chú ý: “O” có nghĩa là Big-O notation.

Ví dụ:

1,000,001<=c*1,000,000 ,với c R do đó ta chọn được 1 giá trị cho c=2 sao cho biểu thức trên đúng.

3n2<=c*n2,với c R do đó ta chọn được 1 giá trị cho c=4 sao cho biểu thức trên đúng.

7n+5<=c*n ,với c R do đó ta chọn được 1 giá trị cho c=8 sao cho biểu thức trên đúng với n là những giá trị đủ lớn.

6.2. Quy tắc xác định O(?).

Xét thành phần có bậc cao nhất của f với f là đa thức tuyến tính.

Ví dụ:

(4n2+8n-4) O(n2).

14

c*g(n)f(n)

a

Running Time

0 n

t

Page 15: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

(4n3log(n)+4n3–1) O(n3log(n)).

6.3. Ví dụ về cách đánh giá thuật toán.

Mỗi lần i lặp:

Số phép so sánh trong là 1.

Số phép gán trong là 1.

Do i = nên số phép so sánh của hàm Temp là:

và số phép gán của hàm Temp là: .

Vậy số lần gán và so sánh của thuật toán Temp là:

.

Vậy độ phức tạp của thuật toán là: O(n).

6.4. Sự phân lớp của độ phức tạp.

1. Hằng số: Hầu hết các chỉ thị của các chương trình đều được thực hiện một lần hay nhiều nhất chỉ một vài lần. Nếu tất cả các chỉ thị của cùng một chương trình có tính chất này thì chúng ta sẽ nói rằng thời gian chạy của nó là hằng số.

2. log(n): Khi thời gian chạy của chương trình là logarit tức là thời gian chạy chương trình tiến chậm khi N lớn dần. Thời gian chạy thuộc loại này xuất hiện trong các chương trình mà giải một bài toán lớn bằng cách chuyển nó thành một bài toán nhỏ hơn.

Ví dụ: Khi n=10 thì là 1; khi n=100 thì là 2.

Bất cứ khi nào n được nhân đôi, tăng lên thêm một hằng số.

15

Cho 1 mảng a gồm n phần tử.void Temp(int a[],int n,int x){

for(int i=0;i<n;i++)

}

if(a[i]==x)

a[i]=1;else a[i]=0;

Page 16: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

3. n: Khi thời gian chạy của một chương trình là tuyến tính.

Ví dụ: Khi n là một triệu thì thời gian chạy cũng cỡ 1 triệu. Khi n được nhân gấp đôi thì thời gian chạy cũng được nhân gấp đôi.

Ðây là tình huống tối ưu cho một thuật toán mà phải xử lý n dữ liệu nhập.

4. nlog(n): Ðây là thời gian chạy tăng dần lên cho các thuật toán mà giải một bài toán bằng cách tách nó thành các bài toán con nhỏ hơn, kế đến giải quyết chúng một cách độc lập và sau đó tổ hợp các lời giải. Chúng ta nói rằng thời gian chạy của thuật toán như thế là "nlog(n)".

Ví dụ: Khi n là một triệu, có lẽ khoảng hai mươi triệu. Khi n được nhân gấp đôi, thời gian chạy bị nhân lên nhiều hơn gấp đôi.

5. n2: Khi thời gian chạy của một thuật toán là bậc hai. Thời gian bình phương thường tăng dần lên trong các thuật toán mà xử lý tất cả các cặp phần tử dữ liệu (có thể là hai vòng lặp lồng nhau).

Ví dụ: Khi n là một ngàn thì thời gian chạy là một triệu. Khi n được nhân đôi thì thời gian chạy tăng lên gấp bốn lần.

6. 2n: Một số ít thuật toán có thời gian chạy lũy thừa, nhưng lại thích hợp trong một số trường hợp thực tế, mặc dù các thuật toán như thế là "không tưởng" để giải các bài toán.

Ví dụ: Khi n là hai mươi thì thời gian chạy là một triệu.

Khi n gấp đôi thì thời gian chạy được nâng lên lũy thừa hai.

7. Bài tập.

7.1. Lý thuyết.

1. Tìm thêm một số ví dụ minh hoạ mối quan hệ giữa cấu trúc dữ liệu và giải thuật.

2. Cho biết một số kiểu dữ liệu được định nghĩa sẵn trong một ngôn ngữ lập trình các bạn thường sử dụng. Cho biết một số kiểu dữ liệu cơ bản này có đủ để đáp ứng mọi yêu cầu về tổ chức dữ liệu không ?

3. Một ngôn ngữ lập trình có nên cho phép người sử dụng tự định nghĩa thêm các kiểu dữ liệu có cấu trúc? Giải thích và cho ví dụ.

16

Page 17: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 1: Tổng quan

4. Cấu trúc dữ liệu và cấu trúc lưu trữ khác nhau những điểm nào? Một cấu trúc dữ liệu có thể có nhiều cấu trúc lưu trữ được không? Ngược lại, một cấu trúc lưu trữ có thể tương ứng với nhiều cấu trúc dữ liệu được không? Cho ví dụ minh hoạ.

5. Các tiêu chuẩn để đánh giá một giải thuật? Và O( ) là gì?

6. Độ phức tạp có phải là tiêu chuẩn để đánh giá một thuật toán nhanh hay chậm? Cái gì là thước đo đánh giá độ phức tạp của bài toán.

7.2. Thực hành.

7. Minh họa kiểu cấu trúc của sinh viên mượn sách thư viện. Sau đó cho 1 mảng các sinh viên, rồi sắp xếp tăng dần các sinh viên theo điểm trung bình.

8. Minh họa con trỏ có kiểu cấu trúc sinh viên mượn sách thư viện. Sau đó tạo danh sách các sinh viên, rồi sắp xếp tăng dần theo điểm trung bình.

10. Nhập vào 1 mảng a có n phần tử. Viết chương trình con sắp xếp mảng a tăng.theo 2 cách. Tính số lần so sánh và số lần gán của 2 thuật toán trên. So sánh thuật toán nào chạy cho kết quả nhanh.

17

Page 18: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

CHƯƠNG II: CÁC GIẢI THUẬT TÌM KIẾM VÀ SẮP XẾP.

Mục tiêu.

Giới thiệu một số thuật toán tìm kiếm và sắp xếp.

Đánh giá độ phức tạp của các giải thuật tìm kiếm và sắp xếp.

1. Giới thiệu.

Trong chương này, chúng ta xem xét các thuật toán tìm kiếm và sắp xếp thông dụng. Cấu trúc dữ liệu chính để minh hoạ các thao tác này chủ yếu là mảng một chiều. Đây cũng là một trong những cấu trúc dữ liệu thông dụng nhất.

Khi khảo sát thuật toán tìm kiếm, chúng ta sẽ làm quen với hai thuật toán. Thuật toán thứ nhất là thuật toán tìm kiếm tuần tự thuật toán này có độ phức tạp tuyến tính (O(n)). Thuật toán thứ hai là thuật toán tìm kiếm nhị phân thuật toán này có độ phức tạp (O(log2(n))). Tuy thuật toán tìm kiếm nhị phân có ưu điểm tìm kiếm nhanh hơn thuật toán tìm kiếm tuyến tính nhưng thuật toán tìm kiếm nhị phân phải sắp xếp trước khi tìm kiếm. Vì thế cần phải dựa vào điều kiện thực tế để quyết định chọn thuật toán nào.

Phần tiếp theo của chương trình bày các thuật toán sắp xếp thông dụng từ đơn giản đến phức tạp (tức là từ chi phí cao đến chi phí thấp).

Các thuật toán đơn giản đó là các thuật toán chọn trực tiếp, chèn trực tiếp, nổi bọt, đổi chỗ trực tiếp; các thuật toán này đều có chi phí về thời gian thực hiện vào khoảng O(n2). Các thuật toán shellSort, HeapSort đều là những thuật toán cải tiến từ những thuật toán đơn giản trên, chúng có chi phí về thời gian thực hiện nhỏ hơn O(n2). Còn lại thuật toán mergeSort và quickSort là những thuật toán thực hiện theo chiến lược chia để trị; tuy cài đặt chúng phức tạp nhưng chi phí thực hiện của chúng lại thấp khoảng O(nlog2(n)).

2. Nhu cầu tìm kiếm và sắp xếp dữ liệu trong 1 hệ thống thông tin.

Trong hầu hết các hệ lưu trữ, quản lý dữ liệu, thao tác tìm kiếm thường được thực hiện nhiều để khai thác thông tin.

Ví dụ: tra cứu từ điển, tìm sách trong thư viện….

Do các hệ thống thông tin thường phải lưu trữ một khối lượng dự liệu đáng kể, nên việc xây dựng các giải thuật cho phép tìm kiếm nhanh sẽ có ý nghĩa rất lớn. Cho nên nếu dữ liệu trong hệ thống được tổ chức theo một trật tự nào đó, thì việc tìm kiếm sẽ tiến hành nhanh chóng và hiệu quả hơn.

18

Page 19: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Ví dụ: Sách trong thư viện được sắp xếp theo từng chủ đề.

Hiện nay có nhiều giải thuật tìm kiếm và sắp xếp được xây dựng, mức độ hiệu quả của từng giải thuật còn phụ thuộc vào tính chất của cấu trúc dữ liệu cụ thể mà nó tác động đến.

3. Các giải thuật tìm kiếm.

Ví dụ: Cho 1 bài toán như sau:

Cho tập dữ liệu được lưu trữ dạng mảng như sau: int a[n];

và khóa cần tìm là: int x;

3.1. Tìm kiếm tuyến tính.

3.1.1. Ý tưởng giải thuật.

Thuật toán tiến hành so sánh x lần lượt với các phần tử thứ nhất, thứ hai,…của mảng a cho đến khi gặp phần tử có khóa cần tìm, hoặc đã tìm hết mảng mà không thấy x.

3.1.2. Lưu đồ.

3.1.3. Ví dụ.

Cho dãy số a như sau:

19

T

Mảng a[],n,i=0

i<n

i=i+1

Begin

EndF

T

F

a[i]==x

Page 20: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Lần 5: Dừng.

3.1.4. Cài đặt.

int LinearSearch(int a[],int n,int x){

for(int i=0;i<n;i++)if(a[i]==x) return i;

return –1;}

3.1.5. Đánh giá giải thuật.

Xét trường hợp xấu nhất:

20

10 14 52 73091

Lần 1: i=0.

x=14

10 14 52 73091

Lần 2: i=1.

x=14

10 14 52 73091

Lần 3: i=2.

x=14

10 14 52 73091

Lần 4: i=3. x=1

4

10 14 52 73091

Page 21: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Số lần so sánh: (n+1)+n=2n+1.

Số lần gán: (n+1).

f(n)=c(2n+1)+d(n+1)=(2c+d)n+(c+d).

Vậy thuật toán có độ phức tạp O(n).

3.1.6. 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ự tăng dần hay giảm dần của các phần tử mảng.

3.2. Tìm kiếm nhị phân.

3.2.1. Ý tưởng giải thuật.

Giả sử dãy số đã có thứ tự tăng.

Tại mỗi bước tiến hành so sánh x với phần tử nằm vị trí giữa của dãy tìm kiếm hiện hành, dựa vào kết quả so sánh này để quyết định giới hạn dãy tìm ở bước kế tiếp là nửa trên hay nửa duới của dãy tìm kiếm hiện hành.

3.2.2. Lưu đồ.

21

T

Mảng a[],left=0,right=n-1,mid

x==a[mid]

Begin

T

F

F

mid=(left+right)/2

left<=right

T

F End

a[mid]<x

left=mid+1

right=mid–1

Page 22: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

3.2.3. Ví dụ.

Cho dãy số a có thứ tự như sau:

Lần 4: Dừng.

3.2.4. Cài đặt.

int BinarySearch(int a[],int n,int x){

int left=0,right=n-1;int mid;while(left<=right){

mid=(left+right)/2;if(x==a[mid]) return mid;else

if(x<a[mid]) right=mid–1;else left=mid+1;

}return –1;

}

3.2.5. Đánh giá giải thuật.

Xét trường hợp xấu nhất:

Số lần so sánh: .

22

1 7 92 3014105

Lần 1: left=0,right=7,mid=3.

x=14

1 7 92 3014105

Lần 2: left=4,right=7,mid=5.

x=14

1 7 92 3014105

Lần 3: left=6,right=7,mid=6.

x=14

1 7 92 3014105

Page 23: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Số lần gán: .

.Vậy thuật toán có độ phức tạp O( ).

3.2.6. Nhận xét.

Giải thuật tìm nhị phân tiết kiệm thời gian hơn rất nhiều so với giải thuật tìm tuyến tính.

Tuy nhiên khi muốn áp dụng giải thuật tìm nhị phân cần phải xét đến thời gian sắp xếp dãy số để thỏa mãn điều kiện dãy số có thứ tự. Thời gian này không nhỏ do đó ta cần phải cân nhắc kĩ nhu cầu thực tế để chọn 1 trong 2 giải thuật tìm kiếm trên sao cho có lợi nhất.

4. Các giải thuật sắp xếp.

4.1. Định nghĩa sắp xếp.

Sắp xếp là quá trình xử lý một danh sách các phần tử để đặt chúng theo một thứ tự thỏa mãn một tiêu chuẩn nào đó dựa trên nội dung thông tin lưu trữ tại mỗi phần tử.

4.2. Các phương pháp sắp xếp.

Giải thuật chọn trực tiếp (SelectionSort).

Giải thuật chèn trực tiếp (InsertionSort).

Giải thuật đổi chỗ trực tiếp (InterchangeSort).

Giải thuật nổi bọt (BubbleSort).

Giải thuật HeapSort.

Giải thuật ShellSort (sắp xếp với độ dài bước giảm dần).

Giải thuật sắp xếp dựa trên phân hoạch (QuickSort).

Giải thuật sắp xếp theo phương pháp trộn trực tiếp (MergeSort).

4.3. Phương pháp đổi chỗ trực tiếp (InterchangeSort).

4.3.1. Ý tưởng giải thuật.

Khái niệm nghịch thế:

Xét 1 mảng các số a1, a2…, an.Nếu có i < j và ai > aj thì ta gọi đó là 1 nghịch thế.

23

Page 24: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Ví dụ: Cho dãy số a như sau: 14 5 7 8 3.

Vậy dãy trên trên có các cặp nghịch thế sau: (14, 5); (7, 3); (8, 3)….

Ta có ý tưởng thuật toán sau:

Xuất phát từ đầu dãy, tìm tất cả nghịch thế chứa phần tử này, đổi chỗ phần tử này với các phần tử trong cặp nghịch thế. Lặp lại xử lý trên với các phần tử tiếp theo trong dãy.

4.3.2. Ví dụ.

Cho dãy số a:

24

10 14 52 73091

10 14 52 73091

i=0 j=1

2 14 510 73091

i=0 j=2

1 14 510 73092

i=1 j=2

1 14 52 730910

i=2 j=4

1 14 102 73095

i=3 j=4

1 10 142 73095

i=3 j=5

Page 25: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Dừng.

Vậy dãy đã được sắp xếp.

4.3.3. Cài đặt.

void Interchangesort(int a[],int n){

for(int i=0;i<n-1;i++)for(int j=i+1;j<n;j++)

if(a[i]>a[j]) Swap(a[i],a[j]);}

25

1 9 142 730105

i=3 j=7

1 7 142 930105

i=4 j=5

1 7 102 930145

i=4 j=7

1 7 92 1030145

i=5 j=7

1 7 92 1430105

i=6 j=71 7 92 3014105

Page 26: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

4.3.4. Đánh giá giải thuật.

Ta có bảng đánh giá thuật toán sau:

Trường hợp Số lần so sánh Số lần gán

Tốt nhất 0

Xấu nhất

Vậy độ phức tạp của thuật toán là O(n2).

4.4. Phương pháp chèn trực tiếp (InsertionSort).

4.4.1. Ý tưởng giải thuật.

Giả sử có 1 dãy a1, a2,…,an trong đó (i – 1) phần tử đầu tiên a1, a2,…, ai-1 đã có thứ tự. Ý tưởng của giải thuật là tìm cách chèn phần tử ai vào vị trí thích hợp của đoạn đã sắp xếp để có dãy mới a1, a2,…, ai đã có thứ tự. Cứ như thế các phần tử tiếp theo cho đến hết dãy. Vậy ta được 1 dãy sắp xếp.

4.4.2. Ví dụ.

Cho dãy số a:

26

10 14 52 73091

10 14 52 73091

i=1

2 14 510 73091

i=2

Page 27: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Dừng.

Vậy dãy đã được sắp xếp.

4.4.3. Cài đặt.

void InsertionSort(int a[],int n){

for(int i=1;i<n;i++){

int x=a[i];for(int j=i-1;j>=0;j--){

if(a[j]>x) a[j+1]=a[j];else break;

}

27

1 14 52 730910

i=3

1 14 52 730910

i=4

1 10 142 73095

i=5

1 9 102 730145

i=6

1 9 102 730145

i=71 7 92 3014105

Page 28: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

a[j+1]=x;}

}

4.4.4. Đánh giá giải thuật.

Ta có bảng đánh giá thuật toán sau:

Trường hợp Số lần so sánh Số lần gán

Tốt nhất

Xấu nhất

Vậy độ phức tạp của thuật toán là O(n2).

4.4.5. Nhận xét.

Ưu điểm: Số lần gán trong giải thuật chèn trực tiếp giảm 3 lần so với giải thuật đổi chỗ trực tiếp.

Nhược điểm: Tìm vị trí chèn với độ phức tạp là O(n).

Khi tìm vị trí thích hợp để chèn a[i] vào đoạn a[0] đến a[i – 1], mà đoạn này đã

được sắp xếp, nên có thể sử dụng giải thuật tìm kiếm nhị phân để thực hiện việc tìm kiếm vị trí cần chèn. Ta có giải thuật sau:

Giải thuật chèn nhị phân (Binary InsertionSort)

void BinsertionSort(int a[],int n){

int l,r,m;int x;for(int i=1;i<n;i++){

x=a[i];l=0;r=i–1;while(l<=r) //tìm vị trí cần chèn theo kiểu nhị phân

{m=(l+r)/2;if(x<a[m]) r=m–1;else l=m+1;

}for(int j=i–1;j>=l;j--) //Dời các phần tử lớn hơn phần tử cần chèn qua

phải 1 phần tử.

a[j+1]=a[j];a[l]=x;

28

Page 29: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

}}

4.5. Phương pháp chọn trực tiếp (SelectionSort).

4.5.1. Ý tưởng giải thuật.

Chọn phần tử nhỏ nhất trong n phần tử ban đầu, đưa phần tử này về vị trí thứ 1 của dãy hiện hành; sau đó không quan tâm đến nó nữa, xem dãy hiện hành chỉ còn (n – 1) phần tử, bắt đầu từ vị trí thứ 2; lặp lại quá trình đó trên dãy hiện hành…đến khi dãy hiện hành chỉ còn 1 phần tử thì dừng.

4.5.2. Ví dụ.

Cho dãy số a:

29

10 14 52 73091

10 14 52 73091

i=0

min

1 14 52 730910

i=1

min

1 14 52 730910

i=2

min

1 14 102 73095

i=3

min

1 7 102 143095

i=4

min

Page 30: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Dừng.

Vậy dãy đã được sắp xếp.

4.5.3. Cài đặt.

void SelectionSort(int a[],int n){

for(int i=0;i<n-1;i++){

int min=i;for(int j=i+1;j<=n-1;j++)

if(a[j]<a[min])min=j;Swap(a[min],a[i]);

}}

4.5.4. Đánh giá giải thuật.

Ta có bảng đánh giá thuật toán sau:

Trường hợp Số lần so sánh Số lần gán

Tốt nhất

Xấu nhất

Vậy độ phức tạp của thuật toán là O(n2).

4.6. Phương pháp nổi bọt (BubbleSort).

4.6.1. Ý tưởng giải thuật.

Cách nói nôm na:

30

1 7 92 1430105

i=5

min

1 7 92 1430105

i=6

min

1 7 92 3014105

Page 31: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Đưa những phần tử nhỏ lên đầu mảng những phần tử lớn về phía sau mảng.

Ý tưởng thực hiện:

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 trong cặp phần tử đó về vị trí đứng đầu dãy hiện hành, sau đó không xét tới nó ở bước tiếp theo, do vậy ở lần lặp thứ i có vị trí đầu dãy là i.

4.6.2. Ví dụ.

Cho dãy số a:

31

10 14 52 73091

10 14 52 73091

i=0 j=7

10 14 52 30791

i=0 j=6

10 14 52 30971

i=0 j=4

10 5 142 30971

i=0 j=2

10 5 141 30972

i=0 j=1

1 5 1410 30972

i=1 j=51 5 710 309142

i=1 j=2

Page 32: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Dừng.

Vậy dãy đã được sắp xếp.

4.6.3. Cài đặt.

void BubleSort(int a[],int n){

32

1 5 72 3091410

i=2 j=61 5 72 3014910

i=2 j=3

1 10 72 301495

i=3 j=4

1 7 102 301495

i=4 j=51 7 92 3014105

i=51 7 92 3014105

i=61 7 92 3014105

Page 33: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

int i,j;for(i=0;i<n-1;i++)for(j=n-1;j>i;j--) //tìm phần tử min kể từ vị trí đưa về vị trí i

if(a[j]<a[j–1])Swap(a[j],a[j-1]);

}

4.6.4. Đánh giá giải thuật.

Ta có bảng đánh giá thuật toán sau:

Trường hợp Số lần so sánh Số lần gán

Tốt nhất 0

Xấu nhất

Vậy độ phức tạp của thuật toán là O(n2).

4.6.5. Nhận xét.

BubleSort có khuyết điểm là không nhận diện được tình trạng dãy đã có thứ tự từng đoạn. Để khắc phục được nhược điểm của BubleSort ta có thuật toán cải tiến sau:

Thuật toán ShakerSort:

void ShakerSort(int a[],int n){

int l,r,k;l=0;r=n–1;k=n–1;while(l<r){

for(int j=r;j>l;j--) //tìm phần tử min trong đoạn đưa về vị trí l

{if(a[j–1]>a[j]){

Swap(a[j],a[j–1]);k=j;

}}l=k;for(int i=l;i<r;i++) //tìm phần tử max trong đoạn đưa về vị trí r

{if(a[i]>a[i+1]){

Swap(a[i],a[i+1]);k=i;

33

Page 34: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

}}r=k;

}}

4.7. Phương pháp HeapSort.

4.7.1. Định nghĩa Heap.

Xét trường hợp dãy sắp xếp tăng dần, khi đó Heap được định nghĩa là 1 dãy các phần tử a1, a2,…, an thỏa quan hệ sau:

ai >= a2i và ai >= a2i+1. với mọi i [1…n].

Tính chất của heap:

- Nếu 1 dãy là 1 heap thì khi cắt bỏ 1 số phần tử ở cuối dãy của heap, dãy con vẫn là 1 heap.

- Nếu 1 dãy là 1 heap thì phần tử đứng đầu luôn là phần tử lớn nhất trong dãy.

4.7.2. Ý tưởng giải thuật.

Giải thuật HeapSort trải qua 2 giai đoạn:

Giai đoạn 1: Hiệu chỉnh dãy số ban đầu thành heap.

Giai đoạn 2: Sắp xếp dãy số dựa trên heap.

4.7.3. Ví dụ.

Cho dãy số a sau:

Giai đoạn 1:

34

10 14 52 73091

10 14 52 73091

l=3

10 30 52 71491

l=2

Page 35: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Giai đoạn 2:

35

10 30 52 71419

l=1

10 2 530 71419

l=1

Hiệu chỉnh lan truyền

10 14 530 7219

l=0

30 14 510 7219

l=0

Hiệu chỉnh lan truyền

7 10 514 30219

r=6l=0

14 10 57 30219

r=6l=0

Hiệu chỉnh lan truyền

14 7 510 30219

r=6l=0

30 10 514 7219

r=7l=0

Page 36: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

36

2 7 510 301419

r=5l=0

10 7 52 301419

r=5l=0

Hiệu chỉnh lan truyền

10 7 29 301415

r=5l=0

1 7 29 3014105

r=4l=0

9 1 27 3014105

r=4l=0

2 1 97 3014105

r=3l=0Hiệu chỉnh lan

truyền

7 1 92 3014105

r=3l=0

10 7 59 301412

r=5l=0

Hiệu chỉnh lan truyền

Hiệu chỉnh lan truyền

9 7 21 3014105

r=4l=0

Page 37: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Dừng.

Vậy dãy đã được sắp xếp.

4.7.4. Cài đặt.

void Shift(int a[],int l,int r){

int x,i,j;i=l;j=2*i;x=a[i];while(j<=r) //thực hiện việc hiệu chỉnh giữa a[i] với a[j] và a[j+1]

{if((j<r)&&(a[j]<a[j+1])) j=j+1;if(a[j]<=x) break;a[i]=a[j];a[j]=x;

37

7 1 95 3014102

r=3l=0

1 7 95 3014102

r=2l=0

5 7 91 3014102

r=2l=02 7 91 3014105

r=1l=01 7 92 3014105

Page 38: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

i=j;j=2*i;

}}

void CreateHead(int a[],int n)

{for(int l=n/2;l>=0;l=l–1;)

Shift(a,l,n-1);}

void HeadSort(int a[],int n)

{int r;CreateHead(a,n);Swap(a[0],a[n-1]);for(r=n-2;r>0; r=r–1){

Shift(a,0,r);Swap(a[0],a[r]);

}}

4.7.5. Đánh giá giải thuật.

Việc đánh giá giải thuật HeapSort rất phức tạp, nhưng đã chứng minh được trong trường hợp xấu nhất độ phức tạp O(nlog2(n)).

4.8. Phương pháp ShellSort (sắp xếp với độ dài bước giảm dần).

4.8.1. Ý tưởng giải thuật.

Là một phương pháp cải tiến của phương pháp chèn trực tiếp. Tức là phân chia dãy ban đầu ra thành những dãy con, mỗi dãy con gồm các phần tử ở cách nhau h vị trí. Các dãy con này được sắp xếp theo phương pháp chèn trực tiếp. Sau đó giảm h theo một tiêu chuẩn nào đó cho tới khi h = 1 thì dừng.

4.8.2. Ví dụ.

Cho dãy số a sau:

Giả sử chọn các khoảng cách h là: 5, 3, 1.

38

10 14 52 73091

Page 39: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

h=5:

h=3:

39

9 14 52 730101

i=3

9 14 52 730101

i=4

9 14 52 730101

i=59 14 52 730101

i=6

9 14 52 730101

i=7

9 14 52 730101

i=6

9 14 52 730101

i=7

10 14 52 73091

i=5

Page 40: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

h=1:

Dừng.

Vậy dãy đã được sắp xếp.

40

9 14 52 730101

i=1

2 14 59 730101

i=21 14 52 730109

i=3

1 14 52 730109

i=4

1 9 102 730145

i=6

1 9 102 730145

i=71 7 92 3014105

1 9 142 730105

i=5

Page 41: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

4.8.3. Cài đặt.

void ShellSort(int a[],int n,int h){

int x;for(;h>0;h=h-2){

for(int i=h;i<n;i++){

x=a[i];int j=i–h;while(j>=0){

if(x<a[j]) a[j+h]=a[j];else break;j=j–h;

}a[j+h]=x;

}}

}

4.8.4. Đánh giá giải thuật.

Việc đánh giá giải thuật ShellSort rất phức tạp. Tuy nhiên hiệu quả của thuật toán còn phụ thuộc vào dãy các độ dài được chọn. Trong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp n1,2

(<<n2).

4.8.5. Nhận xét.

Yếu tố quyết định tính hiệu quả của thuật toán là cách chọn khoảng cách h. Tuy nhiên, đến nay vẫn chưa có tiêu chuẩn rõ ràng trong việc lựa chọn dãy giá trị khoảng cách tốt nhất.

4.9. Phương pháp sắp xếp dựa trên phân hoạch (QuickSort).

4.9.1. Ý tưởng giải thuật.

Giải thuật QuickSort dựa trên việc phân hoạch dãy ban đầu thành 2 phần:

Dãy con 1: gồm các phần tử a1…ai có giá trị không lớn hơn x.

Dãy con 2: gồm các phần tử ai+1…an giá trị không nhỏ hơn x.

Lặp lại quá trình trên với các dãy con.

4.9.2. Ví dụ.

41

Page 42: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Cho dãy số a sau:

Phân hoạch đoạn l=0,r=7,mid=3,x=14.

Dừng lặp.

Phân hoạch đoạn l=0,r=j=6,mid=3,x=7. (chưa làm phân hoạch đoạn l=i=6,r=7).

Dừng lặp.

Phân hoạch đoạn l=0,r=j=3,mid=1,x=2.(chưa làm phân hoạch đoạn l=i=4,r=6).

42

10 14 52 73091

r=7

10 14 52 73091

l=0

i=3 j=7

r=7

10 7 52 143091

l=0

i=4 j=6

10 7 52 143091

r=6l=0

i=0 j=4

5 7 102 143091

r=6l=0

i=3 j=3

5 7 102 143091

r=6l=0

i=4j=2

5 7 102 143091

r=2l=0

j=2i=0

Page 43: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Dừng lặp.

Gọi lại phân hoạch đoạn l=i=4,r=6,mid=5,x=9.

Dừng lặp.

Phân hoạch đoạn l=i=5,r=6,mid=5,x=10.

43

1 7 102 143095

r=2l=0

j=1i=1

1 7 102 143095

r=2l=0

i=2j=0

1 7 102 143095

r=6l=4

j=5i=4

1 7 92 1430105

r=6l=4

i=5j=4

1 7 92 1430105

r=6l=5

j=5i=5

1 7 92 1430105

r=6l=5

i=6j=4

Page 44: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Dừng lặp.

Gọi lại phân hoạch đoạn l=i=4,r=7,mid=5,x=10.

Dừng lặp.

Phân hoạch đoạn l=i=6,r=7,mid=6,x=30.

Dừng lặp.

Dừng.

Vậy dãy đã được sắp xếp.

4.9.3. Cài đặt.

void QuickSort(int a[],int l,int r){

44

1 7 92 1430105

r=7l=4

j=5i=5

1 7 92 1430105

r=7l=4

i=6j=4

1 7 92 1430105

r=7l=6

j=7i=6

1 7 92 3014105

r=7l=6

i=7j=6

1 7 92 3014105

Page 45: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

int i,j,mid,x,flag;mid=(l+r)/2;x=a[mid];i=l;j=r;do{

flag=1;while(a[i]<x) i++;while(a[j]>x) j--;if((i>=mid)||(j<=mid))

flag=0;if(i<=j){

Swap(a[i],a[j]);i++; j--;

}}while((i<=j)&&(flag!=0));if(l<j) QuickSort(a,l,j);if(i<r) QuickSort(a,i,r);

}

4.9.4. Đánh giá giải thuật.

Ta có bảng đánh giá thuật toán sau:

Trường hợp Độ phức tạpTốt nhất O(n*log2(n))

Trung bình O(n*log2(n))Xấu nhất O(n2)

4.9.5. Nhận xét.

Giá trị mốc x được chọn sẽ có tác động đến hiệu quả thực hiện thuật toán vì nó quyết định đến số lần phân hoạch. Số lần phân hoạch sẽ ít nhất nếu ta chọn được x là phần tử trung bình của dãy. Tuy nhiên do tìm phần tử trung bình có chi phí quá cao nên trong thực tế người ta chọn phần tử giữa dãy làm mốc.

4.10. Sắp xếp theo phương pháp trộn trực tiếp (MergeSort).

4.10.1. Ý tưởng giải thuật.

Phân hoạch dãy ban đầu thành các dãy con. Sau khi phân hoạch xong, dãy ban đầu sẽ được tách thành 2 dãy phụ theo nguyên tắc phân phối đều luân phiên. Rồi trộn từng cặp dãy con của 2 dãy phụ thành 1 dãy với nguyên tắc thứ tự tăng dần. Lặp lại qui trình trên sau 1 số bước, ta sẽ nhận được 1 dãy chỉ gồm 1 dãy con không giảm.

4.10.2. Ví dụ.

Cho dãy số a sau:

45

Page 46: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

k=1:

k=2:

k=4:

46

10 14 52 73091

a= 10 14 52 73091

10 301 5

2 714 9

2 14 510 30791

b=

c=

a=

a= 2 14 510 30791

2 910 5

1 3014 7

1 14 52 309710

b=

c=

a=

1 7 92 3014105

a= 1 14 52 309710

1 142 10

5 307 9

b=

c=

a=

Page 47: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

k=8. Dừng.

Vậy dãy đã được sắp xếp.

4.10.3. Cài đặt.

void MergeSort(int a[],int n){

int p,pb,pc;int k=1;int b[MAX],c[MAX];do{

p=pb=pc=0;while(p<n){

for(int i=0;i<k;i++)if(p<n){

b[pb]=a[p]; pb++; p++;}for(int i=0;i<k;i++)if(p<n){

c[pc]=a[p]; pc++; p++;}

}Merge(a,b,pb,c,pc,k);k*=2;}while(k<n);

}

void Merge(int a[],int b[],int nb,int c[],int nc,int k)

{int p,pb,pc,ib,ic,kb,kc;p=0;pb=0;pc=0;ib=0;ic=0;kb=min(k,nb);kc=min(k,nc);while((0<nb)&&(0<nc)){

if(b[pb+ib]<=c[pc+ic]){

a[p]=b[pb+ib];

47

1 7 92 3014105

Page 48: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

p++;ib++;if(ib==kb){

while(ic<kc){

a[p]=c[pc+ic];p++;ic++;

}pb+=kb;pc+=kc;ib=ic=0;nb-=kb;nc-=kc;kb=min(k,nb);kc=min(k,nc);

}}else{

a[p]=c[pc+ic];p++;ic++;if(ic==kc){

while(ib<kb){

a[p]=b[pb+ib];p++;ib++;

}pb+=kb;pc+=kc;ib=ic=0;nb-=kb;nc-=kc;kb=min(k,nb);kc=min(k,nc);

}}

}if(nb>0){

for(int i=1;i<=nb;i++){

a[p]=b[pb+ib];p++;ib++;

}

48

Page 49: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

}}

4.10.4. Đánh giá giải thuật.

Do k=2*k nên số lần lặp của vòng do while là log2(n). Mà vòng lặp thứ 2 lặp n lần. Nên độ phức tạp của thuật toán là O(n*log2(n)).

4.10.5. Nhận xét.

Nhược điểm lớn nhất của thuật toán là không tận dụng những thông tin đặc tính của dãy sắp xếp. Ví dụ dãy đã có thứ tự sẵn. Vì vậy người ta cần phải cải tiến thuật toán.

Phương pháp trộn tự nhiên (cải tiến MergeSort).

Ý tưởng giải thuật.

Phân hoạch dãy ban đầu thành các dãy con. Sau khi phân hoạch xong, dãy ban đầu sẽ được tách thành 2 dãy phụ theo nguyên tắc phân phối các run có chiều dài cực đại. Rồi trộn từng cặp run có chiều dài cực đại của 2 dãy phụ thành 1 dãy với nguyên tắc thứ tự tăng dần. Lặp lại qui trình trên sau 1 số bước, ta sẽ nhận được 1 dãy chỉ gồm 1 dãy con không giảm.

Ví dụ.

Cho dãy số a sau:

49

10 14 52 73091

a= 10 14 52 73091

10 71 14

2 305 9

2 5 910 730141

b=

c=

a=

Page 50: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

Dừng.

Vậy dãy đã được sắp xếp.

Cài đặt.

void improveMergeSort(int a[],int n){

int p,pb,pc;int b[MAX],c[MAX],b1[MAX],c1[MAX];do{

p=pb=pc=0;i=j=0;while(p<n){

if(p<n)

50

a= 2 5 910 730141

2 10 7

1 145 9

1 9 102 730145

b=

c=

a=

30

a= 1 9 102 730145

1 2 5

7

1 7 92 3014105

b=

c=

a=

9 10 3014

1 7 92 3014105

Page 51: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

{b[pb]=a[p];i++;b1[i]=1;pb++;p++;

}while((a[p–1]<=a[p])&&(p<n)){

b[pb]=a[p];b1[i]++;pb++;p++;

}if(p<n){

c[pc]=a[p];j++;c1[j]=1;pc++;p++;

}while(a[p–1]<=a[p]&&p<n){

c[pc]=a[p];c1[j]++;pc++;p++;

}}

improveMerge(a,b,pb,b1,c,pc,c1);}while(pc>0);

}

void improveMerge(int a[],int b[],int nb,int b1[],int c[],int nc,int c1[])

{int p,pb,pc,ib,ic,kb,kc,i,j;p=0;i=1;j=1;kb=b1[i++];kc=c1[j++];pb=0;pc=0;ib=0;ic=0;while((0<nb)&&(0<nc)){

if(b[pb+ib]<=c[pc+ic])

51

Page 52: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

{a[p]=b[pb+ib];p++;ib++;if(ib==kb){

while(ic<kc){

a[p]=c[pc+ic];p++;ic++;

}pb+=kb;pc+=kc;ib=ic=0;nb-=kb;nc-=kc;kb=b1[i++];kc=c1[j++];

}}else{

a[p]=c[pc+ic];p++;ic++;if(ic==kc){

while(ib<kb){

a[p]=b[pb+ib];p++;ib++;

}pb+=kb;pc+=kc;ib=ic=0;nb-=kb;nc-=kc;kb=b1[i++];kc=c1[j++];

}}

}if(nb>0){

for(int i=1;i<=nb;i++){

a[p]=b[pb+ib];p++;

52

Page 53: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

ib++;}

}}

Đánh giá giải thuật.

Do số lần lặp của vòng do while <= log2(n). Mà vòng lặp thứ 2 lặp n lần. Nên độ phức tạp của thuật toán là O(n*log2(n)).

5. Bài tập.

5.1. Lý thuyết.

11. Xét mảng các số nguyên có nội dung như sau:

-7 -2 -2 0 5 6 10 16 24.

a. Tính số lần so sánh để tìm ra phần tử x = -2. bằng phương pháp:

-Tìm tuyến tính.

-Tìm nhị phân.

b. Trong trường hợp tìm nhị phân, phần tử nào sẽ được tìm thấy (thứ 1 hay 2).

12. Cho biết ý tưởng của từng thuật toán sắp xếp trên. Với ý tưởng các thuật toán trên thực hành với ví dụ sau:

9 4 2 -1 7 14 2 3.

13. Trong 3 phương pháp sắp xếp cơ bản (chọn trực tiếp, chèn trực tiếp, nổi bọt) phương pháp nào thực hiện sắp xếp nhanh nhất với 1 dãy có thứ tự. Giải thích.

5.2. Thực hành.

14. Cài đặt 10 thuật toán sắp xếp tăng (và giảm) và 2 thuật toán tìm kiếm đã trình bày. Thể hiện các thao tác thuật toán đó.

15. Cài đặt thuật toán sắp xếp tăng các số nguyên trong mảng bằng phương pháp chọn trực tiếp.

16. Cài đặt hàm tìm dãy con tăng dài nhất của mảng một chiều a có n phần tử.

17. Cài đặt hàm trộn 2 mảng một chiều có thứ tự tăng b và c có m và n phần tử thành 1 mảng 1 chiều a cũng có thứ tự tăng.

53

Page 54: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 2: Các giải thuật tìm kiếm và sắp xếp

18. Cài đặt thuật toán sắp xếp sinh viên theo thứ tự tăng (về tên sinh viên) cho bài tập 9 – chương 1.

19. Bằng việc nhập mảng a randomize. Thử viết chương trình lập bảng so sánh thời gian thực hiện của các thuật toán sắp xếp.

54

Page 55: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

CHƯƠNG III: CẤU TRÚC DỮ LIỆU.

Mục tiêu.

Giới thiệu khái niệm cấu trúc dữ liệu động.

Danh sách liên kết: tổ chức, các thao tác, các thuật toán, ứng dụng.

1. Giới thiệu.

Với các cấu trúc dữ liệu được xây dựng như: kiểu thực, kiểu nguyên, kiểu ký tự… hoặc kiểu tập tin, tập hợp, mảng… sẽ giải quyết được các bài toán đơn giản còn các bài toán phức tạp như: cách lưu số nguyên lớn, lưu sinh viên của trường… việc ta dùng các cấu trúc trên là rất khó khăn. Vì vậy cần phải có cấu trúc khác để giải quyết các bài toán trên.

Dạng đơn giản nhất của các cấu trúc dữ liệu động là danh sách liên kết. Đây là các cấu trúc dữ liệu tuyến tính. Điểm đặc trưng của cấu trúc dữ liệu này là khả năng truy xuất tuần tự. Tuy nhiên điều này làm cho việc truy vấn thông tin lưu trên cấu trúc dữ liệu này thường chậm; nhưng chúng cho phép sử dụng bộ nhớ hiệu quả hơn, thể hiện rõ qua các thao tác trên danh sách liên kết đơn và danh sách liên kết đôi, danh sách liên kết vòng mà chúng ta sẽ khảo sát.

Stack và hàng đợi (Queue) là một trong những dạng cài đặt ứng dụng cụ thể của danh sách liên kết. Stack (hay Queue) là một đối tượng rất thông dụng trong thực tế và là một cấu trúc dữ liệu thông dụng trong lập trình. Vì vậy khả năng ứng dụng của danh sách liên kết sẽ được nêu trong chương 3 này.

2. Định nghĩa.

Cho T là một kiểu được định nghĩa trước, kiểu danh sách Tx gồm các phần tử thuộc kiển T được định nghĩa là:

Tx=<Vx,Ox>.Trong đó:

Vx ={ tập hợp có thứ tự các phần tử kiểu T được móc nối với nhau theo trình tự tuyến tính}.

Ox ={ các phương thức thiết lập trên danh sách Tx (như tạo danh sách; hủy danh sách; tìm phần tử trong danh sách; hủy 1 phần tử…)}

55

Page 56: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

3. Các loại danh sách liên kết.

Danh sách liên kết đơn.

Danh sách liên kết đôi.

Danh sách liên kết vòng.

4. Danh sách liên kết đơn.

4.1. Khái niệm node.

4.1.1. Cấu tạo node.

Thành phần dữ liệu (data): lưu trữ các thông tin về bản thân phần tử.

Thành phần mối liên kết (link): lưu trữ dịa chỉ của phần tử kế tiếp trong danh sách, hoặc lưu trữ giá trị NULL nếu là phần tử cuối danh sách.

NULL là một hằng số biểu thị giá trị của con trỏ chưa được gán địa chỉ nào.

4.1.2. Khai báo node.

typedef int data;typedef struct tagNode{

data key;struct tagNode* pNext;

}Node;

4.1.3. Tạo node.

Node *createNode(data x=0){

Node *p;p=(Node*)new Node;if(p==NULL){

printf(“Không đủ bộ nhớ để cấp phát !”);getch();return NULL;

}pkey=x;

56

data link

x NULL

key pNext

Page 57: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

ppNext=NULL;return p;

}

4.1.4. Xóa node.

void deleteNode(Node *&p){

if(p==NULL) return;ppNext=NULL;delete p;p=NULL;

}

4.2. Khái niệm danh sách liên kết đơn.

Mỗi phần tử liên kết với phần tử đứng sau nó trong danh sách.

Ví dụ: Cho danh sách sau:

typedef struct tagList{

Node *pHead;Node *pTail;

}List;

4.3. Một số phương thức thiết lập trong danh sách liên kết đơn.

4.3.1. Khởi tạo danh sách liên kết đơn.

Ví dụ

Tạo danh sách gồm 3 phần tử qua các bước sau:

57

xp

2 5 3 NULLpHead

pTail

Bước 1: -Khởi tạo pHead=pTail=NULL.

NULLpHead

pTail

Page 58: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Vậy danh sách được tạo ra như sau:

Cài đặt

void createSList(List &l,int n){

data x;Node *q;

58

Bước 2: -Tạo node q1. NULL2

-Gán pHead=q1(1)-Gán pTail=q1(2)

NULL2

NULLpHead

pTail

1

2

NULL5Bước 3: -Tạo node q2

-Gán pTailpNext=q2.(1)-Gán pTail=q2.(2)

pHead

NULL NULL2 5

pTail

1

2

NULL

pHead

pTail

32 5

NULL NULL

pHead

2 5 3

pTail

1

2

-Gán pTailpNext=q3.(1)-Gán pTail=q3.(2)

Bước 4: -Tạo node q3. NULL3

Page 59: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

l.pHead=l.pTail=NULL;for(int i=1;i<=n;i++){

printf(“Nhập phần tử thứ %d là:”,i);scanf(“%d”,&x);q=createNode(x);if(q==NULL){

printf(“Không đủ bộ nhớ cấp phát!”);getch();exit(1);

}if(l.pHead==NULL) l.pHead=l.pTail=q;else{

l.pTailpNext=q;l.pTail=q;

}}

}

4.3.2. Tìm kiếm 1 phần tử trong danh sách liên kết đơn.

Ví dụ

Giả sử có danh sách sau:

Tìm phần tử x=5 trong danh sách trên.

Các bước thực hiện như sau:

59

Bước 2: -Kiểm tra: pkey!=x. -p=ppNext.

pHead

NULL

pTail

32 5

p

Bước 1: -p=pHead.

NULL

pHead pTail

32 5

p

pHead

NULL

pTail

32 5

Page 60: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt

Node *searchSList(List l,data x){

Node *p;p=l.pHead;while(p){

if(pkey==x) return p;p=ppNext;

}return NULL;

}

4.3.3. Thêm 1 phần tử vào danh sách liên kết đơn.

Thêm 1 phần tử vào đầu danh sách.

Ví dụ:

Giả sử ta có danh sách sau:

Thêm phần tử x = 4 vào đầu danh sách trên.

60

Bước3: -Kiểm tra: pkey==x. -Dừng. Đã tìm thấy vị trí x trong danh

sách.

pHead

NULL

pTail

32 5

p

NULL4Bước 1: - Tạo node q có phần tử là 4.

Bước 2: -Gán qpNext=pHead.(1)

-Gán pHead=q.(2)

NULL

pHead

NULL4

3

pTail

2 512

NULL

pHead

3

pTail

2 5

Page 61: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt:

void addHeadSList(List &l,Node *q){

if(q==NULL) return;if(l.pHead==NULL) l.pHead=l.pTail=q;else{

qpNext=l.pHead;l.pHead=q;

}}

Thêm 1 phần tử vào cuối danh sách.

Ví dụ:

Giả sử ta có danh sách sau:

61

Vậy ta có danh sách mới sau:

NULL

pHead

4

3

pTail

2 5

NULL4Bước 1: - Tạo node q có phần tử là 4.

Vậy ta có danh sách mới sau:

pHeadNULL4

3

pTail

2 5

Bước 2: -Gán pTailpNext=q.(1) -Gán pTail=q.(2)

NULL

NULL

pHead2

4

3

pTail

2 51

NULL

pHead

3

pTail

2 5

Page 62: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt:

void addTailSList(List &l,Node *q){

if(q==NULL) return;if(l.pHead==NULL) l.pHead=l.pTail=q;else{

l.pTailpNext=q;l.pTail=q;

}}

Thêm 1 phần tử vào vào sau node p trong danh sách.

Ví dụ:

Giả sử ta có danh sách sau:

Thêm phần tử có giá trị 4 vào sau node p.

62

NULL4Bước 1: -Tạo node q có phần tử là 4.

Vậy ta có danh sách mới sau khi thêm:

NULL

pHead

3

pTail

2 5

4

Bước 2: -qpNext=ppNext.(1) -ppNext=q.(2)

NULL

NULL

pHead

3

pTail

2 5

p 4

12

p

pHead

NULL3

pTail

2 5

Page 63: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt:

void addAfterNodeSList(List &l,Node *p,Node *q){

if(l.pHead==NULL){ l.pHead=l.pTail=q; return;}if(q==NULL) return;if(p==NULL) addHeadSList(l,q); //khi danh sách rỗng

else{

qpNext=ppNext;ppNext=q;if(p==l.pTail) l.pTail=q;

}}

4.3.4. Bỏ 1 phần tử của danh sách liên kết đơn.

Xóa 1 phần tử ở đầu danh sách.

Ví dụ:

Giả sử ta có danh sách sau:

Ta thực hiện xóa phần tử đầu theo các bước sau:

63NULL

pHead

2

Bước 2: -ppNext=NULL.(1)

-free(p).(2)

3

pTail

2 5

p

1

Bước 1: -p=pHead.(1) -pHead=ppNext.(2)

NULL

pHead

3

pTail

2 5

p

2

1

pHead

NULL3

pTail

2 5

Page 64: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt:

void deleteHeadSList(List &l){

Node *p;p=l.pHead;if(p==NULL) return;l.pHead=ppNext;if(l.pHead==NULL) l.pTail=NULL;deleteNode(p);

}

Xóa 1 phần tử ở cuối danh sách.

Ví dụ:

Giả sử ta có danh sách sau:

Ta thực hiện xóa phần tử cuối theo các bước sau:

64

Vậy ta có danh sách mới sau khi xóa:

NULL

pHead

3

pTail

5

Bước 2: -p=pTail.(1) -qpNext=NULL.(2)

NULL

pHead

3

pTail

2 5

q p1

2

Bước 1: -q=pHead. -Duyệt danh sách tìm node q nằm trước node

pTail.

NULL

pHead

3

pTail

2 5

q

NULL

pHead

3

pTail

2 5

Page 65: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt:

void deleteTailSList(List &l){

Node *q;q=l.pHead;if(l.pHead==NULL) return; //khi danh sách không có phần tử nào

while(q) //tìm nút sau nút pTail

{if(qpNext==l.pTail)break;q=qpNext;

}if(q){

l.pTail=q;q=qpNext;l.pTailpNext=NULL;

}else{

q=l.pHead;l.pHead=l.pTail=NULL;

}deleteNode(q);

}

Xóa 1 phần tử ở sau node q trong danh sách.

Ví dụ:

65

Bước 3: -pTail=q.(1) -free(p).(2)

NULL

pHead

32

pTail

2 5

q p

1

Vậy ta có danh sách mới sau khi xóa:

pHead

NULL

pTail

2 5

Page 66: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Giả sử ta có danh sách sau:

Ta thực hiện xóa phần tử sau q theo các bước sau:

Cài đặt:

void deleteAfterNodeSList(List &l,Node *q){

Node *p;if(l.pHead==NULL) return; //danh sách rỗng

66

Bước 2: -ppNext=NULL.(1) -free(p).(2)

NULL

pHead

2 132 5

pTail

q pVậy ta có danh sách mới sau khi xóa:

NULL

pHead

3

pTail

2

Bước 1: -p=qpNext.(1) -qpNext=ppNext.(2)

NULL

pHead

32 5

pTail

q

2

1p

NULL

pHead

3

pTail

2 5

q

Page 67: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

if(q==NULL){

p=l.pHead;l.pHead=ppNext;if(l.pHead==NULL) //khi danh sách có 1 nút

l.pTail=NULL;}else{

p=qpNext;if(p){

qpNext=ppNext;if(p==l.pTail) l.pTail=q; //khi danh sách có 1 nút

deleteNode(p);}

}}

4.3.5. Xóa danh sách liên kết đơn.

Ví dụ:

Giả sử ta có danh sách sau:

Ta thực hiện xóa danh sách theo các bước sau:

67

Bước 2: -p=pHead.(1) -pHead=ppNext.(2) -deleteNode(p).(3)

NULL

pHead

333

pTail

p

2

1

pHead

NULL3

pTail

2 5

3

Bước 1: -p=pHead.(1) -pHead=ppNext.(2) -deleteNode (p).(3)

pHead

NULL32 5

pTail

p1

2

Page 68: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Vậy danh sách đã được xóa.

Cài đặt:

void deleteSList(List &l){

Node *p;if(l.pHead==NULL) return; //khi danh sách rỗng

while(l.pHead !=NULL){

p=l.pHead;l.pHead=ppNext;deleteNode(p);

}l.pTail=NULL;

}

4.4. Các loại danh sách liên kết đơn đặc biệt.

4.4.1. Stack.

68

Bước 3: -p=pHead.(1) -pHead=ppNext.(2) -deleteNode(p).(3)

NULL

pHead

33

pTail

p

2

1Bước 4: -pTail=NULL.

NULL

pHead pTail

VThuốc 1

VThuốc 2

VThuốc 3

VThuốc 4

VThuốc 5

Từng viên thuốc đượclấy ra theo thứ tự.

Từng viên thuốc đượcbỏ vào theo thứ tự.

Hình ảnh viên thuốc được lấy ra và bỏ vào hộp thuốc.

Page 69: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Nhận xét: Cơ chế của Stack là: vào sau ra trước.

Kiểm tra Stack rỗng.

int emptyS(List S){

if(S.pHead) return 0;S.pTail=NULL;return 1;

}

Thêm 1 phần tử vào Stack.

void pushS(List &S,Node *p){

if(p)if(!emptyS(S)){

ppNext=S.pHead;S.pHead=p;

}else{

S.pHead=p;S.pTail=p;

}}

Lấy 1 phần tử ra khỏi Stack.

Node *popS(List &S){

Node *p=NULL;if(!emptyS(S)) //kiểm tra Stack rỗng

{p=S.pHead;S.pHead=S.pHeadpNext;ppNext=NULL;

}return p;

}

69

Page 70: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Ứng dụng:

Một số ứng dụng thường cần đến Stack:

Trong trình biên dịch khi thực hiện các thủ tục, tức là Stack được sử dụng để lưu môi trường của các thủ tục.

Stack cũng còn được sử dụng trong trường hợp khử đệ quy đuôi. Ví dụ thủ tục QuickSort sử dụng Stack.

4.4.2. Hàng đợi(Queue).

Nhận xét: Cơ chế của hàng đợi là: vào trước ra trước.

Kiểm tra hàng đợi rỗng.

int emptyQ(List Q){

if(Q.pHead) return 0;return 1;

}

Thêm 1 phần tử vào hàng đợi.

void pushQ(List &Q,Node *p){

if(p)if(!emptyQ(Q)) //kiểm tra Queue rỗng

{Q.pTailpNext=p;Q.pTail=p;

}else{

Q.pHead=p;Q.pTail=p;

}}

Lấy 1 phần tử ra khỏi hàng đợi.

Node *popQ(List &Q){

70

A C D S T

Khách ra khỏi phòngmua vé theo thứ tự ra.

Khách vào phòng muavé theo thứ tự vào.

Phòng bán vé xem phim

Page 71: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Node *p=NULL;if(!emptyQ(Q)){

p=Q.pHead;Q.pHead=Q.pHeadpNext;ppNext=NULL;

}return p;

}

Ứng dụng:

Hàng đợi có nhiều ứng dụng: khử đệ qui, tổ chức lưu vết các quá trình tìm kiếm theo chiều rộng, tổ chức quản lý và phân phối tiến trình trong các hệ điều hành, tổ chức bộ đệm bàn phím.

5. Danh sách liên kết đôi.

5.1. Khái niệm node.

5.1.1. Cấu tạo node.

Thành phần dữ liệu (data): lưu trữ các thông tin về bản thân phần tử.

Thành phần mối liên kết (link): lưu trữ dịa chỉ của phần tử phía sau hay địa chỉ của phần tử phía trước trong danh sách, hoặc lưu trữ giá trị NULL nếu là phần tử cuối danh sách hay phần tử đầu danh sách.

5.1.2. Khai báo node.

typedef int data;typedef struct tagDNode{

data key;struct tagDNode *pNext;struct tagDNode *pPre;

}DNode;

5.1.3. Tạo node.

DNode *createDNode(data x=0) //khởi tạo giá trị mặc định giá trị x

71

data linklink

x

key pNext

NULLNULL

pPre

Page 72: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

{DNode *p;p=(DNode *)new DNode;if(p==NULL){

printf(“Không đủ bộ nhớ để cấp phát !”);getch();return NULL;

}pkey=x;ppNext=NULL;ppPre=NULL;return p;

}

5.1.4. Xóa node.

void deleteDNode(Dnode *&p){

if(p==NULL) return;ppNext=NULL;ppPre=NULL;delete p;p=NULL;

}

5.2. Khái niệm danh sách liên kết đôi.

Mỗi phần tử liên kết với các phần tử đứng trước và sau nó trong danh sách.

Ví dụ:

Cho danh sách liên kết đôi sau:

typedef struct tagDList{

DNode *pHead;DNode *pTail;

}DList;

72

x

p

3 NULL

pHead pTail

52NULL

Page 73: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

5.3. Một số phương thức thiết lập trong danh sách liên kết đôi.

5.3.1. Khởi tạo danh sách liên kết đôi.

Ví dụ:

Tạo danh sách gồm 2 phần tử qua các bước sau:

Vậy danh sách liên kết đôi được tạo ra:

Cài đặt:

73

Bước 1: - Khởi tạo pHead=pTail=NULL.

pHead NULL

pTail

NULL2NULLBước 2: - Tạo node q1.

pHead

-Gán pHead=q1.(1)-Gán pTail=q1.(2)

NULL

pTail

1

2

NULL2NULL NULL5NULLBước 2: - Tạo node q2.

-Gán pTailpNext=q2.(1)-Gán q2pPre=pTail.(2)-Gán pTail=q2.(3)

pHead

pTail

12

3

NULL2NULL

NULL5NULLpTail

pHead

2NULL NULL5

Page 74: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Bước 2: -ppNext=qpNext.(1)

-qpNext=p.(2)

NULL

12

q

NULL

NULLNULL 3

pHead pTail

52

4

Chương 3: Cấu trúc dữ liệu

void createDList(DList &l,int n){

data x;DNode *p;l.pHead=l.pTail=NULL;for(int i=1;i<=n;i++) //tạo danh sách với n phần tử

{printf(“Nhập phần tử thứ %d là:”,i);scanf(“%d”,&x);p=createDNode(x);if(p==NULL){

printf(“Không đủ bộ nhớ cấp phát!”);getch();exit(1);

}if(l.pHead==NULL) //khi danh sách rỗng

l.pHead=l.pTail=p;else{

l.pTailpNext=p;ppPre=l.pTail;l.pTail=p;

}}

}

5.3.2. Thêm 1 phần tử vào danh sách liên kết đôi.

Ví dụ:

Giả sử ta có danh sách sau:

Thêm phần tử có giá trị 4 vào sau node q.

Thực hiện qua các bước sau:

74

NULL4NULLBước 1: - Tạo node p có giá trị 4.

3 NULL

pHead pTail

52NULL

q

Page 75: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Danh sách sau khi thêm 1 phần tử:

Cài đặt:

void addAfterDNodeDList(DList &l,DNode *q,DNode *p){

if(p==NULL) return;if(l.pHead==NULL) //khi danh sách rỗng

{l.pHead=p;l.pTail=p;

}else{

if(q==NULL) //thêm vào đầu

{ppNext=l.pHead;l.pHeadpPre=p;l.pHead=p;

}else{

ppNext=qpNext;qpNext=p;DNode *r=ppNext; //r sẽ là phần tử sau p

if(r) rpPre=p;ppPre=q;if(q==l.pTail) //thêm vào cuối

l.pTail=p;

75

NULLNULL 3

pHead pTail

52

4

-r=qpNext.(1)-rpPre=p.(2)-ppPre=q.(3)

q

NULL

1

3

r

2

NULLNULL 3

pHead pTail

52

4

Page 76: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

}}

}

5.3.3. Bỏ 1 phần tử ra khỏi danh sách liên kết đôi.

Ví dụ:

Giả sử ta có danh sách sau:

Hủy phần tử sau node q.

Ta thực hiện qua các bước sau:

76

3 NULL

pHead pTail

52NULL

q

Bước 1: -Gán p=qpNext.(1) -Gán r=ppNext.(2)

NULL

pHead pTail

NULL

q p r

2 5 3

Bước 2: -rpPre=q.(1)-qpNext=r.(2)-deleteDNode(p).(3)

32

1

2

NULL

pHead pTail

5NULL

q p r3

Danh sách sau khi xóa 1 phần tử:

3 NULL

pHead pTail

2NULL

Page 77: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt:

void deleteAfterDNodeDList(DList &l,DNode *q){

if(l.pHead==NULL) return;if(q==NULL) //xoá đầu danh sách

{q=l.pHead;l.pHead=l.pHeadpNext;if(l.pHead==NULL) //danh sách chỉ có 1 nút

l.pTail=NULL;else l.pHeadpPre=NULL;deleteDNode(q);

}else{

DNode *p=qpNext;if(p==NULL) return; //khi danh sách có 1 nút

qpNext=ppNext;if(p==l.pTail) //xoá cuối danh sách

l.pTail=q;else{

DNode *r=ppNext;rpPre=q;

}deleteDNode(p);

}}

5.3.4. Xóa danh sách liên kết đôi.

Ví dụ:

Giả sử ta có danh sách sau:

77

3 NULL

pHead pTail

52NULL

Để xóa danh sách trên ta thực hiện các bước sau:

Bước 1: -p=pHead.(1)-pHead=pHeadpNext.(2)

p

3 NULL

pHead pTail

52NULL

1

2

Page 78: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

78

-pHeadpPre=ppNext.(1)-deleteDNode(p).(2)

p

3 NULL

pHead pTail

52NULL

12

Bước 2: -p=pHead.(1)-pHead=pHeadpNext.(2)

pHead

1p

3 NULL

pTail

5NULL

2

-pHeadpPre=ppNext(1)-deleteDNode(p).(2)

pHead

NULL

p

3 NULL

pTail

5

1

2

Bước 3: -p=pHead.(1)-pHead=pHeadpNext.(2)

pHead

p

NULL

2

3 NULL

pTail

1

NULL 3 NULL

pHead pTail

1

2

p

-deleteDNode(p).(1)-pTail=NULL.(2)

Page 79: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt:

void deleteDList(DList &l){

DNode *p;while(l.pHead!=NULL){

p=l.pHead;l.pHead=ppNext;if(l.pHead!=NULL) l.pHeadpPre=NULL;deleteDNode(p);

}l.pTail=NULL;

}

6. Danh sách liên kết vòng.

6.1. Khái niệm danh sách liên kết vòng.

Phần tử cuối của danh sách liên kết với phần tử đầu danh sách.

Ví dụ:

6.2. Một số phương thức thiết lập trong danh sách liên kết vòng.

6.2.1. Khởi tạo danh sách liên kết vòng.

Ví dụ:

Tạo danh sách gồm 2 phần tử qua các bước sau:

79

Vậy danh sách sau khi xóa:

NULL

pHead pTail

pHead

5

pTail

2

Bước 1: -Khởi tạo pHead=pTail=NULL.

NULLpHead

pTail

Page 80: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt:

void createRList(List &l,int n){

Node *p;int x;l.pHead=l.pTail=NULL;for(int i=1;i<=n;i++)

80

Vậy danh sách liên kết vòng sau khi được tạo ra:

pHead

5

pTail

2

Bước 2: -Tạo node q có giá trị 5. 5 NULL

-pHead=q.(1)-pTail=q.(2)

-pTailpNext=pHead.(3)

pHead

5 NULL

NULL

pTail

1

2

3

Bước 3: -Tạo node q có giá trị 2.

2 NULL

-qpNext=pHead.(1) -pHead=q.(2) -pTailpNext=pHead.(3)

pHead

15

pTail

2 NULL

2

3

Page 81: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

{printf(“Nhập phần tử thứ %d là”,i);scanf(“%d”,&x);p=createNode(x);if(p==NULL){

printf(“Không đủ bộ nhớ!”);getch();exit(1);

}if(l.pHead==NULL) //khi danh sách rỗng

{l.pHead=l.pTail=p;l.pTailpNext=l.pHead;

}else{

ppNext=l.pHead;l.pTailpNext=p;l.pHead=p;

}}

}

6.2.2. Thêm 1 phần tử vào danh sách liên kết vòng.

Ví dụ:

Giả sử ta có danh sách liên kết vòng sau:

Thêm 1 node p vào sau node q. Ta thực hiện qua các bước sau:

81

Bước 1: - Tạo node p có giá trị 3:

3 NULL

5

pHead pTail

2

q

Bước 2: -ppNext=qpNext.(1)-qpNext=p.(2)

pHead

5

pTail

2

q3 NULL2

1

Page 82: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt

void addAfterNodeRList(List &l,Node *q,Node *p){

if((q==NULL)||(p==NULL)) return;if(l.pHead==NULL) //thêm đầu danh sách

{l.pHead=l.pTail=p;l.pTailpNext=l.pHead;

}else{

ppNext=qpNext;qpNext=p;if(l.pTail==q) //thêm cuối danh sách

l.pTail=p;}

}

6.2.3. Bỏ 1 phần tử của danh sách liên kết vòng.

Ví dụ

Giả sử ta có danh sách liên kết vòng sau:

Xóa 1 node sau node q. Ta thực hiện qua các bước sau:

82

Vậy ta có danh sách liên kết vòng sau khi được sắp xếp.

pHead

5

pTail

2

3

pHead

5

pTail

2 3

qBước 1: -p=qpNext.(1) -qpNext=ppNext.(2)

pHead

5

pTail

2 3

q p2 1

Page 83: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt

void deleteAfterNodeRList(List &l,Node *q){

if((l.pHead==NULL)||(q==NULL)) return;Node *p=qpNext;qpNext=ppNext;if(q==p) //khi danh sách vòng có 1 nút

l.pHead=l.pTail=NULL;else{

if(p==l.pHead) l.pHead=ppNext;if(p==l.pTail) l.pTail=q;

}deleteNode(p);

}

6.2.4. Xóa danh sách liên kết vòng.

Ví dụ

Giả sử ta có danh sách liên kết vòng sau:

83

Bước 2: -deleteNode(p).

pHead

3 5

pTail

2

q pVậy danh sách liên kết vòng sau khi được xóa.

pHead

5

pTail

2

pHead

5

pTail

2 3

Page 84: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

84

Bước 2: -p=q.(1)-q=ppNext.(2)-deleteNode(p).(3)

pHead

q

35

pTail

2

p1

2NULL

Bước 2: -deleteNode(q).(1)

pHead

q

pTail

2

NULL

NULL

Vậy danh sách liên kết đơn sau khi xóa:

pHead pTail

NULL

-p=q.(1)-q=ppNext.(2)-deleteNode(p).(3)

pHead

3

q

35

pTail

2

p1

2NULL

Xóa danh sách vòng, ta thực hiện qua các bước sau:Bước 1: -q=pHeadpNext.

-pHeadpNext=NULL.

pHead

5

pTail

2 3

qNULL

Page 85: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Cài đặt

void deleteRList(List &l){

Node *p,*q;if(l.pHead==NULL) return;p=l.pHeadpNext;while(p!=l.pHead){

q=p;p=ppNext;deleteNode(q);

}if(p==l.pHead){

deleteNode(p);l.pHead=l.pTail=NULL;

}}

7. Bài tập.

7.1. Lý thuyết.

20. Phân tích ưu điểm và khuyết điểm của xâu liên kết với mảng. Tổng quát hoá các trường hợp nên dùng xâu liên kết.

21. Hiểu được các thao tác thêm xóa sửa tìm kiếm nút. Nắm được các điểm mạnh của cấu trúc dữ liệu.

22. Xây dựng một cấu trúc dữ liệu sinh viên thích hợp. Với các thao tác sau:

Thêm 1 sinh viên.

Xóa 1 sinh viên.

Sửa 1 sinh viên.

Sắp xếp tăng dần danh sách sinh viên đó.

Tìm kiếm sinh viên.

23. Nắm được cơ chế hoạt động của Stack, Queue. Và các thao tác thêm 1 phần tử vào Stack, Queue và lấy 1 phần tử ra khỏi Stack, Queue.

85

Page 86: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 3: Cấu trúc dữ liệu

Ứng dụng vào việc lưu các kí tự của 1 chuỗi bằng hàng đợi, bằng stack. Và cho biết kết quả xuất ra từ hàng đợi và stack với chuỗi như sau:

“ hell*o***w*orld** ”

24. Giả sử xây dựng một chương trình soạn thảo văn bản, hãy chọn cấu trúc dữ liệu thích hợp để lưu trữ văn bản trong quá trình soạn thảo. Biết rằng :

-Số dòng văn bản không hạn chế.

-Mỗi dòng văn bản có chiều dài tối đa 80 tý tự.

-Các thao tác gồm:

Di chuyển trong văn bản.

Thêm, xóa sửa ký tự trong 1 dòng.

Thêm xóa sửa 1 dòng trong văn bản.

7.2. Thực hành.

25. Cài đặt tất cả các thao tác cơ bản trên danh sách liên kết đơn, danh sách kiên kết đôi, danh sách liên kết vòng.

26. Cài đặt thuật toán sắp xếp chèn trực tiếp trên xâu kép. Nhận xét xem nó có phát huy ưu thế của thuật toán hơn trên mảng hay không.

27. Cài đặt thuật toán QuickSort theo kiểu không đệ qui.

28. Cài đặt lại chương trình quản lý sinh viên theo như bài tập 22.

29. Cài đặt lại chương trình soạn thao văn bản theo mô tả trong bài tập 24.

30. Cài đặt chương trình tạo một bảng tính cho phép thực hiện các phép tính +, - , * , / , div trên các số tối đa 30 chữ số.

31. Cài đặt chương trình cho phép nhập vào một biểu thức gồm các số, các toán tử + , -, * , / , % , các hàm toán học sin, cos, tan, ln, ex, dấu mở đóng ngoặc “(”, ”)” và tính toán giá trị của biểu thức.

32. Cài đặt chương trình cho phép nhập vào hai đa thức gồm các toán hạng là các số, các toán tử + , - , * , và biến x, và thực hiện việc + , - , * , / hai đa thức.

86

Page 87: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

CHƯƠNG IV: CÂY.

Mục tiêu.

Giới thiệu khái niệm cấu trúc cây.

Cấu trúc dữ liệu cây nhị phân tìm kiếm: tổ chức, các thao tác, các thuật toán, ứng dụng.

Giới thiệu cấu trúc dữ liệu cây nhị phân tìm kiếm cân bằng, các thao tác cân bằng lại khi mất cân bằng.

1. Giới thiệu.

Do nhược điểm về tốc độ tìm kiếm của danh sách liên kết nên người ta đã tìm kiếm các cấu trúc dữ liệu khác hiệu quả hơn. Cây là một trong những đáp án cho bài toán này. Do đó trong chương này chúng ta sẽ xem xét cấu trúc dữ liệu cây.

Phần đầu của chương trình bày các khái niệm liên quan đến cây nhị phân, các thao tác trên cấu trúc dữ liệu này. Phần tiếp theo, cây nhị phân tìm kiếm là một dạng đặc biệt của cây nhị phân. Đây là một cấu trúc dữ liệu cho phép tìm kiếm hiệu quả hơn hẳn danh sách liên kết mà các thao tác không phức tạp nhiều nên cây nhị phân tìm kiếm là một cấu trúc dữ liệu thông dụng.

Trong một số trường hợp cây nhị phân tìm kiếm bị suy biến thành danh sách liên kết. Điều này làm cho cây nhị phân cân bằng (AVL) ra đời. Cấu trúc cây nhị phân cân bằng đảm bảo thao tác tìm kiếm chỉ tốn chi phí log2(n) với n là số nút trên cây. Nhưng nhược điểm là thao tác cân bằng lại mỗi khi cây mất cân bằng. Việc thêm hay huỷ phần tử đều có thể làm cân mất cân bằng, việc cân bằng lại có thể lan truyền lên tận gốc.

2. Giới thiệu về cây.

Cây là một cấu trúc rất quan trọng và được dùng rất nhiều trong các giải thuật. Trong chương này ta sẽ tìm hiểu các khái niệm cơ bản về cây, các phép toán quan trọng trên cây, biểu diễn cây trên máy tính. Cây có nhiều ứng dụng trong đời sống hàng ngày, chẳng hạn như tổ chức các quan hệ họ hàng trong gia phả, mục lục của một sách,…

Chúng ta đã tìm hiểu về phương pháp tìm kiếm tuyến tính và tìm kiếm nhị phân. Đối với thuật toán tìm kiếm tuyến tính ta có thể đưa vào danh sách liên kết, nhưng thuật toán tìm kiếm nhị phân thì không thể. Trong phần này, chúng ta xét đến cây nhị phân tìm kiếm, mà việc tìm kiếm nhị phân có thể thực hiện trên đó, là một dạng của danh sách liên kết.

87

Page 88: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

3. Cấu trúc cây.

3.1. Định nghĩa cây.

Là một tập hợp T các phần tử (gọi là nút của cây) trong đó có 1 nút đặc biệt được gọi là nút gốc, các nút còn lại được chia thành những tập rời nhau T1,T2,…,Tn theo quan hệ phân cấp trong đó Ti cũng là 1 cây.

Cấu trúc cây Ti là một nút cấu trúc rỗng được gọi là cây rỗng (NULL).

Một nút mà thông tin chính của nó có kiểu T, mà nó liên kết với một số hữu hạn các cấu trúc cây khác cũng có kiểu T. Các cấu trúc cây khác này được gọi là những cây con của cây đang xét.

Ví dụ:

3.2. Một số khái niệm cơ bản về cây.

Bậc của một nút là số cây con của nút đó.

Bậc của một cây là bậc lớn nhất của các nút trong cây.

Hai nút được nối với nhau bằng một nhánh trực tiếp thì nút trên gọi là nút cha, nút còn lại gọi là nút con.

Nút gốc là nút không có nút cha.

Nút lá là nút có bậc bằng 0.

Nút nhánh là nút có bậc khác 0 và không phải là gốc.

Các nút có cùng một nút cha gọi là nút anh em( nút đồng cấp).

Độ dài đường đi từ gốc đến nút x là số nhánh cần đi qua kể từ gốc đến x.

Độ dài đường đi của một cây được định nghĩa là tổng các độ dài đường đi của tất cả các nút của cây.

88

7 1

5 2 8

4

2

Page 89: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

với là độ dài đường đi từ gốc đến x.

Mức của một nút là độ dài đường đi từ gốc đến nút đó.

Chiều cao của một nút là mức của nút đó.

Chiều cao của một cây là chiều cao lớn nhất của các nút trong cây.

Rừng là tập hợp các cây. Như vậy, nếu một cây bị loại bỏ nút gốc có thể cho ta một rừng.

4. Cây nhị phân.

4.1. Định nghĩa cây nhị phân.

Cây nhị phân là cây mà mỗi nút có tối đa 2 cây con.

Ví dụ:

4.2. Khai báo cây nhị phân.

89

Mức 0

Mức 1

Mức 2

Mức 3

2

7 1

45 28

left key right

Page 90: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

typedef int data;

typedef struct tagNode{

data key;struct tagNode *left;struct tagNode *right;

}Node;

4.3. Khởi tạo cây rỗng.

void createRoot(Node* &root){

root=NULL;}

4.4. Tạo node.

Ví dụ

Cài đặt

Node *createNode(data x=0){

Node *p;p=(Node *)new Node;if(p==NULL){

printf(“Không đủ bộ nhớ”);getch();return NULL;

}pkey=x;pleft=NULL;pright=NULL;return p;

}

4.5. Xóa node.

Ví dụ

90

2

NULLNULL

2

Page 91: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Cài đặt

void deleteNode(Node* &p){

pleft=NULL;pright=NULL;delete p;p=NULL;

}

4.6. Các phép duyệt trên cây nhị phân.

4.6.1. NLR.

Ví dụ

Vậy các nút được in thứ tự như sau:

Cài đặt

91

2

7 1

45 28

Giả sử ta có cây như sau:

2 7 5 8 1 2 4

4

2

7 1

5 28

Page 92: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

void NLR(Node *root){

if(root!=NULL){

printf(“%d”,rootkey);NLR(rootleft);NLR(rootright);

}}

4.6.2. LNR.

Ví dụ

Vậy các nút được in thứ tự như sau:

Cài đặt

void LNR(Node *root){

if(root!=NULL){

LNR(rootleft);printf(“%d”,rootkey);LNR(rootright);

}}

92

5 7 8 2 2 1 4

4

2

7 1

5 28

Page 93: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

4.6.3. LRN.

Ví dụ

Vậy các nút được in thứ tự như sau:

Cài đặt

void LRN(Node *root){

if(root!=NULL){

LRN(rootleft);LRN(rootright);printf(“%d”,rootkey);

}}

5. Cây nhị phân tìm kiếm.

5.1. Định nghĩa.

Cây nhị phân tìm kiếm là cây nhị phân trong đó tại mỗi nút, khóa của nút đang xét lớn hơn khóa của tất cả các nút thuộc cây con trái và nhỏ hơn khóa của tất cả các nút thuộc cây con phải.

93

5 8 7 2 4 1 2

4

2

7 1

5 28

Page 94: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Ví dụ:

5.2. Các thao tác trên cây nhị phân tìm kiếm.

5.2.1. Tìm kiếm 1 phần tử.

Ví dụ

Giả sử cho cây như sau:

Tìm phần tử x=5 trong cây đó.

94

9

6

4 8

1 75

6>x

5 9

6

4 8

1 7

5 9

4 8

1 7

6>x

4<x

6

Page 95: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Cài đặt

Node *SearchNode(Node *root,data x){

if(root==NULL) return NULL;if(rootkey==x) return root; //tìm được khóa thì dừng

if(rootkey>x) return SearchNode(rootleft,x);else return SearchNode(rootright,x);

}

Ta xây dựng 1 hàm không đệ qui như sau:

Node *SearchNode(Node *root,data x){

Node *p;p=root;while(p!=NULL){

if(pkey==x) return p;else

if(pkey>x) p=pleft;else p=pright;

}return NULL;

}

5.2.2. Thêm 1 phân tử vào cây.

Ví dụ

Giả sử ta có cây như sau:

Ta thêm phần tử p có giá trị 3 vào cây.

95

5 9

6

4 8

1 7

Page 96: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Cài đặt

int insertNode(Node* &root,Node *p){

if(root==NULL) //điều kiện dừng để ta thêm nút p vào cây

{root=p;return 1;

}else{

if(rootkey==pkey) //nút cần thêm đã có trong cây

return 0;if(rootkey>pkey)

return insertNode(rootleft,p);if(rootkey<pkey)

return insertNode(rootright,p);}

}

Ta xây dựng 1 hàm không đệ qui như sau:

int insertNode(Node* &root,Node *p){

Node *q,*r;if(root==NULL) //khi cây rỗng

{root=p;return 1;

}q=root;r=NULL;while(q!=NULL){

if(qkey==pkey) //nút cần thêm đã có trong cây

return 0;r=q;

96

3

5 9

6

4 8

1 71<pkey

6>pkey

4>pkey

Page 97: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

if(qkey>pkey) q=qleft;else q=qright;

}if(rkey>pkey) rleft=p;else rright=p;return 1;

}

5.2.3. Xóa 1 phần tử trong cây.

Ví dụ

Giả sử x=23 khi đó ta tìm được node cần xóa.

Trường hợp x là nút lá: deleteNode(p);

Ví dụ: Cho cây sau:

Xoá nút x=23 trên cây.

Vậy cây sau khi xoá.

97

15

9 23

7

p

15

9 23

7

15

9

7

Page 98: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Trường hợp x chỉ có 1 con (trái hoặc phải):

Ví dụ: Cho cây sau:

Vậy cây sau khi xoá:

Trường hợp x có đủ cả 2 con:

Có 2 phần tử thế mạng thỏa mãn yêu cầu:

- Phần tử nhỏ nhất (trái nhất) trên cây con phải.

98

23

15

9

7 20

20

15

9

7

239

7 20

(1)(2)

q

r

p

Xoá nút x=23 ta thực hiện như sau:qright=r;(1)deleteNode(p);(2)

15

Page 99: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

- Phần tử lớn nhất (phải nhất) trên cây con trái.

Ta chọn cách 1: ( Phần tử nhỏ nhất (trái nhất) trên cây con phải )

Ví dụ: Cho cây sau:

Ta cần phải xoá nút x=23 như sau:

99

15

9 23

7 20 64

7046

39

5530

q

r

p

(1)

(2)

(3)

15

9 23

7 20 64

7046

30

39

55

Page 100: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Vậy cây sau khi xoá.

Cài đặt

int deleteNodeTree(Node* &root, data x){

Node *p,*q;if(root==NULL) //khi cây rỗng

return 0;if(rootkey>x)

return deleteNodeTree(rootleft,x);if(rootkey<x)

return deleteNodeTree(rootright,x);else{

p=root;if(rootleft==NULL) //khi cây con không có nhánh trái

root=rootright;else

if(rootright==NULL) //khi cây con không có nhánh phải

root=rootleft;else //khi cây con có cả 2 nhánh

searchNodeTheMang(p,rootright);deleteNode(p);

}return 1;

}void searchNodeTheMang(Node* &p,Node* &q){

if(qleft) searchNodeTheMang(p,qleft);else //tìm được phần tử thế mạng là p

{pkey=qkey;

100

39

15

9 30

7 20 64

7046

55

Page 101: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

p=q;q=qright;

}}

5.2.4. Xóa cây.

Ví dụ

Giả sử ta có cây nhị phân như sau:

Xóa danh sách cây theo dạng duyệt LRN. Thể hiện qua các bước sau:

101

15

137

239

(1)

(2)

Bước 1:15

9

137

23

(1)

(2)

Bước 2: 15

9

13

23

Page 102: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Vậy cây đã được xóa.

Cài đặt

void deleteTree(Node* &root){

if(root){

deleteTree(rootleft);deleteTree(rootright);deleteNode(root);

}}

5.3. Nhận xét.

Tất cả các thao tác tìm kiếm, xóa, thêm trên cây nhị phân tìm kiếm đều có độ phức tạp trung bình O(log2(n)).

Cây nhị phân tìm kiếm là một cấu trúc dữ liệu cho phép tìm kiếm hiệu quả hơn hẳn danh sách liên kết, mà các thao tác không quá phức tạp trên cây nhị phân tìm kiếm là một trong những cấu trúc dữ liệu động thông dụng nhất. Tuy nhiên trong một số trường hợp nó suy biến thành danh sách liên kết.

6. Cây nhị phân cân bằng ( AVL Tree).

6.1. Cây nhị phân cân bằng hoàn toàn.

6.1.1. Định nghĩa.

102

15Bước 5:

(1)(2)

Bước 3:15

9 23

(1)(2)

Bước 4: 15

23

Page 103: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Cây cân bằng hoàn toàn là cây nhị phân tìm kiếm mà tại mỗi nút của nó, số nút của cây con trái chênh lệch không quá một so với số nút của cây con phải.

Ví dụ:

6.1.2. Nhận xét.

Cân cân bằng hoàn toàn có n nút có chiều cao h = log2(n). Đây là lý do cho phép bảo đảm khả năng tìm kiếm nhanh trên cấu trúc dữ liệu này.

Nhược điểm cây cân bằng hoàn toàn là một cấu trúc kém ổn định nên trong thực tế không thể sử dụng.

Ưu điểm của nó lại rất quan trọng. Vì vậy cần đưa ra 1 cấu trúc dữ liệu khác có đặc tính giống cây cân bằng hoàn toàn.

6.2. Cây nhị phân cân bằng.

6.2.1. Định nghĩa.

Cây nhị phân tìm kiếm cân bằng là cây mà tại mỗi nút của nó độ cao của cây con trái và của cây con phải chênh lệch không quá một.

Ví dụ:

103

7

15

9

13

23

20

15

9

137

23

20

8

Page 104: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

6.2.2. Các trường hợp mất cân bằng.

Trường hợp 1: Cây T lệch về bên trái (có 3 khả năng).

- Lệch bên trái của cây con trái (LL):

- Lệch bên phải của cây con trái (LR):

Cây con trái không lệch (LB):

Trường hợp 2: Cây R lệch về bên phải (có 3 khả năng).

- Lệch bên trái của cây con phải (RL):

104

L1 R1h h-1

R h-1

T

T1

L1 R1h-1 h

Rh-1

T

T1

L1 R1h h

Rh-1

T

T1

h h-1L1 R1

L h-1

T

T1

Page 105: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

- Lệch bên phải của cây con phải (RR):

- Cây con phải cân bằng (RB):

6.2.3. Các thao tác cân bằng lại cây.

Tại nút T không cân bằng. Ta phải giải quyết 2 trường hợp sau:

Trường hợp 1:

Cân bằng lại LL:

105

L1 R1h-1 h

Lh-1

T

T1

L1 R1h h

Lh-1

T

T1

LL

L1 R1h h-1

R h-1

h-1R1 R h-1

L1h

Tleft=T1right;(1)T1right=T;(2)

(1)

(2) T

T1

T1

T

Page 106: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Cân bằng lại LR:

106

L1 R1h-1 h

Rh-1

L1

L2

h-1

h-1

Rh-1

R2h-1

(1)

(2)

T

T1

T

T1

T2

RR

R2

L1

h-1

h-1

Rh-1

L2h-1

T1right=T2left;(1)T2left=T1;(2)

(1)

(2) T

T2

T1

Tleft=T2right;(1)T2right=T;(2)

RL1h-1h-1 R2

h-1L2

h-1

LL

T2

TT1

Page 107: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Cân bằng lại LB:

Trường hợp 2:

Cân bằng lại RL:

107

LL

L1 R1h h

Rh-1

h-1R1 R h-1

L1h

Tleft=T1right;(1)T1right=T;(2)

(1)

(2) T

T1

T1

T

h h-1L1 R1

Lh-1

h-1

h-1

L2

R1

Lh-1

h-1R2

(1)

(2)

T

T1

T

T1

T2

T1left=T2right;(1)T2right=T1;(2)

LL

h-1

h-1

R2

L2

L h-1

h-1R1

(1)

(2)

T

T2

T1

Page 108: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Cân bằng lại RR:

Cân bằng lại RB:

Chỉ số cân bằng của một nút.

Định nghĩa: Chỉ số cân bằng của một nút là hiệu của chiều cao cây con phải và cây con trái của nó.

Đối với cây cân bằng chỉ số cân bằng (CSCB) của mỗi nút chỉ có thể mang một trong 3 giá trị sau:

108

Tright=T2left;(1)T1left=T;(2)

RR

h-1h-1 R2L L2h-1 h-1R1

T2

T T1

L1 R1h-1 h

L h-1

RRR

R1

L L1h-1 h-1

h

Tright=T1left;(1)T1left=T;(2)

(2)

(1)T

T1

T1

T

L1 R1h h

Lh-1

RRR

R1

L L1h-1 h

h

Tright=T1left;(1)

T1left=T;(2)

(1)

(2)

T

T1

T1

T

Page 109: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

CSCB(p)=0 Độ cao cây con trái (p) = Độ cao cây con phải (p).

CSCB(p)=-1 Độ cao cây con trái (p) > Độ cao cây con phải (p).

CSCB(p)=1 Độ cao cây con trái (p) < Độ cao cây con phải (p).

Ví dụ: Cho cây sau:

Xét nút p có giá trị 9, ta có hệ số cân bằng của nút p: CSCB(p)=-1.

Cài đặt

#define LH -1 //lech trai

#define EH 0 //can bang

#define RH 1 //lech phai

typedef struct tagAVLnode{

int key;int bal;struct tagAVLnode *left;struct tagAVLnode *right;

}AVLnode;

void LL(AVLnode* &T){

AVLnode *T1=Tleft;Tleft=T1right;T1right=T;switch(T1bal){

case LH: //cây T1 lệch trái

Tbal=EH;

109

15

9

137

23

20

8

Page 110: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

T1bal=EH;break;

case EH: //cây T1 cân bằng

Tbal=LH;T1bal=RH;break;

}T=T1;

}

void RR(AVLnode* &T){

AVLnode *T1;T1=Tright;Tright=T1left;T1left=T;switch(T1bal){

case RH: //cây T1 lệch phải

Tbal=EH;T1bal=EH;break;

case EH: //cây T1 cân bằng

Tbal=RH;T1bal=LH;break;

}T=T1;

}

void LR(AVLnode* &T){

AVLnode *T1=Tleft;AVLnode *T2=T1right;T1right=T2left;T2left=T1;Tleft=T2right;T2right=T;switch(T2bal){

Case LH:Tbal=RH;T1bal=EH;break;

case EH:Tbal=EH;T1bal=EH;break;

110

Page 111: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

case RH:Tbal=EH;T1bal=LH;break;

}T2bal=EH;T=T2;

}

void RL(AVLnode* &T){

AVLnode *T1;T1=Tright;AVLnode *T2=T1left;T1left=T2right;T2right=T1;Tright=T2left;T2left=T;switch(T2bal){

case RH:Tbal=LH;T1bal=EH;break;

case EH:Tbal=EH;T1bal=EH;break;

case LH :Tbal=EH;T1bal=RH;break;

}T2bal=EH;T=T2;

}

int balance_left(AVLnode* &T) //khi cây T lệch bên trái cần phải cân bằng

{AVLnode *T1=Tleft;switch(T1bal){

case LH:LL(T);return 2;

case EH:LL(T);return 1;

111

Page 112: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

case RH:LR(T);return 2;

}return 0; //truong balance bị sai

}

int balance_right(AVLnode* &T) //khi cây T lệch bên phải cần phải cân bằng

{AVLnode *T1=Tright;switch(T1bal){

case LH:RL(T);return 2;

case EH:RR(T);return 1;

case RH:RR(T);return 2;

}return 0;

}

6.2.4. Thêm và hủy 1 phần tử trên cây AVL.

Thêm một nút.

Ví dụ: Cho cây sau:

Thêm nút p có giá trị 10 vào cây. Thực hiện như sau:

112

15

11

136

23

20

84

Page 113: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Cây bị mất cân bằng (LR) tại nút có giá trị 11 cần phải cân bằng lại:

113

15

11

136

23

20

84

10

Kết quả thực hiện RR

15

11

138

23

20

106

4

RR

(1)

(2)

15

11

136

23

20

4

10

8

Page 114: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Vậy cây đã được cân bằng sau khi sắp xếp.

Cài đặt.

int insertNode(AVLnode* &T,int x){

int res;if(T){

if(Tkey==x)return 0;//da co

if(Tkey>x){

res=insertNode(Tleft,x);if(res<2) return res;switch(Tbal){

case RH:Tbal=EH;

114

LL (1)

(2)

15

11

138

23

20

106

4

Kết qủa thực hiện LL

15

11

13

8 23

20

10

6

4

Page 115: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

return 1;case EH:

Tbal=LH;return 2;

case LH:balance_left(T);return 1;

}}else{

res=insertNode(Tright,x);if(res<2) return res;switch(Tbal){

case LH:Tbal=EH;return 1;

case EH:Tbal=RH;return 2;

case RH:balance_right(T);return 1;

}}

}T=(AVLnode *)new AVLnode;if(T==NULL) return -1; //khong du vung nho

Tkey=x;Tbal=EH;Tleft=Tright=NULL;return 2;

}

Hủy một nút.

Ví dụ: Cho cây cân bằng sau:

115

15

11

136

23

20

84

Page 116: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Huỷ phần tử có giá trị 23. Ta thực hiện như sau:

Cây bị mất cân bằng (LL) tại nút có giá trị 15 cần phải cân bằng lại:

116

15

11

136

20

84

LL (2)

(1)15

11

136

20

84Kết quả thực hiện LL

15

11

13

6

2084

Page 117: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Vậy cây đã cân bằng sau khi xoá 1 nút.

Cài đặt.

int SearchStandFor(AVLnode* &p,AVLnode* &q){

int res;if(qleft){

res=SearchStandFor(p,qleft);if(res<2) return res;switch(qbal){

case LH:qbal=EH;return 2;

case EH:qbal=RH;return 1;

case RH:return balance_right(q);

}}else{

pkey=qkey;p=q;q=qright;

}return 2;

}

int DelNode(AVLnode* &T,int x){

int res;if(T==NULL) return 0;if(Tkey>x){

res=DelNode(Tleft,x);if(res<2) return res;switch(Tbal){

case LH:Tbal=EH;return 2;

117

Page 118: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

case EH:Tbal=RH;return 1;

case RH:return balance_right(T);

}}if(Tkey<x){

res=DelNode(Tright,x);if(res<2) return res;switch(Tbal){

case RH:Tbal=EH;return 2;

case EH:Tbal=LH;return 1;

case LH:return balance_left(T);

}}else{

AVLnode *p=T;if(Tleft==NULL){

T=Tright;res=2;

}else{

if(Tright==NULL){

T=Tleft;res=2;

}else{

res=SearchStandFor(p,Tright);if(res<2) return res;switch(Tbal){

case RH:Tbal=EH;return 2;

case EH:Tbal=LH;return 1;

118

Page 119: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

case LH:return balance_left(T);

}}

}delete p;return res;

}return res;

}

6.2.5. Tạo cây nhị phân cân bằng AVL.

Ví dụ:

Tạo cây với danh sách sau:

Tạo cây rỗng:

Thêm nút có giá trị 5 vào cây:

Thêm nút có giá trị 8 vào cây:

119

5 8 7 2 4

NULL

T

5

T

8

5

T

Page 120: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Thêm nút có giá trị 7 vào cây:

Cây bị mất cân bằng (RL) tại nút có giá trị 5 cần phải cân bằng lại:

Thêm nút có giá trị 2 vào cây:

120

7

8

5

T

LL Kết quả thực hiện LL

8

7

5

7

8

5

T

1

T

RR Kết quả thực hiện LL

1

8

7

5

T

5 8

7

T

5

2

8

7

T

Page 121: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

Thêm nút có giá trị 4 vào cây:

Cài đặt.

void createTree(AVLnode* &T,int n){

int i=1;int x,res;do{

printf(“Tạo nút %d có giá trị:”,i);scanf(“%d”,&x);res=insertNode(T,x);if(res==0) i--;i++;

}while(i<=n);}

6.3. Nhận xét.

Thao tác thêm một nút có độ phức tạp O(1).

Thao tác hủy 1 nút có độ phức tạp O(h).

Độ dài đườc tìm kiếm trung bình trong cây cân bằng gần bằng O(log2(n)).

Cây nhị phân tìm kiếm cân bằng (AVL) đảm bảo các thao tác tìm kiếm tốt thay thế cây nhị phân tìm kiếm. Nhưng nó có cái giá phải trả là đôi khi xuất hiện nhu cầu cân bằng lại.

7. Bài tập.

121

4

5

2

8

7

T

Page 122: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

7.1. Lý thuyết.

33. Nắm được các thao tác duyệt trên cây. Ứng dụng xóa cây được thực hiện theo thứ tự nào.

34. Đặc điểm của cây nhị phân tìm kiếm. Thao tác nào thực hiện tốt trong cây nhị phân tìm kiếm. Hạn chế của cây nhị phân tìm kiếm là gì?

35. Xét giải thuật tạo cây nhị phân tìm kiếm. nếu thứ tự các khóa nhập vào là như sau:

7 1 13 11 14 3 -4 8 5 9.

thì hình ảnh cây tạo được như thế nào?

Sau đó hủy lần lượt các nút theo thứ tự: 3, 7 thì cây sẽ thay đổi như thế nào trong từng bước hủy.

36. Áp dụng giải thuật tạo cây nhị phân tìm kiếm cân bằng để tạo cây với khóa nhập vào là như sau:

7 1 13 10 14 17 11 8 12 16.

thì hình ảnh cây tạo được như thế nào? Lưu ý vẽ hình minh họa khi thêm từng khóa vào cây.

Sau đó, nếu hủy lần lượt các nút theo thứ tự như sau: 1, 8, 12 thì cây thay đổi như thế nào trong từng bước hủy, vẽ sơ đồ và giải thích.

7.2. Thực hành.

37. Cài đặt tất cả các thao tác đã học trên cây nhị phân tìm kiếm, cây nhị phân cân bằng.

38. Viết các hàm xác định các thông tin của cây nhị phân T:

Đếm số nút lá.

Đếm số nút trong cây.

Tìm chiều cao của cây.

In ra tất cả các nút ở mức thứ k của cây T.

Cho biết thông tin nút nào có chiều cao lớn nhất.

122

Page 123: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Chương 4: Cây

39. Xây dựng cấu trúc dữ liệu biểu diễn cây n-phân (2 < n < 10). Viết chương trình con duyệt cây n-phân.

40. Giả sử a là 1 mảng các số thực đã có thứ tự tăng. Hãy viết hàm tạo 1 cây nhị phân tìm kiếm có chiều cao thấp nhất từ các phần tử của a.

41. Viết chương trình con đảo nhánh (nút trái và nút phải của 1 nút cha bất kỳ trên cây được đảo cho nhau) 1 cây nhị phân.

42. Cài đặt chương trình mô phỏng trực quan các thao tác trên cây nhị phân tìm kiếm.

43. Cài đặt chương trình mô phỏng trực quan các thao tác trên cây AVL.

44. Viết chương trình cho phép tạo, tra cứu và sữa chữa từ điển anh-việt.

123

Page 124: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

PHỤ LỤC

1. Sinh dữ liệu vào / ra.

1.1. Các phương pháp sinh dữ liệu vào / ra:

Hầu hết các bài toán trong tin học đều đòi hỏi dữ liệu vào và ra. Người ta thường dùng ba phương pháp sinh và nạp sau đây:

Nạp dữ liệu trực tiếp từ bàn phím. Phương pháp này được dùng khi có dữ liệu nhập ít.

Sinh dữ liệu thông qua hàm random. Phương thức này nhanh chóng và tiện lợi, nếu khéo tổ chức có thể sinh ngẫu nhiên được các dữ liệu đáp ứng một số điều kiện định trước.

Đọc dữ liệu từ một tập tin. Phương thức này khá tiện lợi khi phải chuẩn bị trước những dữ liệu phức tạp. Kết quả thực hiện chương trình cũng thường được thông báo trực tiếp trên màn hình hoặc ghi vào tập tin văn bản.

1.2. Bài tập

1. Sinh ngẫu nhiên một mảng a gồm n số nguyên nằm trong khoảng ,k>0.

2. Sinh ngẫu nhiên một mảng a gồm n số nguyên được sắp không giảm.

3. Sinh ngẫu nhiên một mảng a gồm n số nguyên sao cho phần tử sau luôn là bội số của phần tử trước.

4. Sinh ngẫu nhiên một mảng hai chiều a[m][n] gồm các số nguyên sao cho các phần tử đối xứng qua đường chéo chính, tức là a[i][j]=a[j][i].

5. Độ cao của một số tự nhiên là tổng các chữ số của số đó. Phát sinh các số tự nhiên có tối đa 3 chữ số và có độ cao h cho trước và ghi kết quả vào một tập tin văn bản có tên cho trước.

6. Một tập tin văn bản fn có ghi sơ đồ của một vùng biển hình chữ nhật chiều ngang 250 kí tự, chiều dài không hạn chế. Trên biển có các con tàu hình chữ nhật chứa các kí tự 1, vùng nước được biểu thị qua các dấu cách. Biết rằng các con tàu không dính nhau, hãy đếm số lượng tàu.

2. Các bước để giải bài toán tin học.

124

Page 125: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

Bước đầu tiên là bước quan trọng nhất là hiểu rõ nội dung của bài toán. Để hiểu rõ bài toán theo cách tiếp cận tin học ta phải gắng xây dựng một số thí dụ phản ánh đúng các yêu cầu đề ra của đầu bài rồi thử giải các thí dụ đó để hình thành dần những hướng đi của thuật toán.

Bước thứ hai là dùng một ngôn ngữ quen thuộc, tốt nhất là ngôn ngữ toán học đặc tả các đối tượng cần xử lý ở mức độ trừu tượng, lập các tương quan, xây dựng các hệ thức thể hiện các qua hệ giữa các đại lượng cần xử lý.

Bước thứ ba là xác định cấu trúc dữ liệu để biểu diễn các đối tượng cần xử lý cho phù hợp với các thao tác của thuật toán. Trong những bước tiếp theo ta tiếp tục làm mịn dần các đặc tả theo trình tự từ trên xuống, từ trừu tượng hóa đến cụ thể, từ đại thể đến chi tiết.

Bước cuối cùng là sử dụng ngôn ngữ lập trình đã chọn để viết chương trình cho hoàn chỉnh. Ở bước này ta dùng kỹ thuật đi từ dưới lên, từ những thao tác nhỏ đến những thao tác tổ hợp.

Sau khi nhận được chương trình ta cho chương trình chạy thử với các dữ liệu lấy từ các thí dụ đã xây dựng ở bước đầu tiên. Cuối cùng là việc xây dựng thủ tục một cách khoa học và có chủ đích nhằm kiểm tra tính tin cậy của chương trình thu được và thực hiện một số cải tiến.

Ví dụ: Tìm tất cả các cặp số có 2 chữ số sao cho chúng là 2 số nguyên tố cùng nhau.

Hiểu đầu bài: Ta kí hiệu (a,b) là ước chung lớn nhất (UCLN) của hai số tự nhiên a và b. Khi đó ta có một số ví dụ như sau :

(23, 21) = 1, vậy (23, 21) là cặp số có 2 chữ số cần tìm.

(21, 14) = 7, vậy (21, 14) không là cặp số có 2 chữ số cần tìm.

Đặc tả: gọi số có 2 chữ số lần lượt là a, b.

Ta đã có thuật toán euclid để tìm cặp số nguyên tố cùng nhau.

Bước 1: Ta có a, b,.và .

Bước 2: sau đó: a := b; b := r.

Bước 3: nếu r != 0 thì lặp lại bước 1.

ngược lại dừng. Nếu b = 1 thì 1 cặp số trên là nguyên tố cùng nhau. Ngược lại thì cặp số trên không là nguyên tố cùng nhau.

125

Page 126: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

Biểu diễn dữ liệu ta dùng 2 số nguyên để biểu số cặp số trên, và 1 số nguyên để lưu trữ phần dư khi chia a cho b.

int a, b, r;

Viết chương trình

int SNTcungnhau(int a,int b){

int r=a mod b;while(r){

a=b;b=r;

}return b;

}

Bài tập.

1. Tìm các số tự nhiên lẻ có ba chữ số. Ba chữ số này theo trật tự viết từ trái qua phải tạo thành một cấp số cộng.

2. Tìm các số tự nhiên có ba chữ số. Ba chữ số này theo trật tự viết từ trái qua phải tạo thành một cấp số nhân.

3. Phát sinh ngẫu nhiên n số nguyên không âm cho mảng nguyên a.

4. Tìm cách chia mảng a gồm n số nguyên dương cho trước thành hai đoạn có tổng các phần tử trong mỗi đoạn bằng nhau.

5. Tìm cách chia mảng a gồm n số nguyên dương cho trước thành hai đoạn có tổng các phần tử trong đoạn này gấp k lần tổng các phần tử trong đọan kia, k nguyên dương.

3. Đệ quy.

3.1. Khái niệm đệ quy.

Một khái niệm X có tính đệ quy nếu trong định nghĩa của X có sử dụng ngay chính khái niệm X.

Ví dụ:

Phép cộng dồn có tính đệ quyi=0;i=i+1;

Phép tính giai thừa có tính đệ quy1!=1;

126

Page 127: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

n!=n*(n–1)!;

function có thể có lời gọi của chính nó. Tính chất này được gọi là tính đệ quy.

Ví dụ:

int GiaiThua(int n){

if(n=0) return 1;else return n*GiaiThua(n–1);

}

3.2. Nhận xét.

Ưu điểm: dùng đệ quy sẽ làm cho chương trình ngắn ngọn, phương pháp giải quyết bài toán trở nên đơn giản.

Nhược điểm: có thể tốn bộ nhớ và thời gian nhiều hơn so với cách không dùng đệ quy.

3.3. Bài tập.

1. Lập chương trình tính 100!

2. Lập chương trình tính 750.

3. Đếm số con tàu trên biển.

Ví dụ: Cho ma trận sau:

những số 1 đứng kề nhau gộp lại là 1 con tàu. Vậy ma trận trên có tới 5 con tàu. (như hình bên).

4. Bài toán tháp Hà nội.

Cho 3 cọc và n đĩa ( lồng vào cọc) đặt ở cọc số 1 và theo thứ tự to dưới nhỏ trên. Hãy chuyển n đĩa đó sang cọc số 3 sao cho thứ tụ vẫn được bảo toàn. Được sử dụng cọc số 2 để làm trung gian và thỏa mãn yêu cầu khi chuyển đĩa bé được đặt trên đĩa to. Mỗi lần được chuyển một đĩa. Hãy lập chương trình mô tả bài toán đó.

4. Khử đệ quy.

127

Page 128: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

Là việc thay vì viết hàm đệ quy ta sẽ viết hàm đó thành hàm không đệ quy.

Ví dụ: Tính giai thừa của 1 số n nguyên bất kỳ.

int GiaiThua(int n){

long s=1;for(int i=1;i<=n;i++) s=s*i;return s;

}

Bài tập.

1. Coi lại phần tìm 1 nút trên cây nhị phân tìm kiếm có hàm viết khử đệ qui.

2. Khử đệ quy của hàm in các nút trên cây theo thứ tự NLR, LNR, LRN. (gợi ý sử dụng Stack và Queue).

5. Khử đệ quy đuôi.

Là quá trình khử lời gọi hàm đệ quy cuối của hàm đệ quy.

Ví dụ: in ra các nút trên cây theo thứ tự NLR.

Hàm đệ quy:

void NLR(Node *root){

if(root!=NULL){

printf(“%d”,rootkey);NLR(rootleft);NLR(rootright);

}}

Hàm khử đệ quy đuôi:

void NLR(Node *root){

while(root!=NULL){

printf(“%d”,rootkey);NLR(rootleft);root=rootright;

}}

Bài tập.

128

Page 129: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

1. Viết hàm khử đệ quy đuôi của việc in ra các nút trên cây theo LNR, LRN.

2. Khử đệ quy đuôi của bài toán tháp Hà Nội.

6. Hướng dẫn sử dụng phần mềm môn học cấu trúc dữ liệu.

6.1. Hướng dẫn cài đặt phần mềm.

Để cài đặt chương trình, chạy file setup.exe.

Sau khi đã cài đặt chương trình vào máy, chép thư mục image vào nơi cài đặt.

Để chạy được chương trình ta chạy file DataStructure.exe.

6.2. Cách sử dụng.

Các chức năng chính: thêm, xoá, sửa, tìm kiếm, sắp xếp trên mảng và danh sách liên kết.

Chạy demo giúp người dùng có thể hiểu được các thuật toán sau:

BubbleSort.

IntersectionSort.

HeapSort.

MergeSort.

QuichSort.

Tìm kiếm tuyến tính.

Tìm kiếm nhị phân.

Các thao tác trên danh sách liên kết.

6.3. Hình ảnh một số thuật toán.

BubbleSort.

129

Page 130: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

Các thao tác chính trên bubbleSort gồm: phát sinh số ngẫu nhiên, nhập số, chạy chương trình.

IntersectionSort.

Các thao tác chính trên insertionSort gồm: phát sinh số ngẫu nhiên, nhập số, chạy chương trình.

HeapSort.

130

Page 131: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

Các thao tác chính trên HeapSort gồm: phát sinh số ngẫu nhiên, nhập số, chạy chương trình.

MergeSort.

Các thao tác chính trên MergeSort gồm: phát sinh số ngẫu nhiên, nhập số, chạy chương trình.

QuichSort.

131

Page 132: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

Các thao tác chính trên QuickSort gồm: phát sinh số ngẫu nhiên, nhập số, chạy chương trình.

Tìm kiếm tuyến tính.

Các thao tác chính trên tìm kiếm tuyến tính gồm: phát sinh số ngẫu nhiên, nhập số, nhập phần tử cần tìm, chạy chương trình.

Tìm kiếm nhị phân.

132

Page 133: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Phụ lục

Các thao tác chính trên tìm kiếm nhị phân gồm: phát sinh số ngẫu nhiên, nhập số, nhập phần tử cần tìm, chạy chương trình.

Các thao tác trên danh sách liên kết.

Các thao tác chính trên danh sách liên kết gồm: có mục tuỳ chọn trong mục này có các thao tác thêm, xoá, sửa danh sách, chạy chương trình.

133

Page 134: data struct · Web viewTrong trường hợp chọn dãy có độ dài theo công thức hi=hi-1+2 và h1=1 và i€[1,k], với k=log2(n)-1 thì giải thuật có độ phức tạp

Tài Liệu Tham Khảo

TÀI LIỆU THAM KHẢO.

[1]. Tác giả Khoa CNTT, Cấu trúc dữ liệu,Trường CDCNTP TP.HCM, 2003.

[2]. Tác giả Đỗ Xuân Lôi, Cấu trúc dữ liệu và giải thuật, NXB Khoa học kỹ thuật, 1996.

[3]. Tác giả Trần Hạnh Nhi và Dương Anh Đức, Nhập môn cấu trúc dữ liệu và thuật toán.

[4]. Tác giả Nguyễn Trung Trực, Cấu trúc dữ liệu. Đại học bách khoa TP. HCM.

[5]. Tác giả Nguyễn Hồng Chương, Cấu trúc dữ liệu ứng dụng và đặt bằng C, Nhà xuất bản Thành phố Hồ Chí Minh, 2003.

[6]. Tác giả Nguyễn Việt Hương, Ngôn ngữ lập trình C++ và cấu trúc dữ liệu, Nhà xuất bản Giáo Dục, 2000.

[7]. Tác giả Robert Sedgewick, Cẩm nang thuật toán (bản dịch),

[8]. Tác giả MARK ALLEN WEISS, Data Structures and Algorithm Analysis, InC. The Benjamin/Cummings Publishing Company, 1993.

[9]. William J.Collins, Data Structures an object Oriented Approach, Addison Wesley, 1992.

[10]. Handbook of Algorithms and Data Structures, Informatik, ETH Zurich, 1999. Gaston H.Gonnet.[11]. Tác giả N. Width, Datastruct & Algorithm = Programs.

134