Кіріспе
sort – C++ стандартты кітапханасындағы салыстыру арқылы сұрыптауды жүзеге асыруға арналған жалпы функция. Бұл функция Стандартты Үлгілер Кітапханасынан (STL) шыққан. Нақты сұрыптау алгоритмі тіл стандартымен міндетті түрде белгіленбеген және түрлі іске асырылымдарда өзгеруі мүмкін, бірақ функцияның нашар жағдайдағы асимптотикалық күрделілігі көрсетілген: N элементтен тұратын диапазонға шақырылғанда, функция сызықтық-логарифмдік салыстырудан аспауы керек.
Жалпылау
жалпыға бірдей сипатталған, сондықтан кез келген кездейсоқ кіру контейнерінде жұмыс істей алады және мұндай контейнердің бір элементі екінші элементтен бұрын орналасуын анықтаудың кез келген тәсілімен. Жалпыға бірдей сипатталғанына қарамастан, бұл барлық сұрыптау мәселелеріне оңай қолданылмайды. Зерттелген нақты мәселе мынадай: Екі массив болсын, онда жарамды барлық индекстер үшін элемент пен элемент арасында белгілі бір қатынас бар. массивін сақтай отырып сұрыптаңыз, яғни массивін сұрыптау үшін қолданылған сол өзгерісті қолданыңыз. Бұл элементтерді көшірмей және массивтер жұбының жаңа массивіне көшірмей, сұрыптамай және элементтерді бастапқы массивтерге қайтарусыз жасалуы керек (бұл O(n) уақытша жадты қажет етеді). Бұл мәселенің шешімін 2002 жылы А. Уильямс ұсынды, ол массивтер жұбы үшін арнайы итератор түрін жасады және мұндай итератор түрін дұрыс іске асырудағы кейбір қиындықтарды талдады. Уильямстың шешімін К. Аландер зерттеп, жетілдірді.
Although generically specified, is not easily applied to all sorting problems. A particular problem that has been the subject of some study is the following:
Let and be two arrays, where there exists some relation between the element and the element for all valid indices Sort while maintaining the relation with , i. e., apply the same permutation to that sorts Do the previous without copying the elements of and into a new array of pairs, sorting, and moving the elements back into the original arrays (which would require O(n) temporary space). A solution to this problem was suggested by A. Williams in 2002, who implemented a custom iterator type for pairs of arrays and analyzed some of the difficulties in correctly implementing such an iterator type. Williams's solution was studied and refined by K. Åhlander.
Күрделілігі мен іске асыруы
C++ стандарты N элементтен тұратын диапазонға қолданғанда, функцияның сызықты-логарифмдік салыстыруларын орындауды талап етеді. C++-тың C++03 сияқты бұрынғы нұсқаларында тек O(N log N) орташа күрделігі талап етілетін. Бұл (медианасы 3) жедел сұрыптау сияқты алгоритмдерді пайдалануға мүмкіндік беру үшін жасалды, олар орташа жағдайда жылдам, тіпті ең нашар жағдайда оңтайлы күрделілігі бар және ең нашар жағдайда квадраттық күрделілігі сирек кездесетін басқа алгоритмдерге қарағанда айтарлықтай жылдам. Интросортировка сияқты гибридтік алгоритмдердің енгізілуі орташа өнімділіктің жоғары болуымен қатар ең нашар жағдайда да оңтайлы өнімділікті қамтамасыз етті, сондықтан кейінгі стандарттарда күрделілік талаптары күшейтілді. Әртүрлі жүзеге асырулар әртүрлі алгоритмдерді қолданады. Мысалы, GNU Standard C++ кітапханасы 3 бөлімді гибридтік сұрыптау алгоритмін қолданады: алдымен интросортировка орындалады (интросортировканың өзі жедел сұрыптау мен үймелі сұрыптаудың гибриді), оның тереңдігі 2 × log2 n-ге дейін жетеді, мұнда n – элементтердің саны, содан кейін нәтижеге енгізу сұрыптау қолданылады.
Сорталаудың басқа түрлері
сұрыптау тұрақты емес: сұрыптау алдында бір ретпен орналасқан тең элементтер, сұрыптаудан кейін басқа ретпен орналасуы мүмкін. Тұрақты сұрыптау, кейбір жағдайларда нашар өнімділік есебінен нәтижелердің тұрақтылығын қамтамасыз етеді. Егер қосымша жад болмаса, ол 2 көрсеткішімен квазилинейлік уақытты – O(n log₂ n) – қажет етеді, ал қосымша жад болса, сызықтық-логарифмдік уақыт O(n log n) қажет етеді. Бұл, орнында тұрақты сұрыптау үшін орнында біріктіру сұрыптауын, ал қосымша жадпен тұрақты сұрыптау үшін жай біріктіру сұрыптауын пайдалануға мүмкіндік береді. Ішінара сұрыптау функциясы арқылы жүзеге асырылады, ол n элементтен тұратын диапазон мен m < n бүтін санын қабылдап, диапазонды қайта реттейді, сонда ең кішкентай m элементі сұрыпталған тәртіппен алғашқы m орынға орналасады (ал қалған n − m элементі қалған орындарда белгілі бір ретпен орналасады). Дизайнға байланысты, бұл толық сұрыптаудан едәуір жылдам болуы мүмкін. Тарихи тұрғыдан алғанда, бұл әдетте Θ(n + m log n) ең нашар жағдай уақытын алатын үйіндіге негізделген алгоритмді қолдану арқылы іске асырылды. Копенгаген STL ішінде жақсырақ алгоритм қолданылады, ол «жедел сұрыптау» деп аталады, бұл күрделілікті Θ(n + m log m) дейін төмендетеді. N-ші элементті таңдау функциясы арқылы іске асырылады, ол іс жүзінде орнында ішінара сұрыптауды жүзеге асырады: ол n-ші элементті дұрыс сұрыптайды және бұл элементтің бөлінуін қамтамасыз етеді, яғни одан бұрынғы элементтер одан кішкентай, ал одан кейінгі элементтер одан үлкен болады. Орташа жағдайда бұл операция сызықтық уақытта орындалуы керек, бірақ ең нашар жағдайға қатысты талаптар жоқ; бұл талаптарды «жедел таңдау» алгоритмі кез келген півот стратегиясы үшін дәл орындайды. Кейбір контейнерлер, тізім сияқты, сұрыптаудың арнайы нұсқасын мүшелік функция ретінде ұсынады. Бұл себебі байланысты тізімдерде кездейсоқ кіру мүмкін емес (сондықтан жай сұрыптау функциясын қолдануға болмайды), сондай-ақ арнайы нұсқа тізім итераторлары көрсеткен мәндерді сақтайды.
Qsort-пен салыстыру
C++ стандартты кітапханасында , C стандартты кітапханасынан функциясы да бар. , салыстырғанда, шаблондық түрі қауіпсіз, себебі ол дерек элементтеріне қауіпсіз емес көрсеткіштер арқылы қол жеткізуді қажет етпейді, ал функциясы осыны қажет етеді. Сондай-ақ, функциясы салыстыру функциясын функция көрсеткіші арқылы қол жеткізеді, осылайша көптеген қайталама функция шақыруларын тудырады, ал -та салыстыру функцияларын шаблондық инстанция үшін жасалған жеке кодқа енгізуге болады. Іс жүзінде, C++ кодын пайдалану, мысалы, бүтін сандар сияқты қарапайым деректерді сұрыптауда, осыған балама C кодын пайдаланудан әлдеқайда жылдам болады.