Кіріспе

Келесі түйінге сілтеме жасайтын түйіндерден құралған дерек құрылымы. Компьютер ғылымында, байланысты тізім – дерек элементтерінің сызықтық жиынтығы, олардың реті жадтағы физикалық орналасуымен анықталмайды. Оның орнына, әрбір элемент келесі элементке сілтеме жасайды. Бұл – бірге тізбек құрайтын түйіндер жиынтығынан тұратын дерек құрылымы. Ең қарапайым түрінде, әрбір түйінде дерек және тізбектегі келесі түйінге сілтеме (яғни, байланыс) болады. Бұл құрылым, итерация кезінде тізбектің кез келген орнына элементтерді тиімді қосуға немесе жоюға мүмкіндік береді. Күрделірек нұсқалары қосымша сілтемелерді қосады, бұл тізбектің кез келген орнында түйіндерді тиімді қосуға немесе жоюға мүмкіндік береді. Байланысты тізімдердің бір кемшілігі – деректерге қол жеткізу уақыты тізімдегі түйіндер санына пропорционалды. Түйіндер тізбектей байланысқандықтан, кез келген түйінге қол жеткізу үшін алдыңғы түйінге бұрын қол жеткізу қажет (бұл құбырлық өңдеуде қиындықтар тудырады). Жылдам қол жеткізу, мысалы, тікелей қол жеткізу мүмкін емес. Массивтер байланысты тізімдерге қарағанда жадтың жақын орналасуын жақсырақ қамтамасыз етеді. Байланысты тізімдер – ең қарапайым және ең көп қолданылатын дерек құрылымдарының бірі. Олар тізімдер, стектер, кезектер, ассоциативтік массивтер және S-өрнектері сияқты басқа да көптеген абстрактілі дерек түрлерін жүзеге асыру үшін пайдаланылуы мүмкін, бірақ осы дерек құрылымдарын негіз ретінде байланысты тізімді пайдаланбастан тікелей жүзеге асыру да жиі кездеседі. Байланысты тізімнің дәстүрлі массивке қарағандағы басты артықшылығы – тізім элементтерін бүкіл құрылымды қайта бөлу немесе қайта ұйымдастыру қажеттілігінсіз оңай қосуға немесе жоюға болады, себебі дерек элементтерін жадта немесе дискіде үздіріліссіз сақтаудың қажеті жоқ, ал массивті орындау кезінде қайта құру әлдеқайда қымбат операция болып табылады. Байланысты тізімдер тізімдегі кез келген нүктеде түйіндерді қосуға және жоюға мүмкіндік береді, сондай-ақ тізімді қарау кезінде қосылатын немесе алынатын сілтемеге дейінгі сілтемені жадта сақтау арқылы тұрақты операцияларды орындауға мүмкіндік береді. Алайда, қарапайым байланысты тізімдер өздері деректерге тікелей қол жеткізуге немесе тиімді индекстеуге мүмкіндік бермейді, сондықтан көптеген негізгі операциялар – мысалы, тізімнің соңғы түйінін алу, белгілі бір деректерді қамтитын түйін табу немесе жаңа түйін енгізілуі керек жерді анықтау – тізім элементтерінің көпшілігін немесе барлығын қарап шығуды қажет етеді.

Тарих

