Shell fajta
Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2020. július 9-én felülvizsgált
verziótól ; az ellenőrzések 23 szerkesztést igényelnek .
A Shell - rendezés egy rendezési algoritmus , amely a beillesztési rendezés továbbfejlesztett változata . A Shell módszer lényege, hogy olyan elemeket hasonlítson össze, amelyek nemcsak egymás mellett, hanem egymástól bizonyos távolságra is vannak. Más szóval, ez egy beszúrásos rendezés előzetes „durva” áthaladással. A buborékos rendezéshez hasonló fejlesztést fésűs rendezésnek nevezünk .
Leírás
A Shell rendezése során az értékeket először összehasonlítják és rendezik egymás között, egymástól bizonyos távolságra ( az érték kiválasztásához lásd alább ). Ezt követően az eljárás megismétlődik néhány kisebb értéknél , és a Shell rendezés az elemek sorrendjével fejeződik be (vagyis a szokásos beszúrási rendezés ). A Shell rendezés hatékonyságát bizonyos esetekben az biztosítja, hogy az elemek „gyorsabban” kerülnek a helyükre (egyszerű rendezési módszereknél, például buborékos rendezésnél két elem minden permutációja maximummal csökkenti az inverziók számát a listában 1-ből, és a Shell rendezésével ez a szám több is lehet).
![d](https://wikimedia.org/api/rest_v1/media/math/render/svg/e85ff03cbe0c7341af6b982e47e9f90d235c66ab)
![d](https://wikimedia.org/api/rest_v1/media/math/render/svg/e85ff03cbe0c7341af6b982e47e9f90d235c66ab)
![d=1](https://wikimedia.org/api/rest_v1/media/math/render/svg/958b426c5ace91d4fb7f5a3becd7b21dba288d50)
Bár a Shellsort sok esetben lassabb, mint a gyorsrendezés, számos előnnyel rendelkezik:
- nincs szükség verem memóriára;
- nem romlik a rossz adatkészletek – A Quicksort könnyen lebomlik O(n²-re), ami rosszabb, mint a Shellsort garantált legrosszabb ideje.
Történelem
A Shell sort feltalálójáról, Donald Shellről nevezték el , aki 1959 -ben publikálta az algoritmust .
Példa
Adjunk meg egy listát, amelyet Shell metódussal rendezünk, és .
![A=(32,95,16,82,24,66,35,19,75,54,40,43,93,68)](https://wikimedia.org/api/rest_v1/media/math/render/svg/21f738b70c210ca2567d01cf170625c3b0058ac1)
![d](https://wikimedia.org/api/rest_v1/media/math/render/svg/e85ff03cbe0c7341af6b982e47e9f90d235c66ab)
![5,3,1](https://wikimedia.org/api/rest_v1/media/math/render/svg/b43045fc1fc3376530e47ac78299d9bff79bda63)
Az első lépés az összes olyan elemből álló allistákat rendezi , amelyek 5 pozícióban különböznek egymástól, azaz allistákat , , , , .![A](https://wikimedia.org/api/rest_v1/media/math/render/svg/7daff47fa58cdfd29dc333def748ff5fa4c923e3)
![A](https://wikimedia.org/api/rest_v1/media/math/render/svg/7daff47fa58cdfd29dc333def748ff5fa4c923e3)
![A_{{5,1}}=(32,66,40)](https://wikimedia.org/api/rest_v1/media/math/render/svg/e6f77b34a7ea6e899f3a9aad2bcd1eac3c0a8eea)
![A_{{5,2}}=(95,35,43)](https://wikimedia.org/api/rest_v1/media/math/render/svg/6fead81394f44526f703f5fb9ef6d283608da26a)
![A_{{5,3}}=(16,19,93)](https://wikimedia.org/api/rest_v1/media/math/render/svg/f3b457308eace5f6f1c86ed36a2f872e4c97c99d)
![A_{{5,4}}=(82,75,68)](https://wikimedia.org/api/rest_v1/media/math/render/svg/c01703c582c4d7335615acae9a0f2827a0722f8c)
Az eredményül kapott listában a második lépésben az allistákat ismét a 3 pozícióval elhelyezett elemekből rendezzük.
A folyamat a kapott lista szokásos beszúrási módjával zárul.
A hézagok hosszának kiválasztása
Az algoritmus átlagos futási ideje függ az intervallumok hosszától - , amelyek az eredeti tömb rendezett elemeit tartalmazzák majd kapacitással az algoritmus minden lépésében. Számos megközelítés létezik ezen értékek kiválasztására:
![d](https://wikimedia.org/api/rest_v1/media/math/render/svg/e85ff03cbe0c7341af6b982e47e9f90d235c66ab)
![N](https://wikimedia.org/api/rest_v1/media/math/render/svg/f5e3890c981ae85503089652feb48b191b57aae3)
- a Shell által eredetileg használt hézaghossz-sorozat: a legrosszabb esetben az algoritmus bonyolultsága ;
![{\displaystyle d_{1}=N/2,d_{i}=d_{i-1}/2,d_{k}=1}](https://wikimedia.org/api/rest_v1/media/math/render/svg/6787e44fb46b003c6ad48146b2a7cb601fbb4612)
![O(N^{2})](https://wikimedia.org/api/rest_v1/media/math/render/svg/e5d43a3df904fa4d7220f5b86285298aa36d969b)
- Hibbard által javasolt sorrend: minden érték ; a lépések ilyen sorozata egy bonyolultságú algoritmushoz vezet ;
![{\displaystyle 2^{i}-1\leq N,i\in \mathbb {N} }](https://wikimedia.org/api/rest_v1/media/math/render/svg/1d0ae414fdd98fca4eb79b02aba42f8a390516c8)
![O(N^{{3/2}})](https://wikimedia.org/api/rest_v1/media/math/render/svg/0ff8d577486acc6b703329c55525ac87909501bf)
- Sedgwick által javasolt sorozat : ha i páros és ha i páratlan. Ilyen növekmények használatakor az algoritmus átlagos bonyolultsága: , és a legrosszabb esetben a sorrend . A Sedgwick-képlet használatakor meg kell állnia az inc[s-1] értéknél, ha 3*inc[s] > méret. [2] ;
![{\displaystyle d_{i}=9\cdot 2^{i}-9\cdot 2^{i/2}+1}](https://wikimedia.org/api/rest_v1/media/math/render/svg/a1fe63653ace9a018f135f818bb963a2e23dc256)
![{\displaystyle d_{i}=8\cdot 2^{i}-6\cdot 2^{(i+1)/2}+1}](https://wikimedia.org/api/rest_v1/media/math/render/svg/b455e9cb3e3b6a39e7a44b6121faf0d9b3e1ce14)
![O(n^{{7/6}})](https://wikimedia.org/api/rest_v1/media/math/render/svg/d38fdcc1b94c0810992aeb5f393fc9823de3b1bb)
![O(n^{{4/3}})](https://wikimedia.org/api/rest_v1/media/math/render/svg/a0395f81d3c0239090b4f92eb4a7165626ae0af6)
- Pratt által javasolt sorrend: minden érték ; ebben az esetben az algoritmus összetettsége ;
![{\displaystyle 2^{i}\cdot 3^{j}\leq N/2,i,j\in \mathbb {N} }](https://wikimedia.org/api/rest_v1/media/math/render/svg/79a785152eb92340d25530453b84c9dea878e65a)
![O(N(logN)^{2})](https://wikimedia.org/api/rest_v1/media/math/render/svg/ee3e458584d2200531ea0e202d9f75f75fc6abcc)
- Marcin Ciur empirikus szekvenciája ( A102549 szekvencia az OEIS -ben ): ; az egyik legjobb egy körülbelül 4000 elemből álló tömb rendezéséhez. [3] ;
![{\displaystyle d\in \left\{1,4,10,23,57,132,301,701,1750\jobbra\))](https://wikimedia.org/api/rest_v1/media/math/render/svg/7a8ba75f5e7e516b36ae619aad63fbb217581105)
- empirikus sorozat Fibonacci-számok alapján : ;
![{\displaystyle d\in \left\{F_{n}\right\}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/97668832f7d61fe23be6ee2dd11667319754dfea)
- minden értéket
, ; egy ilyen lépéssorozat egy bonyolultságú algoritmushoz vezet .![j\in {\mathbb N}](https://wikimedia.org/api/rest_v1/media/math/render/svg/b54b0f8d5a5eb196ce103460f69c9eb3ec9393fb)
![O(N^{{3/2}})](https://wikimedia.org/api/rest_v1/media/math/render/svg/0ff8d577486acc6b703329c55525ac87909501bf)
Megvalósítás C++ nyelven
sablon < típusnév RandomAccessIterator , típusnév Összehasonlítás >
void shell_sort ( RandomAccessIterator először , RandomAccessIterator utolsó , Compare comp )
{
for ( auto d = ( utolsó - első ) / 2 ; d ! = 0 ; d / = 2 )
//kell egy ciklus az első = a[0..d-1]
for ( auto i = első + d ; i != utolsó ; ++ i )
for ( auto j = i ; j - első > = d && comp ( * j , * ( j - d ) ); j - = d )
std :: csere ( * j , * ( j - d ) );
}
Megvalósítás C-ben
void shell_sort ( int * tömb , int méret ) {
for ( int s = méret / 2 ; s > 0 ; s / = 2 ) {
for ( int i = s ; i < méret ; ++ i ) {
for ( int j = i - s ; j >= 0 && array [ j ] > array [ j + s ]; j -= s ) {
inttemp = tömb [ j ] ;
tömb [ j ] = tömb [ j + s ];
tömb [ j + s ] = hőmérséklet ;
}
}
}
}
Implementáció Java nyelven
public class ShellSort {
public static void shellSort ( int [] array ) {
int h = 1 ;
while ( h <= tömb . hossza / 3 ) {
h = h * 3 + 1 ;
}
while ( h > 0 ) {
for ( int külső = h ; külső < tömb . hossza ; külső ++ ) {
int tmp = tömb [ külső ] ;
int belső = külső ;
while ( inner > h - 1 && array [ inner - h ] > tmp ) {
array [ inner ] = array [ inner - h ] ;
belső -= h ;
}
tömb [ belső ] = tmp ;
}
h = ( h - 1 ) / 3 ;
}
}
}
Megvalósítás Pythonban
def shell_sort ( data : list [ int ]) -> list [ int ]:
last_index = len ( data )
step = len ( data ) // 2
while step > 0 :
for i in range ( step , last_index , 1 ):
j = i
delta = j - lépés
, míg delta >= 0 és adat [ delta ] > adat [ j ]:
adat [ delta ], adat [ j ] = adat [ j ], adat [ delta ]
j = delta
delta = j - lépés
lépés //= 2
visszaadja az adatokat
Jegyzetek
- ↑ Shell D. L. A nagy sebességű válogatási eljárás // Commun . ACM - [New York] : Association for Computing Machinery , 1959. - Vol. 2, Iss. 7. - P. 30-32. — ISSN 0001-0782 ; 1557-7317 - doi:10.1145/368370.368387
- ↑ J. Incerpi, R. Sedgewick , "Improved Upper Bounds for Shellsort", J. Computer and System Sciences 31, 2, 1985.
- ↑ Marcin Ciura a Shellsort átlagos esetének legjobb növekményei . Letöltve: 2009. szeptember 15. Az eredetiből archiválva : 2011. augusztus 30.. (határozatlan)
Linkek