Skal sortering
Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den
version , der blev gennemgået den 9. juli 2020; checks kræver
23 redigeringer .
Shell sortering er en sorteringsalgoritme , der er en forbedret version af indsættelsessortering . Ideen med Shell-metoden er at sammenligne elementer, der ikke kun er ved siden af hinanden, men også i en vis afstand fra hinanden. Dette er med andre ord indsættelsessortering med foreløbige "grove" gennemløb. En lignende forbedring til boblesortering kaldes kamsortering .
Beskrivelse
Ved sortering af Shell bliver værdierne først sammenlignet og sorteret indbyrdes, idet de står fra hinanden i en vis afstand ( se nedenfor for valg af værdi ). Derefter gentages proceduren for nogle mindre værdier på , og Shell-sorteringen afsluttes ved at bestille elementerne på (det vil sige den sædvanlige indsættelsessort ). Effektiviteten af Shell-sortering i visse tilfælde sikres ved, at elementerne "hurtigere" falder på plads (i simple sorteringsmetoder, for eksempel boblesortering , reducerer hver permutation af to elementer antallet af inversioner i listen med et maksimum af 1, og med Shell-sortering kan dette tal være mere ).
![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)
Selvom Shellsort i mange tilfælde er langsommere end quicksort , har det en række fordele:
- intet behov for stakhukommelse;
- ingen nedbrydning på dårlige datasæt - Quicksort nedbrydes nemt til O(n²), hvilket er værre end den værste garanterede tid for Shellsort.
Historie
Shell sort blev opkaldt efter dens opfinder, Donald Shell , som offentliggjorde algoritmen i 1959 .
Eksempel
Lad en liste blive givet, og den er sorteret efter Shell-metoden, og .
![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)
Det første trin sorterer underlister sammensat af alle elementer , der adskiller sig med 5 positioner, det vil sige underlister , , , , .![EN](https://wikimedia.org/api/rest_v1/media/math/render/svg/7daff47fa58cdfd29dc333def748ff5fa4c923e3)
![EN](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)
I den resulterende liste, i det andet trin, sorteres underlister igen fra elementer fordelt på 3 positioner.
Processen slutter med den sædvanlige indsættelsessortering af den resulterende liste.
Valg af længde på mellemrum
Den gennemsnitlige køretid for algoritmen afhænger af længden af intervallerne - , som vil indeholde de sorterede elementer i det originale array med en kapacitet på hvert trin i algoritmen. Der er flere tilgange til at vælge disse værdier:
![d](https://wikimedia.org/api/rest_v1/media/math/render/svg/e85ff03cbe0c7341af6b982e47e9f90d235c66ab)
![N](https://wikimedia.org/api/rest_v1/media/math/render/svg/f5e3890c981ae85503089652feb48b191b57aae3)
- rækkefølgen af mellemrumslængder oprindeligt brugt af Shell: i værste fald vil kompleksiteten af algoritmen være ;
![{\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)
- Hibbards foreslåede sekvens: alle værdier ; en sådan sekvens af trin fører til en kompleksitetsalgoritme ;
![{\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)
- sekvens foreslået af Sedgwick : hvis i er lige og hvis i er ulige. Når du bruger sådanne trin, er den gennemsnitlige kompleksitet af algoritmen: , og i værste tilfælde af størrelsesordenen . Når du bruger Sedgwick-formlen, bør du stoppe ved værdien inc[s-1], hvis 3*inc[s] > størrelse. [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)
- sekvens foreslået af Pratt: alle værdier ; i dette tilfælde er kompleksiteten af algoritmen ;
![{\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)
- empirisk sekvens af Marcin Ciur (sekvens A102549 i OEIS ): ; er en af de bedste til at sortere et array op til ca. 4000 elementer. [3] ;
![{\displaystyle d\in \left\{1,4,10,23,57,132,301,701,1750\right\))](https://wikimedia.org/api/rest_v1/media/math/render/svg/7a8ba75f5e7e516b36ae619aad63fbb217581105)
- empirisk sekvens baseret på Fibonacci-tal : ;
![{\displaystyle d\in \left\{F_{n}\right\}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/97668832f7d61fe23be6ee2dd11667319754dfea)
- alle værdier
dage ,; en sådan sekvens af trin fører til en kompleksitetsalgoritme .![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)
Implementering i C++
skabelon < typenavn RandomAccessIterator , typenavn Sammenlign >
void shell_sort ( RandomAccessIterator først , RandomAccessIterator sidst , Sammenlign comp )
{
for ( auto d = ( sidste - først ) / 2 ; d != 0 ; d /= 2 )
//brug for en løkke for først = a[0..d-1]
for ( auto i = første + d ; i != sidste ; ++ i )
for ( auto j = i ; j - først >= d && comp ( * j , * ( j - d ) ); j - = d )
std :: swap ( * j , * ( j - d ) );
}
Implementering i C
void shell_sort ( int * matrix , int size ) {
for ( int s = størrelse / 2 ; s > 0 ; s /= 2 ) {
for ( int i = s ; i < størrelse ; ++ i ) {
for ( int j = i - s ; j >= 0 && array [ j ] > array [ j + s ]; j -= s ) {
intemp = matrix [ j ] ;
array [ j ] = array [ j + s ];
array [ j + s ] = temp ;
}
}
}
}
Implementering i Java
public class ShellSort {
public static void shellSort ( int [] array ) {
int h = 1 ;
while ( h <= matrix . længde / 3 ) {
h = h * 3 + 1 ;
}
while ( h > 0 ) {
for ( int ydre = h ; ydre < array . længde ; ydre ++ ) {
int tmp = array [ ydre ] ;
int indre = ydre ;
while ( indre > h - 1 && matrix [ indre - h ] > tmp ) {
matrix [ indre ] = matrix [ indre - h ] ;
indre -= h ;
}
array [ indre ] = tmp ;
}
h = ( h - 1 ) / 3 ;
}
}
}
Implementering i Python
def shell_sort ( data : liste [ int ]) -> liste [ int ]:
sidste_indeks = len ( data )
step = len ( data ) // 2
mens trin > 0 :
for i i rækkevidde ( trin , sidste_indeks , 1 ):
j = i
delta = j - step
mens delta >= 0 og data [ delta ] > data [ j ]:
data [ delta ], data [ j ] = data [ j ], data [ delta ]
j = delta
delta = j - step
trin //= 2
returner data
Noter
- ↑ Shell D. L. En højhastighedssorteringsprocedure // Commun . ACM - [New York] : Association for Computing Machinery , 1959. - Vol. 2, Iss. 7. - S. 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 bedste stigninger for det gennemsnitlige tilfælde af Shellsort . Hentet 15. september 2009. Arkiveret fra originalen 30. august 2011. (ubestemt)
Links