Байланысты тізімдер 1955–1956 жылдары Ален Ньюэлл, Клифф Шоу және Герберт А. Саймон RAND Corporation және Carnegie Mellon University-де олардың Ақпаратты өңдеу тілі (IPL) үшін негізгі дерек құрылымы ретінде әзірленді. IPL авторлар жасанды интеллекттің бірнеше алғашқы бағдарламаларын, соның ішінде Логикалық теория машинасы, Жалпы проблеманы шешуші және компьютерлік шахмат бағдарламасын әзірлеу үшін пайдаланды. Олардың жұмысы туралы есептер 1956 жылы IRE Transactions on Information Theory және 1957–1959 жылдар аралығында бірнеше конференциялық қағаздарда, соның ішінде 1957 және 1958 жылдары Батыс бірлескен компьютерлік конференциясының қағаздарында және 1959 жылы Ақпаратты өңдеу (Ақпаратты өңдеу жөніндегі алғашқы ЮНЕСКО халықаралық конференциясының қағаздарында) жарияланды. Қазіргі классикалық диаграммада тізім түйіндерін көрсететін блоктар бар, ал тізім түйіндеріне бағытталған жебелер «Логикалық теория машинасына бағдарламалау» еңбегінде Ньюэлл мен Шоудың Proc. WJCC, 1957 жылғы ақпан айында пайда болды. Ньюэлл мен Саймон 1975 жылы ACM Тьюринг сыйлығымен «жасанды интеллектке, адам таным психологиясына және тізімдерді өңдеуге негізгі үлес қосқаны үшін» марапатталды. Табиғи тілді өңдеудегі машиналық аударма мәселесі Массачусетс технология институтындағы (MIT) Виктор Ингвеге лингвистика саласындағы компьютерлік зерттеулер үшін COMIT бағдарламалау тілінде байланысты тізімдерді дерек құрылымдары ретінде пайдалануға мүмкіндік берді. Осы тіл туралы «Машиналық аударма үшін бағдарламалау тілі» атты есеп 1958 жылы «Механикалық аударма» журналында жарияланды. Байланысты тізімдердің тағы бір ерте мысалы – 1953 жылғы қаңтарда IBM-нің ішкі меморандумында Ханс Питер Лун тізбелі хэш-кестелерде байланысты тізімдерді қолдануды ұсынды. LISP, «тізімді өңдеуші» деп аударылатын, 1958 жылы Джон Маккарти MIT-де оқып жүргенде жасалды, ал 1960 жылы ол оның дизайнын ACM Communications журналында «Символикалық өрнектердің рекурсивті функциялары және олардың машинамен есептелуі, 1-бөлім» атты мақаласында жариялады. LISP-тің маңызды дерек құрылымдарының бірі – байланысты тізім. 1960-шы жылдардың басында байланысты тізімдердің және осы құрылымдарды негізгі деректерді көрсету ретінде пайдаланатын тілдердің пайдалылығы толыққанды анықталды. MIT Lincoln Laboratory-сының Берт Грин 1961 жылғы наурыз айында IRE Transactions on Human Factors in Electronics журналында «Символдарды манипуляциялауға арналған компьютерлік тілдер» атты шолу мақаласын жариялады, онда байланысты тізімдер тәсілінің артықшылықтары жинақталды. Кейінгі шолу мақаласы, Боброу мен Рафаэльдің «Тізімді өңдеуге арналған компьютерлік тілдердің салыстыруы» 1964 жылғы сәуірде ACM Communications журналында жарияланды. Техникалық жүйелер консультанттары (алғашқыда Индиана штатының Батыс Лафайетте қаласынан, кейін Солтүстік Каролина штатының Чапел-Хилл қаласынан) әзірлеген бірнеше операциялық жүйелер файлдық құрылым ретінде жеке байланысты тізімдерді пайдаланды. Каталог жазуы файлдың бірінші секторына сілтеме жасады, ал файлдың келесі бөліктері сілтемелерді аралау арқылы анықталды. Бұл әдісті қолданатын жүйелерге Flex (Motorola 6800 CPU үшін), mini Flex (осы CPU) және Flex9 (Motorola 6809 CPU үшін) кірді. Калифорниядағы Smoke Signal Broadcasting компаниясы үшін TSC әзірлеген және сатқан нұсқасы екі есе байланысты тізімдерді дәл осылай пайдаланды. IBM-нің System 360/370 машиналары үшін әзірлеген TSS/360 операциялық жүйесі файлдық жүйесінің каталогы үшін қос байланысты тізімді пайдаланды. Каталог құрылымы Unix-ке ұқсас болды, онда каталог файлдар мен басқа каталогтарды қамти алады және кез келген тереңдікке дейін кеңейе алады.

