Sveiki visiem
Å ajÄ piezÄ«mÄ es nolÄmu uzskaitÄ«t galvenÄs datu struktÅ«ras, ko izmanto grafiku glabÄÅ”anai datorzinÄtnÄs, un es arÄ« runÄÅ”u par vÄl pÄris Å”ÄdÄm struktÅ«rÄm, kas man kaut kÄ āizkristalizÄjÄsā.
TÄtad, sÄksim. Bet ne jau no paÅ”a sÄkuma ā es domÄju, ka mÄs visi jau zinÄm, kas ir grafs un kas tas ir (virzÄ«ts, nevirzÄ«ts, svÄrts, nesvÄrts, ar vai bez vairÄkÄm malÄm un cilpÄm).
TÄtad, ejam. KÄdas datu struktÅ«ras iespÄjas āgrafu glabÄÅ”anaiā mums ir?
1. Matricas datu struktūras
1.1 Blakus matrica. Blakus matrica ir matrica, kurÄ rindu un kolonnu virsraksti atbilst grafa virsotÅu numuriem, un katra tÄs elementa vÄrtÄ«bu a(i,j) nosaka malu esamÄ«ba vai neesamÄ«ba starp virsotnÄm. i un j (ir skaidrs, ka nevirzÄ«tam grafikam Å”Äda matrica bÅ«s simetriska, vai arÄ« varam vienoties, ka visas vÄrtÄ«bas glabÄjam tikai virs galvenÄs diagonÄles). NesvÄrtajiem grafiem a(i,j) var iestatÄ«t pÄc ŔķautÅu skaita no i lÄ«dz j (ja tÄdas nav, tad a(i,j)= 0), bet svÄrtajiem grafiem arÄ« pÄc svara. (kopÄjais svars) minÄto malu.
1.2 SaslimstÄ«bas matrica. Å ajÄ gadÄ«jumÄ mÅ«su grafs tiek saglabÄts arÄ« tabulÄ, kurÄ parasti rindu numuri atbilst tÄs virsotÅu numuriem, bet kolonnu numuri atbilst iepriekÅ” numurÄtÄm malÄm. Ja virsotne un mala atrodas viena pret otru, tad attiecÄ«gajÄ Å”Å«nÄ ieraksta vÄrtÄ«bu, kas nav nulle (nevirzÄ«tiem grafiem raksta 1, ja virsotne un mala ir krÄ«toÅ”as, orientÄtiem grafiem - ā1ā, ja mala āizietā no virsotnes un ā-1ā, ja tas tajÄ āietverā (to ir pietiekami viegli atcerÄties, jo Ŕķiet, ka āmÄ«nusaā zÄ«me ir āiekļautaā arÄ« ciparÄ ā-1ā). SvÄrtajiem grafikiem atkal 1 un -1 vietÄ varat norÄdÄ«t malas kopÄjo svaru.
2. UzskaitīŔanas datu struktūras
2.1 Blakus esoÅ”o saraksts. Nu Å”eit viss Ŕķiet vienkÄrÅ”i. Katru grafa virsotni kopumÄ var saistÄ«t ar jebkuru uzskaites struktÅ«ru (saraksts, vektors, masÄ«vs, ...), kurÄ tiks saglabÄti visu virsotÅu numuri, kas atrodas blakus dotajai virsotnei. VirzÄ«tajiem grafiem mÄs pievienosim Å”Ädam sarakstam tikai tÄs virsotnes, kurÄm ir āvirzÄ«taā mala no objekta virsotnes. SvÄrtajiem grafikiem ievieÅ”ana bÅ«s sarežģītÄka.
2.2 Ribu saraksts. Diezgan populÄra datu struktÅ«ra. Malu saraksts, kÄ mums stÄsta Captain Obviousness, patiesÄ«bÄ ir grafa ŔķautÅu saraksts, no kurÄm katra ir norÄdÄ«ta ar sÄkuma virsotni, beigu virsotni (nevirzÄ«tiem grafiem secÄ«ba Å”eit nav svarÄ«ga, lai gan apvienoÅ”anai var izmantojiet dažÄdus noteikumus, piemÄram, virsotÅu norÄdÄ«Å”anu pieauguma secÄ«bÄ un svaru (tikai svÄrtajiem grafikiem).
JÅ«s varat apskatÄ«t iepriekÅ” minÄtos matricu sarakstus sÄ«kÄk (un ar ilustrÄcijÄm), piemÄram,
2.3 Blakus masÄ«vs. Nav visizplatÄ«tÄkÄ struktÅ«ra. SavÄ bÅ«tÄ«bÄ tas ir veids, kÄ āiesaiÅotā blakus sarakstus vienÄ uzskaites struktÅ«rÄ (masÄ«vÄ, vektorÄ). Å Äda masÄ«va pirmie n (pÄc grafa virsotÅu skaita) elementi satur viena un tÄ paÅ”a masÄ«va sÄkuma indeksus, no kuriem pÄc kÄrtas tiek ierakstÄ«tas visas dotajam blakus esoÅ”Äs virsotnes.
Å eit es atradu sev saprotamÄko skaidrojumu:
3. Blakusuma vektors un asociatīvais blakus masīvs
IzrÄdÄ«jÄs, ka Å”o rindu autors, nebÅ«dams profesionÄls programmÄtÄjs, bet periodiski nodarbojies ar grafiem, visbiežÄk nodarbojies ar ŔķautÅu sarakstiem. PatieÅ”Äm, tas ir Ärti, ja grafikÄ ir vairÄkas cilpas un malas. Un tÄpÄc, izstrÄdÄjot klasiskos ŔķautÅu sarakstus, es ierosinu pievÄrst uzmanÄ«bu to āattÄ«stÄ«bai/atzarojumam/modifikÄcijai/mutÄcijaiā, proti: blakus vektoram un asociatÄ«vajam blakus masÄ«vam.
3.1. Blakus vektors
GadÄ«jums (a1): nesvÄrts grafiks
Par blakus vektoru nesvÄrtam grafam sauksim sakÄrtotu pÄra veselu skaitļu kopu (a[2i], a[2i+1],..., kur i ir numurÄts c 0), kurÄ katrs skaitļu pÄris ir a[2i], a[2i+1 ] norÄda grafa malu attiecÄ«gi starp virsotnÄm a[2i] un a[2i+1].
Å is ieraksta formÄts nesatur informÄciju par to, vai grafiks ir vÄrsts (iespÄjamas abas iespÄjas). Lietojot divkÄrÅ”u formÄtu, tiek uzskatÄ«ts, ka mala ir vÄrsta no a[2i] uz a[2i+1]. Å eit un tÄlÄk: nevirzÄ«tiem grafiem, ja nepiecieÅ”ams, var piemÄrot prasÄ«bas virsotÅu ierakstÄ«Å”anas secÄ«bai (piemÄram, virsotne ar zemÄku tai pieŔķirtÄ skaitļa vÄrtÄ«bu).
ProgrammÄ C++ ir ieteicams norÄdÄ«t blakus vektoru, izmantojot std::vector, lÄ«dz ar to arÄ« Ŕīs datu struktÅ«ras nosaukumu.
GadÄ«jums (a2): nesvÄrts grafiks, malu svari ir veseli skaitļi
PÄc analoÄ£ijas ar gadÄ«jumu (a1) mÄs saucam blakus vektoru svÄrtam grafikam ar veselu skaitļu malu svaru par sakÄrtotu skaitļu kopu (dinamisko masÄ«vu) (a[3i], a[3i+1], a[3i+2], ..., kur i ir numurÄts c 0), kur katrs skaitļu a[3i], a[3i+1], a[3i+2] ātripletsā norÄda grafa malu starp virsotnÄm, kas numurÄtas a[3i] un a[3i+1], un vÄrtÄ«ba a [3i+2] ir Ŕīs malas svars. Å Äds grafiks var bÅ«t arÄ« virzÄ«ts vai nÄ.
GadÄ«jums (b): nesvÄrts grafiks, malu svari, kas nav veseli skaitļi
TÄ kÄ, piemÄram, vienÄ masÄ«vÄ (vektorÄ) nav iespÄjams uzglabÄt neviendabÄ«gus elementus, ir iespÄjama Å”Äda realizÄcija. Grafs tiek saglabÄts vektoru pÄrÄ«, kurÄ pirmais vektors ir grafika blakus vektors, nenorÄdot svarus, bet otrais vektors satur atbilstoÅ”os svarus (iespÄjama C++ ievieÅ”ana: std::pair ). TÄdÄjÄdi malai, ko nosaka virsotÅu pÄris zem pirmÄ vektora indeksiem 2i, 2i+1, svars bÅ«s vienÄds ar elementu zem otrÄ vektora indeksa i.
Nu, kÄpÄc tas ir vajadzÄ«gs?
Å o rindu autoram tas Ŕķita diezgan noderÄ«gs vairÄku problÄmu risinÄÅ”anai. No formÄlÄ viedokļa bÅ«s Å”Ädas priekÅ”rocÄ«bas:
- Blakus vektors, tÄpat kÄ jebkura cita āuzskaitÄmÄā struktÅ«ra, ir diezgan kompakts, aizÅem mazÄk atmiÅas nekÄ blakusesÄ«bas matrica (retiem grafikiem) un ir salÄ«dzinoÅ”i viegli Ä«stenojams.
- Grafa virsotnes principÄ var atzÄ«mÄt arÄ« ar negatÄ«viem skaitļiem. Ko darÄ«t, ja Å”Äda "izvirtÄ«ba" ir vajadzÄ«ga?
- Grafikos var bÅ«t vairÄkas malas un vairÄkas cilpas ar atŔķirÄ«gu svaru (pozitÄ«vs, negatÄ«vs, pat nulle). Å eit nav nekÄdu ierobežojumu.
- Varat arÄ« pieŔķirt malÄm dažÄdus rekvizÄ«tus, bet par to vairÄk skatiet 4. sadaļÄ.
TomÄr jÄatzÄ«st, ka Å”is āsarakstsā nenozÄ«mÄ Ätru piekļuvi malai. Un Å”eit palÄ«gÄ nÄk Associative Adjacency Array, kas tiek apspriests tÄlÄk.
3.2. Asociatīvais blakus masīvs
TÄtad, ja piekļuve konkrÄtai malai, tÄs svaram un citÄm Ä«paŔībÄm mums ir kritiska, un atmiÅas prasÄ«bas neļauj izmantot blakusesÄ«bas matricu, tad padomÄsim, kÄ mÄs varam mainÄ«t blakusesÄ«bas vektoru, lai atrisinÄtu Å”o problÄmu. TÄtad atslÄga ir grafika mala, kuru var norÄdÄ«t kÄ sakÄrtotu veselu skaitļu pÄri. KÄ tas izskatÄs? Vai tÄ nav atslÄga asociatÄ«vajÄ masÄ«vÄ? Un, ja tÄ, kÄpÄc mÄs to neieviesÄm? Ä»aujiet mums izveidot asociatÄ«vu masÄ«vu, kurÄ katra atslÄga - sakÄrtots veselu skaitļu pÄris - tiks saistÄ«ts ar vÄrtÄ«bu - veselu skaitli vai reÄlu skaitli, kas norÄda malas svaru. C++ valodÄ Å”o struktÅ«ru ieteicams ieviest, pamatojoties uz std::map konteineru (std::map , int> vai std::map , double>) vai std::multimap, ja ir paredzÄtas vairÄkas malas. Mums ir struktÅ«ra grafu glabÄÅ”anai, kas aizÅem mazÄk atmiÅas nekÄ āmatricasā struktÅ«ras, var definÄt grafikus ar vairÄkÄm cilpÄm un malÄm, un tai pat nav stingru prasÄ«bu virsotÅu skaitļu nenegatÄ«vÄ«bai (es nezinu kam tas vajadzÄ«gs, bet tomÄr).
4. Datu struktÅ«ras ir pilnas, bet kaut kÄ pietrÅ«kst
Un tÄ ir taisnÄ«ba: risinot vairÄkas problÄmas, mums, iespÄjams, bÅ«s jÄpieŔķir daži raksturlielumi grafika malÄm un attiecÄ«gi jÄsaglabÄ. Ja ir iespÄjams viennozÄ«mÄ«gi Ŕīs pazÄ«mes reducÄt lÄ«dz veseliem skaitļiem, tad Å”Ädus āgrafikus ar papildu pazÄ«mÄmā iespÄjams uzglabÄt, izmantojot blakus vektora un asociatÄ«vÄ blakus masÄ«va paplaÅ”inÄtÄs versijas.
TÄtad, pieÅemsim neizsvÄrtu grafiku, kura katrai malai ir nepiecieÅ”ams saglabÄt, piemÄram, 2 papildu pazÄ«mes, kas norÄdÄ«tas ar veseliem skaitļiem. Å ajÄ gadÄ«jumÄ ir iespÄjams definÄt tÄ blakus vektoru kÄ sakÄrtotu kopu, kas nav āpÄruā, bet gan veselu skaitļu ākvartetuā (a[2i], a[2i+1], a[2i+2], a [2i+3]ā¦) , kur a[2i+2] un a[2i+3] noteiks atbilstoÅ”Äs malas raksturlielumus. Grafikam ar malu veseliem skaitļiem secÄ«ba parasti ir lÄ«dzÄ«ga (vienÄ«gÄ atŔķirÄ«ba bÅ«s tÄda, ka atribÅ«ti sekos malas svaram un tiks norÄdÄ«ti ar elementiem a[2i+3] un a[2i+4] , un pati mala tiks norÄdÄ«ta nevis 4, bet 5 sakÄrtoti cipari). Un grafikam ar malu svariem, kas nav veseli skaitļi, pazÄ«mes var ierakstÄ«t tÄ nesvÄrtajÄ komponentÄ.
Izmantojot asociatÄ«vo blakusesÄ«bu masÄ«vu grafiem ar veselu malu svaru, kÄ vÄrtÄ«bu var norÄdÄ«t nevis vienu skaitli, bet skaitļu masÄ«vu (vektoru), kas papildus malas svaram norÄda arÄ« visu pÄrÄjo nepiecieÅ”amo. IespÄjas. TajÄ paÅ”Ä laikÄ neÄrtÄ«bas attiecÄ«bÄ uz svaru, kas nav veseli skaitļi, radÄ«s nepiecieÅ”amÄ«ba norÄdÄ«t zÄ«mi ar peldoÅ”Ä komata skaitli (jÄ, tas ir neÄrtÄ«bas, bet, ja Å”Ädu zÄ«mju nav tik daudz un NeuzstÄdiet tos pÄrÄk āgrÅ«tiā dubultÄ, tad tas var bÅ«t nekas) . Tas nozÄ«mÄ, ka C++ paplaÅ”inÄtos asociatÄ«vos blakus masÄ«vus var definÄt Å”Ädi: std::map , std::vector> vai std::map , std::vector, kurÄ pirmÄ vÄrtÄ«ba āatslÄgas vÄrtÄ«bas vektorÄā bÅ«s malas svars, un pÄc tam atrodas tÄs raksturlielumu skaitliskie apzÄ«mÄjumi.
Literatūra:
Par grafikiem un algoritmiem kopumÄ:
1. Kormens, Tomass H., Leizersons, ÄÄrlzs I., Rivests, Ronalds L., Steins, Klifords. Algoritmi: konstrukcija un analÄ«ze, 2. izdevums: Trans. no angļu valodas ā M.: Williams Publishing House, 2011.
2. Harari Frenks. Grafu teorija. M.: Mir, 1973.
Autora ziÅojums par Å”o paÅ”u vektoru un blakus esoÅ”o asociatÄ«vo masÄ«vu:
3. Chernoukhov S.A. Blakus vektors un asociatÄ«vais blakusesÄ«bu masÄ«vs kÄ grafiku attÄloÅ”anas un uzglabÄÅ”anas veidi / SA Äernouhovs. Blakusvektors un blakuskarte kÄ datu struktÅ«ras, lai attÄlotu grafiku // StarptautiskÄs zinÄtniski praktiskÄs konferences āInovatÄ«vu izstrÄdÅu rezultÄtu ievieÅ”anas problÄmas un to risinÄÅ”anas veidiā rakstu krÄjums (Saratova, 14.09.2019. gada 2019. septembris). ā Sterlitamak: AMI, 65, lpp. 69-XNUMX
NoderÄ«gi tieÅ”saistes avoti par Å”o tÄmu:
4.
5.
Avots: www.habr.com