სორტირება გადათვლით (Countingsort)
რამდენად სწრაფი შეიძლება იყოს სორტირება? აქამდე განხილულ სორტირების ყველა ალგორითმს შეგვიძლია “შედარების” ალგორითმი ვუწოდოთ – ისინი ელემენტთა თანმიმდევრობას შედარებების საშუალებით ადგენენ. (მაგ. სორტირება ჩასმით, ჩქარი სორტირება, სორტირება გროვით და ა.შ.) შესრულების საუკეთესო დრო ამ ალგორითმებისათვის იყო O (n lg n). არის თუ არა ეს დრო საუკეთესო? დიახ. თუკი ჩვენ გამოვიყენებთ შედარებებს.
A, I, A(I)=P(I) and Time(A,I) Tupper(|I|) ამოცანის დროითი სირთულე მინიმალური დრო, რომელიც სჭირდება ალგორითმს ამოცანის ამოსახსნელად. ზედა საზღვარი P ამოცანა იხსნება Tupper(n) დროში, თუ მას გამოაქვს სწორი პასუხი მაქსიმუმ ამ დროში. A, I, A(I)=P(I) and Time(A,I) Tupper(|I|) მაგ: სორტირებისათვის Tupper(n) = O(n2).
A, I, A(I) P(I) or Time(A,I) Tlower(|I|) ამოცანის დროითი სირთულე მინიმალური დრო, რომელიც სჭირდება ალგორითმს ამოცანის ამოსახსნელად. ქვედა საზღვარი P ამოცანის ამოხსნის ქვედა საზღვარს უწოდებენ Tlower(n) დროს, რომელზეც უფრო სწრაფად ამოცანის ამოხსნა შეუძლებელია. A, I, A(I) P(I) or Time(A,I) Tlower(|I|) მაგ: სორტირებისათვის Tlower = sqrt(N)
ამოხსნის ხე Sort a1, a2, …, an 1:2 2:3 123 1:3 132 312 213 231 321 ყოველი შიგა კვანძს შეესაბამება i:j, სადაც i, j {1, 2,…, n}. მარცხენა ქვეხე აჩვენებს შედარებებებს, სადაც ai aj. მარჯვენა ქვეხე აჩვენებს შედარებებებს, სადაც if ai aj.
ამოხსნის ხის მაგალითი Sort a1, a2, a3 9, 4, 6 1:2 9 4 2:3 1:3 123 1:3 213 2:3 132 312 231 321 ყოველი შიგა კვანძს შეესაბამება i:j, სადაც i, j {1, 2,…, n}. მარცხენა ქვეხე აჩვენებს შედარებებებს, სადაც ai aj. მარჯვენა ქვეხე აჩვენებს შედარებებებს, სადაც if ai aj.
ამოხსნის ხის მაგალითი Sort a1, a2, a3 9, 4, 6 1:2 2:3 1:3 9 6 123 1:3 213 2:3 132 312 231 321 ყოველი შიგა კვანძს შეესაბამება i:j, სადაც i, j {1, 2,…, n}. მარცხენა ქვეხე აჩვენებს შედარებებებს, სადაც ai aj. მარჯვენა ქვეხე აჩვენებს შედარებებებს, სადაც if ai aj.
ამოხსნის ხის მაგალითი Sort a1, a2, a3 9, 4, 6 1:2 2:3 1:3 123 213 2:3 4 6 132 312 231 321 ყოველი შიგა კვანძს შეესაბამება i:j, სადაც i, j {1, 2,…, n}. მარცხენა ქვეხე აჩვენებს შედარებებებს, სადაც ai aj. მარჯვენა ქვეხე აჩვენებს შედარებებებს, სადაც if ai aj.
ამოხსნის ხის მაგალითი Sort a1, a2, a3 9, 4, 6 4 6 9 1:2 2:3 1:3 123 1:3 213 2:3 132 312 231 321 4 6 9 თითოეული ფოთოლი შეიცავს გადანაცვლებას , ,…, (n), რომელიც დალაგებულია a(1) a(2) a(n) .
ნებისმიერი სორტირება, რომელიც შედარებებს იყენებს, შეიძლება გარდავქმნათ ამოხსნის ხედ class InsertionSortAlgorithm { for (int i = 1; i < a.length; i++) { int j = i; while ((j > 0) && (a[j-1] > a[i])) { a[j] = a[j-1]; j--; } a[j] = B; }} 1:2 2:3 123 1:3 132 312 213 231 321
ამოხსნის ხის ქვედა საზღვარი სორტირებისათვის თეორემა. n ელემენტის დალაგებისათვის აგებული ამოხსნის ხის სიმაღლეა (n lg n) . დამტკიცება. ამოხსნის ხე შეიცავს n! ფოთოლს, რადგან სულ შესაძლოა n! გადანაცვლება. h სიმაღლის ორობით ხეს აქვს 2h ფოთოლი. მაშასადამე, n! 2h . h lg(n!) lg ((n/e)n) (სტირლინგის ფორმულა) = n lg n – n lg e = (n lg n) .
შედარების ალგორითმების ქვედა საზღვარი დასკვნა. სორტირება გროვით და სორტირება შერწყმით ასიმპტოტურად ოპტიმალური შედარების ალგორითმები არიან.
სორტირება წრფივ დროში k=max(A) Counting sort: ალაგებს ელემენტთა შედარების გარეშე Input: A[1 . . n], სადაც A[ j]{1, 2, …, k} . Output: C[1 . . n], დალაგებული. დამატებითი მასივი: B[1 . . k] . k=max(A)
Counting-sort A: 4 1 5 4 3 8 3 3 4 3 B: for (i=0; i<n; i++) { 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 1 1 1 3 2 4 3 2 1 1 for (i=0; i<n; i++) { B[A[i]]++; }
Counting-sort A: 4 1 5 4 3 8 3 3 4 3 B: B: for (i=1; i<k; i++) { 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 3 1 4 1 1 1 2 3 4 5 6 7 8 B: 8 1 1 5 9 9 9 10 for (i=1; i<k; i++) { B[i]=B[i]+B[i-1]; }
Counting-sort A: 4 1 5 4 3 8 3 3 4 3 B: C: 3 for (i=n; i>0; i--) { 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 8 1 1 5 4 9 9 9 10 1 2 3 4 5 6 7 8 9 10 C: 3 for (i=n; i>0; i--) { C[B[A[i]]]=A[i]; B[A[i]]--; }
Counting-sort 1 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 8 1 1 4 7 9 9 9 10 1 2 3 4 5 6 7 8 9 10 C: 3 4 for (i=n; i>0; i--) { C[B[A[i]]]=A[i]; B[A[i]]--; }
Counting-sort 1 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 7 1 1 4 3 9 9 9 10 1 2 3 4 5 6 7 8 9 10 C: 3 3 4 for (i=n; i>0; i--) { C[B[A[i]]]=A[i]; B[A[i]]--; }
Counting-sort 1 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 7 1 1 3 2 9 9 9 10 1 2 3 4 5 6 7 8 9 10 C: 3 3 3 4 for (i=n; i>0; i--) { C[B[A[i]]]=A[i]; B[A[i]]--; }
Counting-sort 1 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 7 1 1 2 9 9 9 10 9 1 2 3 4 5 6 7 8 9 10 C: 3 3 3 4 8 for (i=n; i>0; i--) { C[B[A[i]]]=A[i]; B[A[i]]--; }
Counting-sort 1 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 7 1 1 1 2 9 9 9 9 1 2 3 4 5 6 7 8 9 10 C: 3 3 3 3 4 8 for (i=n; i>0; i--) { C[B[A[i]]]=A[i]; B[A[i]]--; }
Counting-sort 1 2 3 4 5 6 7 8 9 10 A: 4 1 5 4 3 8 3 3 4 3 1 2 3 4 5 6 7 8 B: 5 1 1 8 9 9 9 1 2 3 4 5 6 7 8 9 10 C: 1 3 3 3 3 4 4 4 5 8 for (i=n; i>0; i--) { C[B[A[i]]]=A[i]; B[A[i]]--; }
ანალიზი (n) (k) (n) (n + k) for (i=0; i<n; i++) { B[A[i]]++; } for (i=1; i<k; i++) { B[i]=B[i]+B[i-1]; } (k) for (i=n; i>0; i--) { C[B[A[i]]]=A[i]; B[A[i]]--; } (n) (n + k)
სტაბილურობა Counting sort სტაბილური სორტირებაა: ტოლ ელემენტთა შორის თავდაპირველი განლაგება არ იცვლება A: 4 1 3 B:
Radix-sort 78575633 345065522 4458034 43534644 90905431 3443868 90905431 345065522 78575633 4458034 43534644 3443868 90905431 345065522 78575633 4458034 43534644 3443868 345065522 90905431 78575633 4458034 43534644 3443868 345065522 90905431 78575633 4458034 43534644 3443868 4458034 90905431 345065522 78575633 43534644 3443868 4458034 90905431 345065522 78575633 43534644 3443868 3443868 43534644 90905431 345065522 78575633 4458034
Radix-sort 3443868 43534644 90905431 345065522 78575633 4458034 90905431 43534644 3443868 4458034 345065522 78575633 90905431 43534644 3443868 4458034 345065522 78575633 345065522 3443868 4458034 43534644 78575633 90905431 345065522 3443868 4458034 43534644 78575633 90905431 90905431 3443868 43534644 4458034 345065522 78575633 90905431 3443868 43534644 4458034 345065522 78575633 3443868 4458034 43534644 345065522 78575633 90905431
Radix-sort 3443868 4458034 43534644 78575633 90905431 345065522