Негізгі түсініктер және номенклатура

Байланыс тізімінің әрбір жазбасын көбінесе "элемент" немесе "түйін" деп атайды. Келесі түйіннің мекенжайын қамтитын әрбір түйіннің өрісі әдетте "келесі сілтеме" немесе "келесі көрсеткіш" деп аталады. Қалған өрістер "дерек", "ақпарат", "мәні", "жүк" немесе "пайдалы жүктеме" өрістері деп аталады. Тізімнің "басы" оның бірінші түйіні болып табылады. Тізімнің "құйрығы" тізімнің басынан кейінгі бөлігіне немесе тізімдегі соңғы түйінге сілтеме жасай алады. Lisp және кейбір туынды тілдерде келесі түйін тізімнің 'cdr' (айтылады) деп аталуы мүмкін, ал бас түйіннің пайдалы жүктемесін 'car' деп атауға болады.

Екі рет байланысты тізім

Екі есе байланысқан тізімде әрбір түйін келесі түйінге сілтемеден басқа, тізбектегі "алдыңғы" түйінге нұсқайтын екінші сілтеме өрісін қамтиды. Бұл екі сілтеме "алға" және "артқа", немесе "келесі" және "бұрынғы" деп аталуы мүмкін. XOR байланыстыру деп аталатын техника, әрбір түйінде бір сілтеме өрісін пайдалана отырып, екі есе байланысқан тізімді жүзеге асыруға мүмкіндік береді. Дегенмен, бұл техника адрестерге биттік операциялар жасау мүмкіндігін талап етеді, сондықтан кейбір жоғары деңгейлі тілдерде қолжетімді болмауы мүмкін. Көптеген қазіргі заманғы операциялық жүйелер белсенді процестерге, жіптерге және басқа да динамикалық объектілерге сілтемелерді сақтау үшін екі есе байланысқан тізімдерді пайдаланады. Руткиттердің анықталудан қашуының кең таралған стратегиясы – осы тізімдерден өздерін алып тастау.

Көбейтіліп байланыстырылған тізім

Көп байланысты тізімде әр түйінде екі немесе одан көп байланыс өрісі болады, әрбір өріс бірдей деректер жиынтығын әртүрлі тәртіппен (мысалы, аты бойынша, бөлімі бойынша, туған күні бойынша және т.б.) байланыстыру үшін қолданылады. Екі есе байланысқан тізім көп байланысты тізімнің ерекше жағдайы болып табылады, бірақ екі немесе одан көп тәртіп бір-біріне қарама-қарсы болғандықтан, бұл қарапайым және тиімді алгоритмдерге алып келеді, сондықтан олар көбінесе жеке жағдай ретінде қарастырылады.

Айналмалы түрде байланысты тізім

Байланыс тізімінің соңғы түйініндегі сілтеме өрісі көбінесе null сілтемесін қамтиды, бұл арнайы мән қосымша түйіндердің жоқтығын көрсетеді. Кем кездесетін жағдай – оны тізімнің бірінші түйініне бағыттау; мұндай жағдайда тізім "айналмалы" немесе "айналымды байланысқан" деп аталады, ал әйтпесе – "ашық" немесе "сызықтық" деп аталады. Бұл соңғы түйіннің көрсеткіші бірінші түйінге сілтейтін тізім (яғни соңғы түйіннің "келесі сілтеме" көрсеткіші бірінші түйіннің жад мекенжайын сақтайды). Айналмалы екі жақты байланысқан тізімде бірінші түйін тізімнің соңғы түйініне де сілтеме жасайды.

Қараушы тораптар

Кейбір жағдайларда, бірінші дерек жазбасының алдына немесе соңғы дерек жазбасынан кейін қосымша "күзетші" немесе "фальш" түйін қосылуы мүмкін. Бұл тәсіл кейбір тізімді басқару алгоритмдерін оңайлатып, жылдамдатады, себебі барлық сілтемелерді қауіпсіз түрде қолдануға болады және кез келген тізімде (дерек элементтері жоқ тізімдерде де) әрқашан "бірінші" және "соңғы" түйін болады.

