Кіріспе

Кездейсоқ іздеу ағашы дерек құрылымы

Компьютер ғылымында, treap және кездейсоқ бинарлық іздеу ағашы – реттелген кілттердің динамикалық жиынтығын сақтайтын және кілттер арасында бинарлық іздеулерді жүзеге асыруға мүмкіндік беретін екілік іздеу ағашы дерек құрылымдарының өте жақын түрлері. Кілттерді енгізу және жоюдың кез келген тізбегінен кейін, ағаш пішіні кездейсоқ бинарлық ағашқа ұқсас ықтималдық таралымына ие кездейсоқ айнымалы болып табылады; атап айтқанда, жоғары ықтималдықпен оның биіктігі кілттер санының логарифміне пропорционал, сондықтан әрбір іздеу, енгізу немесе жою операциясы логарифмдік уақытты қажет етеді.

Сипаттама

Ағашқа алғаш рет Раймунд Зайдель мен Сесилия Р. Арагон 1989 жылы сипаттаған; оның атауы «ағаш» және «үйінді» сөздерінің қосындысынан жасалған. Бұл – әрбір кілтке (кездейсоқ таңдалған) сандық басымдық берілген Картезиан ағашы. Кез келген екілік іздеу ағашы сияқты, түйіндерді баптау реті кілттердің сұрыпталған ретімен сәйкес келеді. Ағаштың құрылымы үйінділік ретке келу талабымен анықталады: яғни, жапырақ емес түйіннің басымдық саны оның ұрпақтарының басымдығынан үлкен немесе тең болуы керек. Осылайша, жалпы Картезиан ағаштарындағыдай, түбір түйін – ең жоғары басымдыққа ие түйін, ал оның сол және оң тармақтары сол түйіннің сол және оң жағындағы сұрыпталған тізбектерден бірдей қалыптасады. Трепті сипаттаудың тағы бір жолы – оны қайта теңгерместен, ең жоғары басымдыққа ие түйіндерді біртіндеп екілік іздеу ағашына енгізу арқылы құруға болады. Сондықтан, егер басымдықтар тәуелсіз кездейсоқ сандар болса (екі түйіннің бірдей басымдыққа ие болу ықтималдығы өте төмен болуын қамтамасыз ететін, жеткілікті кең мүмкіндіктер кеңістігінен алынған үлестірімнен), онда трептің пішіні кездейсоқ екілік іздеу ағашының пішінімен бірдей ықтималдық үлестіріміне ие, яғни түйіндерді кездейсоқ енгізу ретімен теңгерместен құрылған іздеу ағашы. Кездейсоқ екілік іздеу ағаштарының жоғары ықтималдылықпен логарифмдік биіктігі бар екендігі белгілі болғандықтан, трептер үшін де осы жағдай орынды. Бұл, жылдам сұрыптаудың күтілетін уақытта жұмыс істейтін екілік іздеу ағашының аргументін көрсетеді. Егер екілік іздеу ағаштары сұрыптаудың динамикалық мәселесіне шешім болса, онда трептер динамикалық жылдам сұрыптауға сәйкес келеді, онда басымдықтар півотты таңдауды басшылыққа алады. Арагон мен Зайдель жиі қол жеткізілетін түйіндерге жоғары басымдықтарды беруді ұсынады, мысалы, әр қол жеткізілу кезінде кездейсоқ санды таңдап, егер ол бұрынғы басымдықтан жоғары болса, түйіннің басымдығын сол санмен ауыстыру арқылы. Бұл өзгерту ағаштың кездейсоқ пішінін жоғалтуына әкелуі мүмкін; керісінше, жиі қол жеткізілетін түйіндер ағаш түбіріне жақын орналасуы мүмкін, осылайша оларды іздеу жылдамырақ болады. Наор мен Ниссим ашық кілтті криптожүйелерде авторизациялық сертификаттарды сақтауға арналған қолданылуын сипаттайды.

Сырғанақ салу

Треп құру үшін біз жай ғана n мәнді трепке енгізе аламыз, мұндағы әрқайсысы уақытты қажет етеді. Сондықтан, треп мәндер тізімінен уақыт ішінде құрылуы мүмкін.

Кездейсоқ екілік іздеу ағашы

