960 likes | 1.18k Views
Chương I : Tìm kiếm & Sắp xếp. Các giải thuật tìm kiếm nội. Tìm kiếm tuyến tính Tìm kiếm nhị phân. Tìm kiếm tuyến tính. Tìm kiếm tuyến tính. Bước 1: i = Vị trí đầu ; Bước 2: Nếu a [ i ] = x : Tìm thấy . Dừng , vị trí xuất hiện : i
E N D
Cácgiảithuậttìmkiếmnội Tìmkiếmtuyến tính Tìmkiếmnhịphân
Tìmkiếmtuyến tính • Bước 1: i = Vịtríđầu; • Bước 2: Nếua[i] = x : Tìmthấy. Dừng, vịtríxuấthiện: i • Bước 3 : i = Vịtríkế(i);// xéttiếpphầntửkếtrongmảng • Bước 4: Nếui >Vịtrícuối: //Hếtmảng Khôngtìmthấy. Dừng. Ngượclại: LặplạiBước 2. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
0 1 2 3 4 5 6 7 Tìmkiếmtuyến tính(sequential search) 5 Vị trí = 2 Khóa tìm 7 13 5 21 6 2 8 15 Tìm thành công Số lần so sánh: 3 Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
0 1 2 3 4 5 6 7 Tìmkiếmtuyến tính (Khoâng tìm thaáy) 9 Khóa tìm 7 13 5 21 6 2 8 15 Không tìm thấy Số lần so sánh: 8 Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmtuyến tính intLinearSearch(int a[], int n, int x) { int i=0; while(i<n && a[i]!=x) i++; if (i<n) return i; // a[i] làphầntửcókhoáx return -1; // tìmhếtmảngnhưngkhôngcóx } Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmtuyến tính • Cảitiếncàiđặt: dùngphươngpháp“línhcanh” • Đặtthêmmộtphầntửcógiátrịxvàocuốimảng • Bảođảmluôntìmthấyxtrongmảng • Sauđódựavàovịtrítìmthấyđểkếtluận. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmtuyến tính intLinearSearch(int a[], int n, int x) { int i=0; // mảnggồmNphầntửtừa[0]..a[N-1] a[n] = x; // thêmlínhcanhvàocuốidãy while(a[i]!=x) i++; if (i<n) return i; // a[i] làphầntửcókhoáx return -1; // tìmhếtmảngnhưngkhôngcóx } Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmtuyến tính • Đánhgiágiảithuật: • Vậygiảithuậttìmtuầntựcóđộphứctạptínhtoáncấpn: T(n) = O(n) Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmtuyến tính • Nhậnxét: • Giảithuậttìmtuyếntínhkhôngphụthuộcvàothứtựcủacácphầntửtrongdanhsách, dovậyđâylàphươngpháptổngquátnhấtđểtìmkiếmtrênmộtdanhsáchbấtkỳ. • Mộtthuậttoáncóthểđượccàiđặttheonhiềucáchkhácnhau, kỹthuậtcàiđặtảnhhưởngđếntốcđộthựchiệncủathuậttoán. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmnhịphân • Đốivớinhữngdãyđãcóthứtự (giảsửthứtựtăng ), cácphầntửtrongdãycóquanhệ a[i-1]a[i]a[i+1] • Nếux >a[i]thìxchỉcóthểxuấthiệntrongđoạn [a[i+1],a[N]] củadãy • Nếux <a[i]thìxchỉcóthểxuấthiệntrongđoạn [a[0],a[i-1]] củadãy . Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmnhịphân • Ýtưởngcủagiảithuậtlàtạimỗibướctiếnhànhsosánhxvớiphầntửnằm ở vịtrígiữacủadãytìmkiếmhiệnhành, dựavàokếtquảsosánhnàyđểquyếtđịnhgiớihạndãytìmkiếm ở bướckếtiếplànửatrênhaynửadướicủadãytìmkiếmhiệnhành Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmnhịphân Bước 1: left = VTĐ; right = VTC; Bước 2: Trongkhileftrightlặp: //đoạntìmkiếmchưarỗng Bước 21: mid = (left+right)/2; // lấymốcsosánh Bước 22: Nếua[mid] = x: //Tìmthấy. Dừng, vịtríxuấthiện: mid Bước 23: Nếua[mid] > x: //tìmxtrongdãyconaleft .. amid -1 right = mid - 1; Ngượclại //tìmxtrongdãyconamid +1 .. aright left = mid + 1; //Hếtlặp Bước 3: Dừng, khôngtìmthấy. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
0 1 2 3 4 5 6 7 8 9 mid left right Tìmkiếmnhịphân Vi trí = 3 10 Khóa cần tìm lớn hơn Khóa cần tìm nhỏ hơn hoặc bằng Khóa cần tìm bằng Khóa tìm 2 5 8 10 12 13 15 18 21 24 Tìm thấy Số lần so sánh: 4 Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmnhịphân intBinarySearch(int a[],int n,int x ) { int left =0, right = n-1, mid; while (left <= right) { m = (left + right)/2; if (x == a[mid]) return m;//Tìmthấyxtạimid if (x<a[mid]) r = mid -1; else l = mid +1; } return -1; // trongdãykhôngcóx } Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmnhịphân • Đánhgiágiảithuật: • Giảithuậttìmnhịphâncóđộphứctạptínhtoáncấplogn: T(n) = O(log 2n) Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmnhịphân • Nhậnxét: • Giảithuậttìmnhịphândựavàoquanhệgiátrịcủacácphầntửmảngđểđịnhhướngtrongquátrìnhtìmkiếm, dovậychỉápdụngđượcchonhữngdãyđãcóthứtự. • Giảithuậttìmnhịphântiếtkiệmthờigianhơnrấtnhiềusovớigiảithuậttìmtuầntựdo Tnhịphân(n) = O(log2n) < Ttuầntự(n) = O(n). Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Tìmkiếmnhịphân • Nhậnxét: • Khimuốnápdụnggiảithuậttìmnhịphâncầnphảixétđếnthờigiansắpxếpdãysốđểthỏađiềukiệndãysốcóthứtự. Thờigiannàykhôngnhỏ, vàkhidãysốbiếnđộngcầnphảitiếnhànhsắpxếplại => khuyếtđiểmchínhchogiảithuậttìmnhịphân. • Cầncânnhắcnhucầuthựctếđểchọnmộttronghaigiảithuậttìmkiếmtrênsaochocólợinhất. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Địnhnghĩabàitoánsắpxếp • Sắpxếplàquátrìnhxửlýmộtdanhsáchcácphầntử (hoặccácmẫutin) đểđặtchúngtheomộtthứtựthỏamãnmộttiêuchuẩnnàođódựatrênnộidungthôngtinlưugiữtạimỗiphầntử. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Kháiniệmnghịchthế • Kháiniệmnghịchthế: • Xétmộtmảngcácsốa[0], a[1], …a[n-1]. • Nếucói<jvàa[i] > a[j], thìtagọiđólàmộtnghịchthế. • Mảngchưasắpxếpsẽcónghịchthế. • Mảngđãcóthứtựsẽkhôngchứanghịchthế. a[0]a[1]…a[n -1] Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Interchangesort Selectionsort Insertionsort Bubblesort Quick sort Cácphươngphápsắpxếpthôngdụng Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Sử dụng hàm hoán vị voidSwap( int &a , int &b ) { int temp = a; a = b; b = temp; } Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
InterchangeSort–Ýtưởng • Nhậnxét: Đểsắpxếpmộtdãysố, tacóthểxétcácnghịchthếcótrongdãyvàlàmtriệttiêudầnchúngđi. Ýtưởngchính: • Xuấtpháttừđầudãy, tìmtấtcảnghịchthếchứaphầntửnày, triệttiêuchúngbằngcáchđổichỗphầntửnàyvớiphầntửtươngứngtrongcặpnghịchthế. • Lặplạixửlýtrênvớicácphầntửtiếptheotrongdãy Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
InterchangeSort–Thuậttoán //input: dãy (a, n) //output: dãy (a, n) đãđượcsắpxếp • Bước 1 : i = 1; // bắtđầutừđầudãy • Bước 2 : j = i+1; //tìmcáccặpphầntửa[j] < a[i], j>i • Bước 3 : Trongkhij n thựchiện • Nếua[j]<a[i]: a[i]a[j]; • j = j+1; • Bước 4 : i = i+1; • Nếui < n: LặplạiBước 2. • Ngượclại: Dừng. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 InterchangeSort–Vídụ j 12 2 8 5 1 6 4 15 1 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 InterchangeSort–Vídụ j 2 1 12 8 5 2 6 4 15 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 InterchangeSort–Vídụ j 1 2 12 8 5 6 4 15 4 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 InterchangeSort–Vídụ j 1 2 4 12 8 6 5 15 5 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 InterchangeSort–Vídụ 1 2 4 5 6 8 12 15 Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
InterchangeSort- Càiđặt voidInterchangeSort(int a[], int n) { int i, j; for (i = 0 ; i<n-1 ; i++) for (j =i+1; j < n ; j++) if(a[j]< a[i]) //nếucónghịchthếthìđổichỗ Swap(a[i],a[j]); } Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
InterchangeSortĐánhgiágiảithuật • Sốlượngcácphépsosánhxảyrakhôngphụthuộcvàotìnhtrạngcủadãysốbanđầu • Sốlượngphéphoánvịthựchiệntùythuộcvàokếtquảsosánh Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Selection sort – Ý tưởng • Nhận xét: Mảng có thứ tự thì a[i]=min(a[i], a[i+1], …, a[n-1]) • Ý tưởng: mô phỏng một trong những cách sắp xếp tự nhiên nhất trong thực 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í đúng là đầu dãy hiện hành • Xem dãy hiện hành chỉ còn n-1 phần tử của dãy ban đầu, bắt đầu từ vị trí thứ 2; lặp lại quá trình trên cho dãy hiện hành... đến khi dãy hiện hành chỉ còn 1 phần tử. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Selectionsort–Thuậttoán //input: dãy (a, n) //output: dãy (a, n) đãđượcsắpxếp • Bước 1 : i = Vịtríđầu; • Bước 2 : Tìmphầntửa[min] nhỏnhấttrongdãyhiệnhànhtừa[i] đếna[n-1] • Bước 3 : Nếumin i: Hoánvịa[min] vàa[i] • Bước 4 : NếuichưalàVịtrícuối • i = Vịtríkế(i); • LặplạiBước 2 Ngượclại: Dừng. //n phầntửđãnằmđúngvịtrí. Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 Selectionsort–Vídụ Swap(a[i], a[min]) FindMinPos(1, 8) min 12 2 8 5 1 6 4 15 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 Selectionsort–Vídụ Swap(a[i], a[min]) FindMinPos(2, 8) min 1 2 8 5 12 6 4 15 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 Selectionsort–Vídụ Swap(a[i], a[min]) FindMinPos(3, 8) min 1 2 8 5 12 6 4 15 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 Selectionsort–Vídụ Swap(a[i], a[min]) FindMinPos(4, 8) min 1 2 4 5 12 6 8 15 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 Selectionsort–Vídụ Swap(a[i], a[min]) FindMinPos(5, 8) min 1 2 4 5 12 6 8 15 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 Selectionsort–Vídụ Swap(a[i], a[min]) FindMinPos(6, 8) min 1 2 4 5 6 12 8 15 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
1 2 3 4 5 6 7 8 Selectionsort–Vídụ Swap(a[i], a[min]) FindMinPos(7, 8) min 1 2 4 5 6 8 12 15 12 15 i Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Selectionsort voidSelectionSort(int a[],int n ) { int min; // chỉsốphầntửnhỏnhấttrongdãyhiệnhành for (int i=0; i<n-1 ; i++) { min = i; for(int j = i+1; j < n ; j++) if (a[j] < a[min]) min = j; // ghinhậnvịtríphầntửnhỏnhất if (min != i) Swap(a[min], a[i]); } } Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Selectionsort–Đánhgiágiảithuật • Ởûlượtthứi, cần (n-i) lầnsosánhđểxácđịnhphầntửnhỏnhấthiệnhành. • Sốlượngphépsosánhkhôngphụthuộcvàotìnhtrạngcủadãysốbanđầu. • Trongmọitrườnghợp, sốlầnsosánhlà: Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
Selectionsort–Đánhgiágiảithuật • Sốlầnhoánvị (mộthoánvịbằng 3 phépgán) phụthuộcvàotìnhtrạngbanđầucủadãysố Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp
InsertionSort–Ýtưởng • Nhậnxét : Mọidãya[0], a[1],..., a[n-1]luôncói-1phầntửđầutiêna[0], a[1],... ,a[i-2]đãcóthứtự (2 ≤ i). Ýtưởngchính: Tìmcáchchènphầntửaivàovịtríthíchhợpcủađoạnđãđượcsắpđểcódãymớia[0], a[1],... ,a[i-1]trởnêncóthứtự. • Vịtrínàychínhlàposthỏa : a[pos-1]a[i ]<a[pos](1posi). Caáu truùc Döõ lieäu - Tìm kieám vaø Saép xeáp