Бос тізімдер

Бос тізім — дерек жазбалары жоқ тізім. Бұл көбінесе тізімде нөл түйін бар дегенмен бірдей. Егер күзетші түйіндер қолданылса, тізімде тек күзетші түйіндер болғанда ғана ол бос деп есептеледі.

Хаш-байланыс

Байланыс өрістері түйіндердің физикалық бөлігі болуы міндетті емес. Егер дерек жазбалары массивте сақталса және олардың индекстері арқылы сілтеме жасалса, байланыс өрісі дерек жазбаларымен бірдей индекстері бар жеке массивте сақталуы мүмкін.

Тізім тұтқалары

Бірінші түйінге сілтеме бүкіл тізімге қол жеткізуді қамтамасыз ететіндіктен, бұл сілтеме жиі тізімнің "мекенжайы", "көрсеткіші" немесе "басқарушысы" деп аталады. Тізімдік тізімдермен жұмыс жасайтын алгоритмдер әдетте кіріс тізімдеріне осындай басқарушыларды алады және нәтижелі тізімдерге басқарушыларды қайтарады. Шындығында, мұндай алгоритмдер контекстінде "тізім" сөзі көбінесе "тізім басқарушысы" дегенді білдіреді. Дегенмен, кейбір жағдайларда тізімге оның бірінші және соңғы түйіндеріне көрсетіп тұрған екі сілтемеден тұратын басқарушы арқылы сілтеме жасау ыңғайлы болуы мүмкін.

Баламаларды біріктіру

Жоғарыда тізілген баламаларды дерлік кез келген тәсілмен ерікті түрде үйлестіруге болады, сондықтан күзетшілерсіз екі жақты дөңгелек тізімдер, күзетшілермен бір жақты дөңгелек тізімдер және т.б. болуы мүмкін.

Компромистік факторлар

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

Сілтемеленген тізімдер мен динамикалық массивтер