Мартинес пен Рура Арагон мен Сейделдің treaps жұмысынан кейін енгізген кездейсоқ екілік іздеу ағашы, ағаш пішінінің бірдей кездейсоқ таралымымен бірдей түйіндерді сақтайды, бірақ ағаштың кездейсоқ құрылымын сақтау үшін түйіндердің ішінде әртүрлі ақпаратты ұстайды. Әр түйінде кездейсоқ басымдықтарды сақтаудың орнына, кездейсоқ екілік іздеу ағашы әрбір түйінде кішкентай бүтін санды сақтайды – оның ұрпақтарының санын (өзін біреу ретінде санап); бұл сандар ағаш айналу операциялары кезінде әр айналымға тек тұрақты уақыт қосымша жұмсау арқылы сақталуы мүмкін. Егер ағашта n түйін болса және x кілті енгізілсе, енгізу алгоритмі x-ті ағаштың жаңа түбірі ретінде орналастыру ықтималдығын 1/(n + 1) деп таңдайды, әйтпесе x-ті сол немесе оң тармаққа енгізу үшін енгізу процедурасын рекурсивті шақырады (кілті түбірден кіші немесе үлкен болуына байланысты). Ұрпақтардың саны алгоритмге әр қадамда кездейсоқ таңдаулар үшін қажетті ықтималдықтарды есептеуге көмектеседі. x-ті тармақтың түбіне орналастыру, оны жапыраққа енгізіп, содан кейін жоғары айналдыру арқылы немесе Мартинес пен Рура сипаттаған, тармақты жаңа түйіннің сол және оң балалары ретінде пайдалану үшін екі бөлікке бөлетін балама алгоритммен орындалуы мүмкін. Кездейсоқ екілік іздеу ағашының жою процедурасы енгізу процедурасы сияқты түйіндегі бірдей ақпаратты пайдаланады, бірақ енгізу процедурасынан айырмашылығы, ол жойылған түйіннің сол және оң балаларынан түсетін екі тармақты бір ағашқа біріктіру үшін орташа есеппен O(1) кездейсоқ шешімді ғана қажет етеді. Бұл себебі біріктірілетін тармақтардың тереңдігі орташа есеппен Θ(log n) құрайды; n және m өлшемді екі ағашты біріктіру үшін орташа есеппен Θ(log(n+m)) кездейсоқ таңдау қажет. Егер жойылған түйіннің сол немесе оң тармағы бос болса, біріктіру операциясы тривиальды болады; әйтпесе, жойылған түйіннің сол немесе оң баласы ұрпақтарының санына пропорционалды ықтималдықпен жаңа тармақтың түбірі ретінде таңдалады, ал біріктіру рекурсивті жалғасады.

Салыстыру

Кездейсоқ екілік ағаштағы түйінге сақталатын ақпарат трепке қарағанда қарапайым (жоғары дәлдікті кездейсоқ санның орнына кішкентай бүтін сан), бірақ ол кездейсоқ сандар генераторына көбірек шақырулар жасайды (бір енгізу немесе жою операциясына O(log n) шақыру, бір шақырудың орнына) және түйінге ұрпақтар санын жаңарту қажеттілігіне байланысты енгізу процедурасы сәл күрделірек. Шағын техникалық айырмашылық – трепте соқтығысу ықтималдығы бар (екі кілт бірдей приоритетке ие болуы мүмкін), және екі жағдайда да нақты кездейсоқ сандар генераторы мен әдетте цифрлық компьютерлерде қолданылатын псевдо кездейсоқ сандар генераторы арасында статистикалық айырмашылықтар болады. Дегенмен, кез келген жағдайда алгоритмді жобалау үшін қолданылатын мінсіз кездейсоқ таңдаудың теориялық моделі мен нақты кездейсоқ сандар генераторларының мүмкіндіктері арасындағы айырмашылықтар ең аз болады. Трейп пен кездейсоқ екілік іздеу ағашының әрбір жаңартудан кейін ағаш пішіндерінің кездейсоқ таралуы бірдей болғанымен, осы екі дерек құрылымының енгізу және жою операциялары тізбегі бойынша ағаштарға енгізген өзгерістердің тарихы әртүрлі болуы мүмкін. Мысалы, егер 1, 2 және 3 сандары 1, 3, 2 ретімен енгізіліп, содан кейін 2 саны жойылса, қалған екі түйіннің ата-бала қатынасы ортаңғы сан енгізілгенге дейін болғандай болады. Кездейсоқ екілік іздеу ағашында жоюдан кейін қалған ағаш, ортаңғы сан енгізілгенге дейін ағаш қалай болғандығына қарамастан, екі түйіні бар екі мүмкін ағаштың бірі болуы мүмкін.

Кіргізу элементі

Позицияға элемент енгізу үшін массивті екі бөлікке бөлеміз: [0 pos 1] және [pos sz]. Бұл үшін split функциясын шақырып, екі ағаш аламыз. Содан кейін join функциясын шақырып, жаңа түйінмен біріктіреміз. Ақырында, join функциясын тағы да шақырып, екі ағашты біріктіреміз.

Элементті өшіру

Біз жойылатын элементті табамыз және оның L және R балаларын біріктіреміз. Содан кейін жойылатын элементті біріктіру операциясынан алынған ағашпен алмастырамыз.

Берілген диапазонда кері

Берілген түйіннің кіші ағашын әр түйін үшін кері қайтару қажеттігін көрсету үшін, біз қосымша логикалық R өрісін жасап, оның мәнін `true` деп белгілейміз. Бұл өзгерісті тарату үшін түйіннің балаларын ауыстырып, олардың барлығына R-ді `true` деп қоямыз.