- Ý nghĩa và vai trò cąa mô đun: Mục tiêu của mô đun: - VÁ ki¿n thức: - Trình bày đ°āc mßi quan hÉ giāa cÃu trúc dā liÉu và giÁi thuÁt trong viÉc xây dăng ch°¢ng trình; - Trình bày đ°āc
T Ĉ BÀI TOÁN ĐÀN CH¯¡NG TRÌNH
Modul hóa viÉc giÁi quyÁt bài toán
Giải thuật hay thuật toán là phương pháp hoặc kỹ thuật dùng để giải quyết vấn đề Giải thuật có thể được minh họa bằng ngôn ngữ tự nhiên, sơ đồ dòng chảy hoặc mô tả giả Trong thực tế, giải thuật thường được minh họa hoặc thể hiện bằng mô tả giả trên một hay một số ngôn ngữ lập trình nhất định (thường là ngôn ngữ mà người lập trình chọn để cài đặt thuật toán), chẳng hạn như C, Pascal, v.v.
Ph°Âng phỏp tinh chònh tĉng b°óc
Khi thiết kế một cấu trúc dữ liệu phù hợp, lập trình viên sẽ bắt đầu xây dựng thuật toán giải quyết yêu cầu bài toán dựa trên cấu trúc dữ liệu đã chọn Để giải quyết một vấn đề có thể có nhiều phương pháp, do đó việc lựa chọn phương pháp phù hợp là công việc mà lập trình viên phải cân nhắc và tính toán kỹ Việc lựa chọn này cũng có thể góp phần đáng kể trong việc giảm bớt công việc của lập trình viên trong phần cài đặt thuật toán trên một ngôn ngữ cụ thể.
Mòi quan hẫ giāa cÃu trỳc dā liẫu và GiÁi thuÁt cú thÅ minh hóa bằng đẳng thćc:
CÃu trúc dā liÉu + GiÁi thuÁt = Ch°¢ng trình
Nh° vÁy, khi đó cú cÃu trỳc dā liẫu tòt, nÃm vāng giÁi thuÁt thăc hiẫn thỡ viẫc thÅ hiẫn ch°Âng trỡnh bằng mỏt ngụn ngā că thÅ chò là vÃn đà thồi gian Khi cú cÃu trúc dā liÉu mà ch°a tìm ra thuÁt giÁi thì không thÅ có ch°¢ng trình và ng°āc l¿i không thÅ có ThuÁt giÁi khi ch°a có cÃu trúc dā liÉu Mát ch°¢ng trình máy tính chò cú thÅđ°āc hoàn thiẫn khi cú đầy đą cÁ CÃu trỳc dā liẫu đÅ l°u trā dā liẫu và GiÁi thuÁt xÿ lý dā liÉu theo yêu cầu cąa bài toán đặt ra
3 Đò phức t¿p tớnh toỏn của giÁi thu¿t
3.1 Khái niÉm: Đỏ phćc t¿p thồi gian là toàn bỏ tài nguyờn và thồi gian mà mỏy tớnh cần đÅ thăc thi mỏt thuÁt toỏn nào đú, đ°āc thÅ hiẫn bằng hàm sò y = f\left ( x \right ) Thụng th°ồng, đỏ phćc t¿p thồi gian s¿ dăa vào sò lần mà mỏt cõu lẫnh c bÁn vói thồi gian thăc thi là hằng sò đ°āc thăc thi Chỳng ta s¿ tỡm hiÅu rừ hÂn qua vớ dă ỗ cỏc phần sau Đòi vói mỏt ch°Âng trỡnh, s¿ cú hai lo¿i đỏ phćc t¿p là đỏ phćc t¿p thồi gian và đá phćc t¿p bá nhã Tuy nhiên, trong khoá hãc này, mình s¿ chą yÁu đà cÁp đÁn đá phćc t¿p thồi gian Do đú, khi mỡnh núi = 1 và 0! = 1
#include void main(void)
{ int in; long giaithua(int); printf("Nhap vao so n: "); scanf("%d", &in); printf("%d! = %ld.\n", in, giaithua(in)); getch();
13 int i; long ltich = 1; if (in == 0) return (1L); else { for (i = 1; i info) return t; else if (x < t->info) return TimCayNPTK2(t->pLeft, x); else return TimCayNPTK2(t->pRight, x);
Thêm phần tÿ mãi vào cây nhá phân tìm kiÁm
Yêu cầu: Phần tÿ mãi thêm vào phÁi bÁo đÁm tính chÃt cąa cây nhá phân tìm kiÁm
Vớ dă: thờm sò nỳt vào cõy
Cách thăc hiÉn: thêm giá trá X vào cây
GiÁ sÿ X đã tán t¿i trong cây, nh° vÁy X phÁi có mát nút cha p, tìm nút cha này
T¿o mỏt nỳt t cú giỏ trỏ là X và cho con trồ bờn trỏi hay bờn phÁi cąa nỳt cha p trồ tói nút t này int ChenNut(Tree *&t, int x)
{ if (t->info = x) return 0; // đã có if (t->info < x) return ChenNut(t->pLeft, x); else return ChenNut(t->pRight, x); } t= new Node; t->info= x; t->pLeft= t->pRight= NULL; return 1;
Xúa phần tÿ khồi cõy nhỏ phõn tỡm kiÁm
Yêu cầu: Khi xóa mát phần tÿ các phần tÿ còn l¿i cũng phÁi bÁo đÁm tính chÃt cąa cây nhá phân tìm kiÁm
Cú 3 tr°ồng hāp cąa nỳt cần xúa X:
Tr°ồng hāp 1: X là nỳt lỏ
Chò cần hąy múc nòi tĉ nỳt cha đÁn nỳt
X b) Tr°ồng hāp 2: X chò cú mỏt nỳt con
Cho nỳt cha cąa X chò đÁn nỳt con cąa X
37 c) Tr°ồng hāp 3: X cú hai nỳt con
Khụng thÅ xúa X và cho nỳt cha trồ đÁn 2 con cąa X đ°āc
Thay vì xóa X tìm nút Y thÁ m¿ng cho X
(Y chò cú tòi đa 1 nỳt con)
Xúa nỳt Y theo tr°ồng hāp 1 hay 2
Cú thÅ chón nỳt Y là nỳt nhồ
NhÃt trong cây con bên phÁi
Cąa X Nh° vÁy Y tòi đa chò cú
38 con int XoaNut(Tree &t, int x)
{ if (t== NULL) return 0; // không tìm thÃy nút x if (t->info < x) return XoaNut(t->pLeft, x); if (t->info > x) return XoaNut(t->pRight, x);
Node *p = t; if (p->pLeft== NULL) t = p->pRight; else if (p->pRight== NULL) t = p->pLeft; else { p = TimNutTheMang(p->pRight); t->info= p->info;
Node* tm; if (tr->pLeft== NULL){ tm = tr; tr= tr->pRight;
} tm= p; q->pLeft= p->pRight; } return tm;
Xóa toàn bá cây nhá phân
ViÉt xóa cây nhá phân đ°āc thăc hiÉn đÉ quy nh° sau:
Xóa cây con bên trái
Xóa cây con bên phÁi
Xúa nỳt gòc void XoaCay(Tree &t)
B ÀI TÀP
1.Trình bày thuÁt toán và cài đặt tÃt cÁ các thao tác trên cây nhá phân tỡm kiÁm, cõynhỏ phõn tỡm kiÁm cõn bằng trong tr°ồng hāp chÃp nhÁn să trùng khóa nhÁn diÉn cąa các nút trong cây?
Trình bày các thuật toán và cài đặt các thuật toán để thực hiện nhiệm vụ tìm kiếm nút cha của một nút trên cây nhị phân tìm kiếm có 02 cây con Đánh giá độ đơn giản của từng thuật toán và nêu nhận xét về từng thuật toán.
3 Trình bày và cài đặt tÃt cÁ các thuÁt toán đÅ thăc hiÉn các thao tác t rên cây nháphân tìm kiÁm, cây nhá phân tìm kiÁm cân bằng trong hai tr°ồng hāp: ChÃp nhÁn vàKhụng chÃp nhÁn să trựng lÃp và khúa cąa cỏc n út bằng cách không sÿ dăng thuÁt_toán đÉ quy (Trĉ các thao tác đã trình bày trong tài liÉu)?
4 Trình bày thuÁt toán và cài đặt ch°¢ng trình thăc hiÉn các công viÉc sau
40 trên cây nhá phân: a) Tớnh sò nỳt lỏ cąa cõy b) Tớnh sò nỳt trung gian cąa cõy c) Tớnh chiÃu dài đ°ồng đi tói mỏt nỳt cú khúa là K trờn cõy d) Cho biÁt cÃp cąa mát nút có khóa là K trên cây
6 Trình bày thuÁt toán và cài đặt ch°¢ng trình thăc hiÉn công viÉc t¿o cây nhá phân tìm kiÁm mà khóa cąa các nút là khóa cąa các nút trong mát danh sách liên kÁt đụi sao cho tòi °u húa bỏ nhó BiÁt rằng, danh sỏch liờn kÁt đụi ban đầu khụng cần thiÁt sau khi t¿o xong cây nhá phân tìm kiÁm và giÁ sÿ không cho phép să trùng khóa giāa các nút trong cây
Đảm bảo dữ liệu không bị mất sau khi tạo cây nhánh phân tìm kiếm bằng cách trích xuất các danh sách liên kết chứa nhiều trường dữ liệu giống nhau từ bài tập 8 ở trên.
8 Trình bày thuÁt toán và cài đặt ch°¢ng trình thăc hiÉn công viÉc chuyÅn cây nhỏ phõn tỡm kiÁm thành danh sỏch liờn kÁt đụi sao cho tòi °u húa bỏ nhó BiÁt rằng, cây nhá phân tìm kiÁm ban đầu không cần thiÁt Sau khi t¿o xong danh sách liên kÁt (ng°āc vãi yêu cầu trong bài tÁp 8)
CH¯ĂNG V Đõ THị VÀ MịT VÀI CÂU TRÚC PHI TUYắN
- Trình bày đ°āc khái niÉm đá thá, cây khung và giÁi thuÁt cây khung;
- Trình bày đặc điÅm cąa các cách biÅu diÇn đá thá;
- Phân biÉt đ°āc các lo¿i đá thá: Đá thá đánh h°ãng, đá thá không đánh h°ãng, đánh h°ãng liên thông và đánh h°ãng không liên thông;
- Trình bày đ°āc các phép duyÉt đá thá vãi các giÁi thuÁt minh hãa
- Phân biÉt đ°āc các phép tìm kiÁm theo chiÃu ráng và tìm kiÁm theo chiÃu sâu vãi các đá thá;
- Rốn luyẫn tớnh cẩn thÁn, tò mò, chớnh xỏc, sỏng t¿o, linh ho¿t trong cụng viẫc
1 Cỏc khỏi niỏm vÁ đó thò Đònh nghĩa 1: Mỏt đÂn đỏ thỏ G = (V, E) gỏm mỏt tÁp khỏc ròng V mà cỏc phần tÿ cąa nú gói là cỏc đònh và mỏt tÁp E mà cỏc phần tÿ cąa nú gói là cỏc c¿nh, đú là cỏc cặp khụng cú thć tă cąa cỏc đònh phõn biẫt Đònh nghĩa 2: Mỏt đa đỏ thỏ G = (V, E) gỏm mỏt tÁp khỏc ròng V mà cỏc phần tÿ cąa nú gói là cỏc đònh và mỏt hó E mà cỏc phần tÿ cąa nú gói là cỏc c¿nh, đú là cỏc cặp khụng cú thć tă cąa cỏc đònh phõn biẫt Hai c¿nh đ°āc gói là c¿nh bỏi hay song
41 song nÁu chỳng cựng t°Âng ćng vói mỏt cặp đònh Rừ ràng mòi đÂn đỏ thỏ là đa đỏ thỏ, nh°ng không phÁi đa đá thá nào cũng là đ¢n đá thá Đònh nghĩa 3: Mỏt giÁ đỏ thỏ G = (V, E) gỏm mỏt tÁp khỏc ròng V mà cỏc phần tÿ cąa nú gói là cỏc đònh và mỏt hó E mà cỏc phần tÿ cąa nú gói là cỏc c¿nh, đú là cỏc cặp khụng cú thć tă cąa cỏc đònh (khụng nhÃt thiÁt là phõn biẫt) Vói v∈V, nÁu
(v,v)∈E thỡ ta núi cú mỏt khuyờn t¿i đònh v
Tóm l¿i, giÁ đá thá là lo¿i đá thá vô h°ãng tổng quát nhÃt vì nó có thÅ chća các khuyên và các c¿nh bái Đa đá thá là lo¿i đá thá vô h°ãng có thÅ chća c¿nh bái nh°ng không thÅ có các khuyên, còn đ¢n đá thá là lo¿i đá thá vô h°ãng không chća c¿nh bái hoặc các khuyên Đònh nghĩa 4: Mỏt đỏ thỏ cú h°óng G = (V, E) gỏm mỏt tÁp khỏc ròng V mà cỏc phần tÿ cąa nú gói là cỏc đònh và mỏt tÁp E mà cỏc phần tÿ cąa nú gói là cỏc cung, đó là các cặp có thć tă cąa các phần tÿ thuác V Đònh nghĩa 5: Mỏt đa đỏ thỏ cú h°óng G = (V, E) gỏm mỏt tÁp khỏc ròng V mà cỏc phần tÿ cąa nú gói là cỏc đònh và mỏt hó E mà cỏc phần tÿ cąa nú gói là cỏc cung, đó là các cặp có thć tă cąa các phần tÿ thuác V Đá thá vô h°ãng nhÁn đ°āc tĉ đá thá cú h°óng G bằng cỏch xoỏ bồ cỏc chiÃu mũi tờn trờn cỏc cung đ°āc gói là đỏ thỏ vụ h°ãng nÃn cąa G
2.1 BiÅu diÇn bằng ma trÁn lân cÁn: Đánh nghĩa 6: Cho đá thá G=(V,E) (vô h°ãng hoặc có h°ãng), vãi V={v1,v2, , vn} Ma trÁn liÃn kà cąa G ćng vói thć tăcỏc đònh v1,v2, , vn là ma trÁn A= )( ),( a ,1
≤≤ njiij ∈ ZnM , trong đú aij là sò c¿nh hoặc cung nòi tĉ vi tói vj Nh° vÁy, ma trÁn liÃn kà cąa mỏt đỏ thỏ vụ h°óng là ma trÁn đòi xćng, nghĩa là , trong khi ma trÁn liÃn
42 kà cąa mỏt đỏ thỏ cú h°óng khụng cú tớnh đòi xćng = aa jiij
2.2BiÅu diÇn bằng danh sách lân cÁn
3 Phộp duyỏt mòt đó thò
3.1 Tìm kiÁm theo chiÃu sâu:
Tìm kiÁm °u tiên chiÃu sâu hay tìm kiÁm theo chiÃu sâu (tiÁng Anh: Depth-first search - DFS) là mát thuÁt toán duyÉt hoặc tìm kiÁm trên mát cây hoặc mát đá thá ThuÁt toỏn khỗi đầu t¿i gòc (hoặc chón mỏt đònh nào đú coi nh° gòc) và phỏt triÅn xa nhÃt cú thÅ theo mòi nhỏnh
Thụng th°ồng, DFS là mỏt d¿ng tỡm kiÁm thụng tin khụng đầy đą mà quỏ trỡnh tỡm kiÁm đ°āc phỏt triÅn tói đònh con đầu tiờn cąa nỳt đang tỡm kiÁm cho tói khi gặp đ°āc đònh cần tỡm hoặc tói mỏt nỳt khụng cú con Khi đú giÁi thuÁt quay lui và đònh vĉa mói tỡm kiÁm ỗ b°óc tr°óc Trong d¿ng khụng đẫ quy, tÃt cÁ cỏc đònh chồ đ°āc phát triÅn đ°āc bổ sung vào mát ngn xÁp LIFO Đá phćc t¿p không gian cąa DFS thÃp h¢n cąa BFS (tìm kiÁm theo chiÃu ráng) Đỏ phćc t¿p thồi gian cąa hai thuÁt toỏn là t°Âng đ°Âng nhau và bằng O(|V| + |E|)
3.2Tìm kiÁm theo chiÃu ráng:
Trong lý thuyÁt đỏ thỏ, tỡm ki¿m theo chiÁu ròng (BFS) là mỏt thuÁt toỏn tỡm kiÁm trong đỏ thỏ trong đú viẫc tỡm kiÁm chò bao gỏm 2 thao tỏc: (a) cho tr°óc mỏt đònh cąa đỏ thỏ; (b) thờm cỏc đònh kà vói đònh vĉa cho vào danh sỏch cú thÅ h°óng tói tiÁp theo Có thÅ sÿ dăng thuÁt toán tìm kiÁm theo chiÃu ráng cho hai măc đích: tìm kiÁm đ°ồng đi tĉ mỏt đònh gòc cho tr°óc tói mỏt đònh đớch, và tỡm kiÁm đ°ồng đi tĉ đònh gòc tói tÃt cÁ cỏc đònh khỏc Trong đỏ thỏ khụng cú tróng sò, thuÁt toỏn tỡm kiÁm theo chiÃu rỏng luụn tỡm ra đ°ồng đi ngÃn nhÃt cú thÅ ThuÁt toỏn BFS bÃt đầu tĉ đònh gòc và lần l°āt nhỡn cỏc đònh kà vói đònh gòc Sau đú, vói mòi đònh trong sò đú, thuÁt toỏn l¿i lần l°āt nhỡn tr°óc cỏc đònh kà vói nú mà ch°a đ°āc quan sỏt tr°óc đú và lặp l¿i Xem thêm thuÁt toán tìm kiÁm theo chiÃu sâu, trong đó cũng sÿ dăng 2 thao tác trờn nh°ng cú trỡnh tăquan sỏt cỏc đònh khỏc vói thuÁt toỏn tỡm kiÁm theo chiÃu rỏng
B IÄU DIặN Đà THà
BiÅu diÇn bằng ma trÁn lân cÁn
Đánh nghĩa 6: Cho đá thá G=(V,E) (vô h°ãng hoặc có h°ãng), vãi V={v1,v2, , vn} Ma trÁn liÃn kà cąa G ćng vói thć tăcỏc đònh v1,v2, , vn là ma trÁn A= )( ),( a ,1
≤≤ njiij ∈ ZnM , trong đú aij là sò c¿nh hoặc cung nòi tĉ vi tói vj Nh° vÁy, ma trÁn liÃn kà cąa mỏt đỏ thỏ vụ h°óng là ma trÁn đòi xćng, nghĩa là , trong khi ma trÁn liÃn
42 kà cąa mỏt đỏ thỏ cú h°óng khụng cú tớnh đòi xćng = aa jiij
P HÉP DUYÈT MàT Đà THà
Tìm kiÁm theo chiÃu sâu
Tìm kiÁm °u tiên chiÃu sâu hay tìm kiÁm theo chiÃu sâu (tiÁng Anh: Depth-first search - DFS) là mát thuÁt toán duyÉt hoặc tìm kiÁm trên mát cây hoặc mát đá thá ThuÁt toỏn khỗi đầu t¿i gòc (hoặc chón mỏt đònh nào đú coi nh° gòc) và phỏt triÅn xa nhÃt cú thÅ theo mòi nhỏnh
Thụng th°ồng, DFS là mỏt d¿ng tỡm kiÁm thụng tin khụng đầy đą mà quỏ trỡnh tỡm kiÁm đ°āc phỏt triÅn tói đònh con đầu tiờn cąa nỳt đang tỡm kiÁm cho tói khi gặp đ°āc đònh cần tỡm hoặc tói mỏt nỳt khụng cú con Khi đú giÁi thuÁt quay lui và đònh vĉa mói tỡm kiÁm ỗ b°óc tr°óc Trong d¿ng khụng đẫ quy, tÃt cÁ cỏc đònh chồ đ°āc phát triÅn đ°āc bổ sung vào mát ngn xÁp LIFO Đá phćc t¿p không gian cąa DFS thÃp h¢n cąa BFS (tìm kiÁm theo chiÃu ráng) Đỏ phćc t¿p thồi gian cąa hai thuÁt toỏn là t°Âng đ°Âng nhau và bằng O(|V| + |E|).
Tìm kiÁm theo chiÃu ráng
Trong lý thuyÁt đỏ thỏ, tỡm ki¿m theo chiÁu ròng (BFS) là mỏt thuÁt toỏn tỡm kiÁm trong đỏ thỏ trong đú viẫc tỡm kiÁm chò bao gỏm 2 thao tỏc: (a) cho tr°óc mỏt đònh cąa đỏ thỏ; (b) thờm cỏc đònh kà vói đònh vĉa cho vào danh sỏch cú thÅ h°óng tói tiÁp theo Có thÅ sÿ dăng thuÁt toán tìm kiÁm theo chiÃu ráng cho hai măc đích: tìm kiÁm đ°ồng đi tĉ mỏt đònh gòc cho tr°óc tói mỏt đònh đớch, và tỡm kiÁm đ°ồng đi tĉ đònh gòc tói tÃt cÁ cỏc đònh khỏc Trong đỏ thỏ khụng cú tróng sò, thuÁt toỏn tỡm kiÁm theo chiÃu rỏng luụn tỡm ra đ°ồng đi ngÃn nhÃt cú thÅ ThuÁt toỏn BFS bÃt đầu tĉ đònh gòc và lần l°āt nhỡn cỏc đònh kà vói đònh gòc Sau đú, vói mòi đònh trong sò đú, thuÁt toỏn l¿i lần l°āt nhỡn tr°óc cỏc đònh kà vói nú mà ch°a đ°āc quan sỏt tr°óc đú và lặp l¿i Xem thêm thuÁt toán tìm kiÁm theo chiÃu sâu, trong đó cũng sÿ dăng 2 thao tác trờn nh°ng cú trỡnh tăquan sỏt cỏc đònh khỏc vói thuÁt toỏn tỡm kiÁm theo chiÃu rỏng.
C ÂY KHUNG
GiÁi thuÁt Kruskal
ThuÁt toỏn s¿ xõy dăng tÁp c¿nh ET cąa cõy khung nhồ nhÃt T=(VT, ET) theo tĉng b°ãc Tr°ãc hÁt sÃp xÁp các c¿nh cąa đá thá G theo thć tă không giÁm cąa trãng sò BÃt đầu tĉ ET =A, ỗ mòi b°óc ta s¿ lần l°āt duyẫt trong danh sỏch c¿nh đó sÃp xÁp, tĉ c¿nh cú đỏ dài nhồ đÁn c¿nh cú đỏ dài lón hÂn, đÅ tỡm ra c¿nh mà viẫc bổ sung nú vào tÁp E T không t¿o thành chu trình trong tÁp này ThuÁt toán s¿ kÁt thúc khi ta thu đ°āc tÁp ET gám n-1 c¿nh Că thÅ có thÅ mô tÁ nh° sau:
1 BÃt đầu tĉ đỏ thỏ ròng T cú n đònh.
2 SÃp xÁp cỏc c¿nh cąa G theo thć tă khụng giÁm cąa tróng sò
3 BÃt đầu tĉ c¿nh đầu tiên cąa dãy này, ta cć thêm dần các c¿nh cąa dãy đã đ°āc xÁp vào T theo nguyên tÃc c¿nh thêm vào không đ°āc t¿o thành chu trình trong
4 Lặp l¿i B°óc 3 cho đÁn khi nào sò c¿nh trong T bằng n-1, ta thu đ°āc cõy khung nhồ nhÃt cần tỡm
Thớ dă 2: Tỡm cõy khung nhồ nhÃt cąa đỏ thỏ cho trong hỡnh d°ói đõy:
BÃt đầu tĉ đỏ thỏ ròng T cú 6 đònh
SÃp xÁp cỏc c¿nh cąa đỏ thỏ theo thć tă khụng giÁm cąa tróng sò:
Thêm vào đá thá T c¿nh (v3, v5)
Do số cạnh của T là 1 nên tiếp tục thêm cạnh (v4, v6) vào T Bây giờ số cạnh của T đã là 2 vẫn nhỏ hơn 6, ta tiếp tục thêm cạnh tiếp theo trong đóy đó sắp xếp vào T Sau khi thêm cạnh (v4, v5) vào T, nếu thêm cạnh (v5, v6) thì nó sẽ tạo thành với 2 cạnh (v4, v5), (v4, v6) đó có trong T một chu trình Tình huống tương tự cũng xảy ra đối với cạnh (v3, v4) là cạnh tiếp theo trong đóy Tiếp theo ta bổ sung cạnh (v1, v3), (v2, v3) vào T và thu được tập ET gồm 5 cạnh:
Tính đúng đÃn cąa thuÁt toán: Rõ ràng đá thá thu đ°āc theo thuÁt toán có n-1 c¿nh và không có chu trình Vì vÁy theo Đánh lý 6.1.3, nó là cây khung cąa đá thá G Nh° vÁy chò cũn phÁi chò ra rằng T cú đỏ dài nhồ nhÃt GiÁ sÿ tỏn t¿i cõy khung S cąa đá thá mà m(S) I; J ) if (M[J] < M[J-1])
Hàm Swap có prototype nh° sau: void Swap(T????X, T????Y);
Hàm thăc hiÉn viÉc hoán vá giá trá cąa hai phần tÿ X và Y cho nhau Nái dung cąa hàm nh° sau: void Swap(T????X, T????Y)
- Ví dă minh hãa thuÁt toán:
GiÁ sÿ ta cần sÃp xÁp mÁng M có 10 phần tÿ sau (N = 10):
Ta s¿ thăc hiÉn 9 lần đi (N - 1 = 10 - 1 = 9) đÅ sÃp xÁp mÁng M:
+ Trong mói tr°ồng hāp:
Sò phộp so sỏnh: S = (N-1) + (N-2) + ? + 1 = ẵN(N-1)
+ Trong tr°ồng hāp tòt nhÃt: khi mÁng ban đầu đó cú thć tă tng
Sò phộp hoỏn vỏ: Hmin = 0
+ Trong tr°ồng hāp xÃu nhÃt: khi mÁng ban đầu đó cú thć tă giÁm
Sò phộp hoỏn vỏ: Hmin = (N-1) + (N-2) + ? + 1 = ẵN(N-1)
+ Sò phộp hoỏn vỏ trung bỡnh: Havg = ẳN(N-1)
- NhÁn xét và thuÁt toán nổi bãt:
+ ThuÁt toán sÃp xÁp nổi bãt khá đ¢n giÁn, dÇ hiÅu và dÇ cài đặt
Trong thuật toán sắp xếp nổi bọt, mỗi lần duyệt từ cuối mảng về đầu mảng thì phần tử nhẹ được nổi lên rất nhanh trong khi đó phần tử nặng lại "chìm" xuống không thể tiếp tục di chuyển xuống (chỉ từ đầu mảng về cuối mảng).
+ ThuÁt toán nổi bãt không phát hiÉn ra đ°āc các đo¿n phần tÿ nằm hai đầu cąa mÁng đó nằm đỳng vỏ trớ đÅ cú thÅ giÁm bót quóng đ°ồng đi trong mòi lần
Khi sắp xếp tiền, cần chú ý đến mệnh giá, sắp xếp tiền theo thứ tự tiền nhỏ trước, tiền lớn sau để đảm bảo tính thuận tiện và chính xác khi đếm và sử dụng tiền.
Ph°Âng phỏp xÁp tiÃn là: lần l°āt ch ọ n ra cỏc tồ tiÃn tĉ nhồ đÁn lón đÅ xÁp cho đÁn khi hÁt xÃp tiÃn Đòi vói mÁng, cỏc b°óc thăc hiẫn là:
Trong N phần tÿ cąa mÁng, chãn phần tÿ bé nhÃt, chuyÅn lên đầu mÁng
Trong N-1 phần tÿ còn l¿i, chãn phần tÿ bé nhÃt, chuyÅn vào vá trí thć 2
TiÁp tăc cho đÁn khi sÃp xÁp hÁt
Giòng nh° cỏch xÁp bài khi đ°āc chia quõn bài
Quân bài mãi nhÁn đ°āc chèn vào nhāng quân bài đã có trên tay
Các quân bài trên tay luôn đ°āc sÃp xÁp
ThuÁt toán: void InsertionSort(int a[], int N)
Dùng giÁi pháp đÉ quy (chia đÅ trá)
Bước 1: Phân ho¿ch mÁng A ban đầu thành 2 mÁng con B và C sao cho bi c j
Bước 2: SÃp xÁp mÁng con B bằng đÉ quy
Bước 3: SÃp xÁp mÁng con C bằng đÉ quy ĐiÃu kiẫn dĉng: khi mÁng con cần sÃp chò cú 1 phần tÿ xem nh° đ°āc sÃp
Vì B, C đ°āc sÃp và bi c j nên mÁng A là đ°āc sÃp
Ph°¢ng pháp: Cũng sÿ dăng giÁi pháp chia đÅ trá
Bước 1: Chia mÁng A ban đầu thành 2 mÁng con B và C
Bước 2, 3: SÃp xÁp mÁng con B và C bằng đÉ quy (ĐiÃu kiÉn dĉng: khi mÁng con cần sÃp chò cú 1 phần tÿ)
Bước 4: Trán (merge) 2 mÁng con đã sÃp B, C thành mÁng A đ°āc sÃp
Thu¿t toán: int Partition(int a[], int p, int r)
} void QuickSort(int a[], int p, int r)
T ÌM KIÀM
Khái quát và tìm kiÁm
Trong thăc tÁ, khi thao tác, khai thác dā liÉu chúng ta hầu nh° lúc nào cũng phÁi thăc hiÉn thao tác tìm kiÁm ViÉc tìm kiÁm nhanh hay chÁm tùy thuác vào tr¿ng thái và trÁt tă cąa dā liÉu trên đó KÁt quÁ cąa viÉc tìm kiÁm có thÅ là không có (không tìm thÃy) hoặc có (tìm thÃy) NÁu kÁt quÁ tìm kiÁm là có tìm thÃy thì nhiÃu khi chỳng ta cũn phÁi xỏc đỏnh xem vỏ trớ cąa phần tÿ dā liẫu tỡm thÃy là ỗ đõu? Trong ph¿m vi cąa ch°Âng này chỳng ta tỡm cỏch giÁi quyÁt cỏc cõu hồi này
Tr°óc khi đi vào nghiờn cću chi tiÁt, chỳng ta giÁ sÿ rằng mòi phần tÿ dā liÉu đ°āc xem xét có mát thành phần khóa (Key) đÅ nhÁn diÉn, có kiÅu dā liÉu là
T nào đó, các thành phần còn l¿i là thông tin (Info) liên quan đÁn phần tÿ dā liẫu đú Nh° vÁy mòi phần tÿ dā liẫu cú cÃu trỳc dā liẫu nh° sau: typedef
Trong tài liẫu này, khi núi tói giỏ trỏ cąa mỏt phần tÿ dā liẫu chỳng ta muòn núi tãi giá trá khóa (Key) cąa phần tÿ dā liÉu đó ĐÅ đ¢n giÁn, chúng ta giÁ sÿ rằng mòi phần tÿ dā liẫu chò là thành phần khúa nhÁn diẫn
ViÉc tìm kiÁm mát phần tÿ có thÅ diÇn ra trên mát dãy/mÁng (tìm kiÁm nái) hoặc diần ra trờn mỏt tÁp tin/ file (tỡm kiÁm ngo¿i) Phần tÿ cần tỡm là phần tÿ cần thồa món điÃu kiẫn tỡm kiÁm (th°ồng cú giỏ trỏ bằng giỏ trỏ tỡm kiÁm) Tựy thuỏc vào tĉng bài toán că thÅ mà điÃu kiÉn tìm kiÁm có thÅ khác nhau song chung quy viÉc tỡm kiÁm dā liẫu th°ồng đ°āc vÁn dăng theo cỏc thuÁt toỏn trỡnh bày sau đõy.
Tìm tuần tă (Linear Search)
ThuÁt toán tìm tuyÁn tính còn đ°āc gãi là ThuÁt toán tìm kiÁm tuần tă (Sequential Search) a T° t°ỗng:
Lần l°āt so sánh các phần tÿ cąa mÁng M vãi giá trá X bÃt đầu tĉ phần tÿ đầu tiên cho đÁn khi tìm đÁn đ°āc phần tÿ có giá trá X hoặc đã duyÉt qua hÁt tÃt cÁ các phần tÿ cąa mÁng M thì kÁt thúc b ThuÁt toán:
//NÁu ch°a tìm thÃy và cũng ch°a duyÉt hÁt mÁng
Không tìm thÃy phần tÿ có giá trá X
B5: KÁt thúc c Cài đặt thuÁt toán:
Hàm LinearSearch có prototype: int LinearSearch (T M[], int N, T X);
Hàm thăc hiÉn viÉc tìm kiÁm phần tÿ có giá trá X trên mÁng M có N phần tÿ
Hàm trả về vị trí tương ứng của phần tử tìm thấy trong mảng, hoặc -1 nếu không tìm thấy Cú pháp của hàm như sau: int LinearSearch (T M[], int N, T X).
{ int k = 0; while (M[k] != X??? k < N) k++; if (k < N) return (k); return (-1);
- Tr°ồng hāp tòt nhÃt khi phần tÿđầu tiờn cąa mÁng cú giỏ trỏ bằng X:
Sò phộp so sỏnh: Smin = 2 + 1 = 3
- Tr°ồng hāp xÃu nhÃt khi khụng tỡm thÃy phần tÿ nào cú giỏ trỏ bằng X:
Sò phộp so sỏnh: Smax = 2N+1
Sò phộp so sỏnh: Savg = (3 + 2N + 1) : 2 = N + 2
Trong thuÁt toỏn trờn, ỗ mòi b°óc lặp chỳng ta cần phÁi thăc hiẫn 2 phộp so sánh đÅ kiÅm tra să tìm thÃy và kiÅm soát să hÁt mÁng trong quá trình duyÉt mÁng Chỳng ta cú thÅ giÁm bót 1 phộp so sỏnh nÁu chỳng ta thờm vào cuòi mÁng mỏt phần tÿ cầm canh (sentinel/stand by) có giá trá bằng X đÅ nhÁn diÉn ra să hÁt mÁng khi duyÉt mÁng, khi đó thuÁt toán này đ°āc cÁi tiÁn l¿i nh° sau:
//k = N song đú chò là phần tÿ cầm canh
Không tìm thÃy phần tÿ có giá trá X
Hàm LinearSearch đ°āc viÁt l¿i thành hàm LinearSearch1 nh° sau: int LinearSearch1 (T M[], int N, T X)
}? f Phân tích thuÁt toán cÁi tiÁn:
- Tr°ồng hāp tòt nhÃt khi phần tÿ đầu tiờn cąa mÁng cú giỏ trỏ bằng X:
Sò phộp so sỏnh: Smin = 1 + 1 = 2
- Tr°ồng hāp xÃu nhÃt khi khụng tỡm thÃy phần tÿ nào cú giỏ trỏ bằng X:
Sò phộp so sỏnh: Smax = (N+1) + 1 = N + 2
Sò phộp so sỏnh: Savg = (2 + N + 2) : 2 = N/2 + 2
- Nh° vÁy, nÁu thồi gian thăc hiẫn phộp gỏn khụng đỏng kÅ thỡ thuÁt toỏn cÁi tiÁn s¿ ch¿y nhanh h¢n thuÁt toán nguyên thąy.
Tìm nhá phân (Binary Search)
ThuÁt toỏn tỡm tuyÁn tớnh tồ ra đÂn giÁn và thuÁn tiẫn trong tr°ồng hāp sò phần tÿ cąa dóy khụng lón lÃm Tuy nhiờn, khi sò phần tÿ cąa dóy khỏ lón, chẳng h¿n chỳng ta tìm kiÁm tên mát khách hàng trong mát danh b¿ điÉn tho¿i cąa mát thành phò lón theo thuÁt toỏn tỡm tuần tă thỡ quÁ thăc mÃt rÃt nhiÃu thồi gian Trong thăc tÁ, thụng th°ồng cỏc phần tÿ cąa dóy đó cú mỏt thć tă, do vÁy thuÁt toỏn tỡm nhỏ phõn sau đõy s¿ rỳt ngÃn đỏng kÅ thồi gian tỡm kiÁm trờn dóy đó cú thć tă Trong thuÁt toán này chúng ta giÁ sÿ các phần tÿ trong dãy đã có thć tă tng (khụng giÁm dần), tćc là cỏc phần tÿ đćng tr°óc luụn cú giỏ trỏ nhồ hÂn hoặc bằng (không lãn h¢n) phần tÿ đćng sau nó
Khi đú, nÁu X nhồ hÂn giỏ trỏ phần tÿ đćng ỗ giāa dóy (M[Mid]) thỡ
X chò cú thÅ tỡm thÃy ỗ nÿa đầu cąa dóy và ng°āc l¿i, nÁu X lón hÂn phần tÿ M[Mid] thỡ X chò cú thÅ tỡm thÃy ỗ nÿa sau cąa dóy a T° t°ỗng:
Ph¿m vi tìm kiÁm ban đầu cąa chúng ta là tĉ phần tÿ đầu tiên cąa dãy (First = 1) cho đÁn phần tÿ cuòi cựng cąa dóy (Last = N)
So sỏnh giỏ trỏ X vói giỏ trỏ phần tÿđćng ỗ giāa cąa dóy M là M[Mid]
NÁu X < M[Mid]: Rút ngÃn ph¿m vi tìm kiÁm và nÿa đầu cąa dãy M (Last Mid-1)
NÁu X > M[Mid]: Rút ngÃn ph¿m vi tìm kiÁm và nÿa sau cąa dãy M (First Mid+1)
Lặp l¿i quá trình này cho đÁn khi tìm thÃy phần tÿ có giá trá X hoặc ph¿m vi tìm kiÁm cąa chúng ta không còn nāa (First > Last) b ThuÁt toán đÉ quy (Recursion Algorithm):
//HÁt ph¿m vi tìm kiÁm
B5.1: Tìm thÃy t¿i vá trí Mid
Tìm đÉ quy tĉ First đÁn Last = Mid - 1
Tìm đÉ quy tĉ First = Mid + 1 đÁn Last
Bkt: KÁt thúc c Cây nhá phân tìm kiÁm:
Hàm BinarySearch có prototype: int BinarySearch (T M[], int N, T X);
Hàm thăc hiÉn viÉc tìm kiÁm phần tÿ có giá trá X trong mÁng M có N phần tÿ đó cú thć tă tng NÁu tỡm thÃy, hàm trÁ và mỏt sò nguyờn cú giỏ trỏ tĉ 0 đÁn N-1 là vỏ trớ t°Âng ćng cąa phần tÿ tỡm thÃy Trong tr°ồng hāp ng°āc l¿i, hàm trÁ và giá trá -1 (không tìm thÃy) Hàm BinarySearch sÿ dăng hàm đÉ quy RecBinarySearch có prototype: int RecBinarySearch(T M[], int First, int Last, T X);
Hàm RecBinarySearch thăc hiÉn viÉc tìm kiÁm phần tÿ có giá trá X trên mÁng M trong ph¿m vi tĉ phần tÿ thć First đÁn phần tÿ thć Last NÁu tìm thÃy, hàm trÁ và mỏt sò nguyờn cú giỏ trỏ tĉ First đÁn Last là vỏ trớ t°Âng ćng cąa phần tÿ tìm thÃy
Trong tr°ồng hāp ng°āc l¿i, hàm trÁ và giỏ trỏ -1 (khụng tỡm thÃy)
1 Trỡnh bày t° t°ỗng cąa cỏc thuÁt toỏn tỡm kiÁm: TuyÁn tớnh, Nhỏ phõn, Chò măc? Cỏc thuÁt toỏn này cú thÅ đ°āc vÁn dăng trong cỏc tr°ồng hāp nào? Cho vớ dă?
2 Cài đặt l¿i thuÁt toán tìm tuyÁn tính bằng các cách:
- Sÿ dăng vòng lặp for,
- Sÿ dăng vòng lặp do & while?
Cú nhÁn xột gỡ cho mòi tr°ồng hāp?
Trong quá trình phát triển phần mềm, các công ty có thể nâng cấp thuật toán tìm kiếm tuyến tính của mình bằng nhiều cách Tối ưu hóa và tùy chỉnh thuật toán tìm kiếm tuyến tính có thể cải thiện hiệu suất của nó Các thuật toán tìm kiếm tuyến tính nâng cao cung cấp hiệu quả cao hơn trong việc quản lý và tìm nạp dữ liệu, do đó tăng tốc độ và độ chính xác của các ứng dụng phần mềm.
4 Trong tr°ồng hāp cỏc phần tÿ cąa dóy đó cú thć tă giÁm, hóy trỡnh bày và cài đặt l¿i thuÁt toỏn tỡm nhỏ phõn trong hai tr°ồng hāp: Đẫ quy và Khụng đẫ quy?
5 VÁn dăng thuÁt toán tìm nhá phân, hãy cÁi tiÁn và cài đặt l¿i thuÁt toán tìm kiÁm dăa theo tÁp tin chò măc? Đỏnh giỏ và so sỏnh giāa thuÁt toỏn nguyờn thąy vói các thuÁt toán cÁi tiÁn?
6 Sÿ dăng hàm random trong C đÅ t¿o ra mỏt dóy (mÁng) M cú tòi thiÅu 1.000 sò nguyờn, sau đú chón ng¿u nhiờn (cũng bằng hàm random) mỏt giỏ trỏ nguyờn K VÁn dăng các thuÁt toán tìm tuyÁn tính, tìm nhá phân đÅ tìm kiÁm phần tÿ có giá trá K trong mÁng M
Vói cựng mỏt dā liẫu nh° nhau, cho biÁt thồi gian thăc hiẫn cỏc thuÁt toỏn
7 Trỡnh bày và cài đặt thuÁt toỏn tỡm tuyÁn tớnh đòi vói cỏc phần tÿ trờn mÁng hai chiÃu trong hai tr°ồng hāp:
- Không sÿ dăng phần tÿ