Динамикалық массив — жадыда барлық элементтерді тізбектей орналастыратын және қазіргі элементтер санын есептейтін дерек құрылымы. Динамикалық массивке бөлінген орын жетіспесе, ол қайта бөлінеді және (мүмкін) көшіріледі, бұл қымбат операция. Тізбекті тізімдер динамикалық массивтерге қарағанда бірнеше артықшылықтарға ие. Егер біз тізімдегі түйінге (жойылатын түйінден бұрын немесе енгізу орнынан бұрын) сілтемеге ие болсақ, тізімнің белгілі бір жеріне элементті енгізу немесе жою тұрақты уақыт операциясы болып табылады (әйтпесе, сілтемесіз O(n) уақыт алады), ал кездейсоқ жерлерге динамикалық массивке енгізу орташа есеппен элементтердің жартысын, ал ең жаман жағдайда барлық элементтерді жылжытуды қажет етеді. Массивтен элементті "бос" деп белгілеп, тұрақты уақыт ішінде "жоюға" болады, бірақ бұл итерацияның өнімділігіне кедері келтіретін фрагментацияға әкеледі. Сонымен қатар, тізбекті тізімге кез келген сандағы элементтерді енгізуге болады, бұл тек жалпы жад көлемімен шектеледі; ал динамикалық массив ақырында негізгі массивтік дерек құрылымын толтырып, қымбат операция — қайта бөлуді қажет етеді, егер жад фрагменттелген болса, ол тіпті мүмкін болмайды, бірақ қайта бөлу құнын енгізулерге орташалап есептеуге болады, сондай-ақ қайта бөлуден туындаған енгізу құны да амортизацияланған O(1) болады. Бұл массивтің соңына элементтерді қосуға көмектеседі, бірақ ортаңғы позицияларға енгізу (немесе жою) деректерді жылжытуға байланысты әлі де тым жоғары шығындарға әкеледі. Көптеген элементтер алынып тасталған массивтің көлемін де тым көп орынды ысырап ету үшін өзгертуге болады. Керісінше, динамикалық массивтер (сондай-ақ, белгілі өлшемді массивтік дерек құрылымдары) тұрақты уақыт ішінде кездейсоқ қол жеткізуге мүмкіндік береді, ал тізбекті тізімдер элементтерге тек тізбектеп қол жеткізуге мүмкіндік береді. Шын мәнінде, бір бағытты тізбекті тізімдерді бір бағытта ғана оңай аралауға болады. Бұл тізбекті тізімдерді элементті оның индексі бойынша жылдам іздеуге болатын қолданбалар үшін жарамсыз етеді, мысалы, heapsort. Көптеген машиналарда массивтер мен динамикалық массивтердегі тізбектеп қол жеткізу тізбекті тізімдерге қарағанда жылдамырақ, өйткені олар сілтемелердің оңтайлы орналасуына ие және деректер кэшін жақсы пайдаланады. Тізбекті тізімдердің тағы бір кемшілігі — сілтемелерге қажетті қосымша жад, бұл оларды кейде кішкентай дерек элементтерінің тізімдері үшін, мысалы, таңбалар немесе логикалық мәндер үшін практикалық емес етеді, өйткені сілтемелердің жад шығыны деректердің мөлшерінен екі немесе одан да көп есе артық болуы мүмкін. Керісінше, динамикалық массивке тек деректерге арналған орын (және өте аз басқару деректері) қажет. Сондай-ақ, ол баяу болуы мүмкін, ал қарапайым бөлушімен әр жаңа элемент үшін жадыны бөлек бөлу, жадты тиімді пайдалану арқылы шешілетін мәселе. Кейбір гибридтік шешімдер екі бейнелеудің артықшылықтарын біріктіруге тырысады. Ашылмаған тізбекті тізімдер әр тізім түйінінде бірнеше элементтерді сақтайды, бұл кэштің өнімділігін арттырады, сонымен бірге сілтемелердің жад шығынын азайтады. CDR кодтау осы екеуін де орындайды, сілтемелерді сілтемеленген нақты деректермен алмастырады, бұл сілтеме жазбасының соңынан созылады. Динамикалық массивтерді және тізбекті тізімдерді пайдаланудың артықшылықтары мен кемшіліктерін көрсететін жақсы мысал — Иосиф Флавий мәселесін шешетін бағдарламаны іске асыру. Иосиф Флавий мәселесі — бұл сайлау әдісі, ол адамдар тобын шеңберге орналастыру арқылы жұмыс істейді. Алдын ала белгіленген адамнан бастап, шеңберді n рет санауға болады. N-ші адамға жеткеннен кейін оны шеңберден алып тастап, мүшелер шеңберді жабады. Бұл процесс тек бір адам қалғанша қайталанады. Бұл адам сайлауда жеңіске жетеді. Бұл тізбекті тізімнің күшті және әлсіз жақтарын динамикалық массивке қарсы көрсетеді, өйткені егер адамдар шеңберлі тізбекті тізімдегі байланысты түйіндер ретінде қарастырылса, онда тізбекті тізім түйіндерді қалай оңай жоя алатынын көрсетеді (тек әртүрлі түйіндерге сілтемелерді қайта орналастыру қажет). Алайда, тізбекті тізім келесі адамды табуға жарамсыз болады және ол адамды тапқанша тізімді іздеуі керек болады. Динамикалық массив, керісінше, түйіндерді (немесе элементтерді) жоюда нашар болады, өйткені ол тізімдегі барлық элементтерді бір-бірден жылжырмастан жоя алмайды. Алайда, массивтегі олардың орны бойынша тікелей сілтеме арқылы шеңбердегі n-ші адамды табу өте оңай. Тізімді реттеу мәселесі тізбекті тізімді массивке тиімді түрлендіруге қатысты. Дәстүрлі компьютер үшін тривиальды болса да, бұл мәселені параллель алгоритммен шешу қиын және көп зерттеулердің нысаны болды. Теңгерілген ағаш тізбекті тізім сияқты жадқа қол жеткізу үлгілеріне және жад шығындарына ие, бірақ кездейсоқ қол жеткізуді әлдеқайда тиімді етуге мүмкіндік береді, O(log n) уақыт алады, ал тізбекті тізімде O(n) уақыт алады. Алайда, ағаштың тепе-теңдігін сақтау үшін жасалатын манипуляцияларға байланысты енгізу және жою операциялары қымбат. Ағаштардың автоматты түрде тепе-теңдік күйін сақтау схемалары бар: AVL ағаштары немесе қызыл-қара ағаштар.

Бір-бірімен байланыстырылатын сызықтық тізімдер мен басқа тізімдер

Екі есе байланысқан және дөңгелек тізімдердің бір-бірімен байланысқан сызықтық тізімдерге қарағанда артықшылықтары бар, бірақ сызықтық тізімдер кейбір жағдайларда олардан артықшылықтарға ие. Бір-бірімен байланыстырылған сызықтық тізім – рекурсивті дерек құрылымы, себебі ол өзінің түріндегі кішірек объектіге сілтеме береді. Осы себепті, бір-бірімен байланысқан сызықтық тізімдердегі көптеген операциялар (мысалы, екі тізімді біріктіру немесе элементтерді кері ретпен санау) көбінесе өте қарапайым рекурсивті алгоритмдерге ие, олар итеративті командаларды қолданатын кез келген шешімнен әлдеқайда қарапайым. Бұл рекурсивті шешімдерді екі есе байланысқан және дөңгелек байланысқан тізімдер үшін бейімдеуге болады, бірақ процедураларға көбінесе қосымша аргументтер мен күрделірек базалық жағдайлар қажет. Сызықтық, жеке байланысты тізімдер сондай-ақ екі түрлі тізімнің соңғы бөлігі ретінде қосалқы тізімнің ортақ соңғы бөлігін пайдалануға мүмкіндік береді – құйрықты бөлісу. Атап айтқанда, тізімнің басына жаңа түйін қосылса, бұрынғы тізім жаңа тізімнің құйрығы ретінде қолжетімді болады – тұрақты дерек құрылымының қарапайым мысалы. Бұл басқа нұсқаларда дұрыс емес: түйін ешқашан екі түрлі дөңгелек немесе екі есе байланысқан тізімге жатпауы мүмкін. Атап айтқанда, соңғы белгішелер жеке байланысты, дөңгелек емес тізімдер арасында бөлісе алады. Әрбір мұндай тізім үшін бірдей соңғы белгішені пайдалануға болады. Мысалы, Lisp-те әрбір дұрыс тізім арнайы белгішеге сілтемемен аяқталады, ол nil деп белгіленеді. Күрделі нұсқалардың артықшылықтары көбінесе олардың тиімділігінде емес, алгоритмдердің күрделілігінде болады. Дөңгелек тізімді, әдетте, бірінші және соңғы түйіндерге сілтейтін екі айнымалымен бірге сызықтық тізіммен эмуляциялауға болады, бұл қосымша шығынға түспейді.

Екі еселенген немесе бір реттелген

Қос байланысты тізімдер әр түйінге көбірек орын қажет етеді (егер XOR байланысы қолданылмаса), сондай-ақ олардың қарапайым операциялары да қымбатқа түседі; бірақ оларды манипуляциялау оңайрақ, себебі олар тізімге екі бағытта да жылдам және оңай тізбекпен қол жеткізуге мүмкіндік береді. Қос байланысты тізімде, тек түйіннің мекенжайы белгілі болса, түйін енгізу немесе жою операцияларын тұрақты санда орындауға болады. Бір байланысты тізімде осылай істеу үшін, сол түйінге көрсетушінің мекенжайы болуы керек, ол тізімнің бастапқы түйіні болған жағдайда тізімнің тұтқасы, ал басқа жағдайда алдыңғы түйіндегі көрсетуші саласы болады. Кейбір алгоритмдер екі бағытта да қолжетімділік қажет етеді. Алайда, қос байланысты тізімдер құйрық бөлісуге мүмкіндік бермейді және оларды тұрақты деректер құрылымы ретінде қолдануға болмайды.

Сұлбалық байланыстар мен сызықтық байланыстар

Дөңгелек тізбекті тізім, табиғаты бойынша дөңгелек массивтерді көрсетудің табиғи нұсқасы болуы мүмкін, мысалы, көпбұрыштың төбелері, FIFO ("бірінші кірген, бірінші шыққан") тәртібінде пайдаланылатын және босатылатын буферлер жиынтығы немесе дөңгелек робин тәртібімен уақыт бөлінетін процестер жиынтығы. Бұл қолданбаларда кез келген түйінге сілтеме бүкіл тізімге қолжеткізу құралы ретінде қызмет етеді. Дөңгелек тізімде соңғы түйінге сілтеме жасау, бір сілтемені бақылап, бірінші түйінге де оңай қол жеткізуге мүмкіндік береді. Осылайша, тізімнің екі басына да қол жеткізуді қажет ететін қолданбаларда (мысалы, кезекті жүзеге асыру кезінде) дөңгелек құрылым бір көрсеткіш арқылы құрылымды басқаруға мүмкіндік береді, екі емес. Дөңгелек тізімді әр бөліктің соңғы түйінінің мекенжайларын көрсету арқылы тұрақты уақытта екі дөңгелек тізімге бөлуге болады. Операция осы екі түйіннің сілтеме өрістерінің мазмұнын ауыстырудан тұрады. Екі түрлі тізімдегі кез келген екі түйінге бірдей операцияны қолдану екі тізімді біріктіреді. Бұл қасиет кейбір алгоритмдер мен дерек құрылымдарын, мысалы, төрт қырлы және беттік қырларды жеңілдетеді. Бос дөңгелек тізімді көрсетудің ең қарапайым тәсілі (мұндай нәрсе мағыналы болған жағдайда) – бұл null көрсеткіш, ол тізімде түйіндердің жоқтығын көрсетеді. Бұл таңдаусыз көптеген алгоритмдер осы ерекше жағдайды тексеруге және оны бөлек өңдеуге мәжбүр болады. Керісінше, бос сызықтық тізімді көрсету үшін null пайдалану көбінесе табиғирақ және аз ерекше жағдайлар тудырады. Кейбір қолданбалар үшін дөңгелек және сызықтық немесе тіпті сызықтық бастапқы сегменті бар дөңгелек болуы мүмкін жеке тізбекті тізімдерді пайдалану пайдалы болуы мүмкін. Оларды іздеу немесе басқаша жұмыс істеу алгоритмдері кездейсоқ шексіз циклге түсіп кетпеу үшін сақтық шараларын қабылдауы керек. Белгілі бір әдіс – екінші көрсеткіштің тізімді жартылай немесе екі есе жылдамдықпен жүріп өтуі, егер екі көрсеткіш бір түйінде кездессе, цикл табылды деп білуге болады.

Сентинеллік тораптарды пайдалану

Күзетші түйін кейбір тізім операцияларын жеңілдетуі мүмкін, әр элемент үшін келесі немесе алдыңғы түйіндердің болуын қамтамасыз ету арқылы, тіпті бос тізімдерде де кем дегенде бір түйіннің бар екендігін кепілдік беру арқылы. Тізімнің соңындағы кейбір тексерулерді болдырмау үшін, тиісті деректер өрісі бар күзетші түйін тізімнің соңында қолданылуы мүмкін. Мысалы, тізімді белгілі бір x мәні бар түйін іздеу кезінде, күзетшінің деректер өрісін x-ке орнату тізімнің соңына тексеру қажеттілігін жояды. Тағы бір мысал – екі сұрыпталған тізімді біріктіру: егер олардың күзетшілерінің деректер өрісі +∞ мәніне тең болса, келесі шығыс түйінін таңдау бос тізімдер үшін ерекше өңдеуді қажет етпейді. Дегенмен, күзетші түйіндері қосымша орынды пайдаланады (әсіресе көптеген қысқа тізімдерді қолданатын жағдайларда) және басқа операцияларды күрделендіруі мүмкін (мысалы, жаңа бос тізімді құру). Бірақ, егер дөңгелек тізім тек сызықтық тізімді модельдеу үшін қолданылса, соңғы және алғашқы деректер түйіндерінің арасына бір күзетші түйін қосу арқылы осы күрделіліктің бір бөлігін болдырмауға болады. Осы келісім бойынша, бос тізім тек қана күзетші түйінінен тұрады, ол келесі түйін сілтемесі арқылы өзіне сілтейді. Тізімді басқарушы, тізім бос емес болса, күзетшіден бұрынғы соңғы деректер түйініне, ал тізім бос болса, күзетшінің өзіне сілтеме болуы керек. Осы тәсілді екі бағытты сызықтық тізімді бір күзетші түйіні бар екі бағытты дөңгелек тізімге айналдыру арқылы оны басқаруды жеңілдету үшін де қолдануға болады. Алайда, бұл жағдайда тұтқаның өзі сол қалта түйінге сілтеме болуы керек.

Байланысты тізімдегі операциялар

Байланысты тізімдерді өзгерте отырып жұмыс істегенде, бұрынғы тапсырмаларда қолданудан шығарылған мәндерді пайдаланбауға көңіл болу керек. Бұл байланысты тізімдерге түйіндерді қосу немесе жою алгоритмдерін күрделі етеді. Осы бөлімде, жеке, қос және шеңберлік байланысты тізімдерден түйіндерді орнында қосу немесе жою үшін псевдокод келтіріледі. Біз тізім соңының белгісі немесе күзетші ретінде "null" терминін қолданамыз, оны әртүрлі тәсілдермен іске асыруға болады.

Байланысты дерек құрылымдары

Стектер мен кезектер көбінесе байланысқан тізімдерді пайдаланып іске асырылады, бұл қолдау көрсетілетін операциялардың түрін шектейді. Скип тізімі – бұл көптеген элементтерден жылдам өту үшін және келесі қабатқа түсу үшін қабаттармен толықтырылған байланысқан тізім. Бұл процесс тізімнің негізгі қабатына дейін жалғасады. Бинарлық ағаш – элементтері бірдей сипаттағы тізімдер болатын байланысқан тізімнің бір түрі деп қарауға болады. Нәтижесінде, әрбір түйін басқа бір немесе екі байланысқан тізімнің бірінші түйініне сілтеме жасай алады, олар мазмұнымен бірге осы түйіннің астындағы кіші ағаштарды құрайды. Ашылмаған байланысқан тізім – әрбір түйінінде деректердің массиві бар байланысқан тізім. Бұл кэштің жұмысын жақсартады, себебі тізім элементтерінің көп бөлігі жадта біріктірілген болады, сондай-ақ жадтың артық шығындары азаяды, өйткені тізімнің әрбір элементі үшін аз метадеректерді сақтау қажет. Хеш-кестеде бір орында хеш-тегісі бірдей элементтердің тізбектерін сақтау үшін байланысқан тізімдерді пайдалануға болады. Жинақ байланысқан тізімнің кейбір реттелу қасиеттерін бөліседі, бірақ көбінесе массивті пайдаланады. Түйіндер арасындағы сілтемелердің орнына, келесі және алдыңғы дерек индекстері ағымдағы деректің индексі арқылы есептеледі. Өзін-өзі ұйымдастыратын тізім деректерді іздеу уақытын қысқарту үшін, жиі қол жеткізілетін түйіндерді тізімнің басында ұстап, кейбір эвристикалық принциптер бойынша түйіндерін қайта ұйымдастырады.