From 9e30209244c35cdb71bc90b68c3fc4fcb11bf65b Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:00:46 +0000 Subject: [PATCH 001/227] Setting up GitHub Classroom Feedback From e3de13640ed1e9a83c4fb4b5a465cb15435407d8 Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Sat, 16 Mar 2024 15:19:15 +0300 Subject: [PATCH 002/227] docs: add license --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From da145ce8f91fddcd0000e809c2c1690274c42023 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 15:30:25 +0300 Subject: [PATCH 003/227] build: gradle init --- gradle/libs.versions.toml | 15 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 249 +++++++++++++++++++++++ gradlew.bat | 92 +++++++++ lib/build.gradle.kts | 47 +++++ settings.gradle.kts | 14 ++ 7 files changed, 424 insertions(+) create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 lib/build.gradle.kts create mode 100644 settings.gradle.kts diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..d4d7e1f --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,15 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format + +[versions] +commons-math3 = "3.6.1" +guava = "32.1.3-jre" +junit-jupiter-engine = "5.10.0" + +[libraries] +commons-math3 = { module = "org.apache.commons:commons-math3", version.ref = "commons-math3" } +guava = { module = "com.google.guava:guava", version.ref = "guava" } +junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit-jupiter-engine" } + +[plugins] +jvm = { id = "org.jetbrains.kotlin.jvm", version = "1.9.20" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..d64cd4917707c1f8861d8cb53dd15194d4248596 GIT binary patch literal 43462 zcma&NWl&^owk(X(xVyW%ySuwf;qI=D6|RlDJ2cR^yEKh!@I- zp9QeisK*rlxC>+~7Dk4IxIRsKBHqdR9b3+fyL=ynHmIDe&|>O*VlvO+%z5;9Z$|DJ zb4dO}-R=MKr^6EKJiOrJdLnCJn>np?~vU-1sSFgPu;pthGwf}bG z(1db%xwr#x)r+`4AGu$j7~u2MpVs3VpLp|mx&;>`0p0vH6kF+D2CY0fVdQOZ@h;A` z{infNyvmFUiu*XG}RNMNwXrbec_*a3N=2zJ|Wh5z* z5rAX$JJR{#zP>KY**>xHTuw?|-Rg|o24V)74HcfVT;WtQHXlE+_4iPE8QE#DUm%x0 zEKr75ur~W%w#-My3Tj`hH6EuEW+8K-^5P62$7Sc5OK+22qj&Pd1;)1#4tKihi=~8C zHiQSst0cpri6%OeaR`PY>HH_;CPaRNty%WTm4{wDK8V6gCZlG@U3$~JQZ;HPvDJcT1V{ z?>H@13MJcCNe#5z+MecYNi@VT5|&UiN1D4ATT+%M+h4c$t;C#UAs3O_q=GxK0}8%8 z8J(_M9bayxN}69ex4dzM_P3oh@ZGREjVvn%%r7=xjkqxJP4kj}5tlf;QosR=%4L5y zWhgejO=vao5oX%mOHbhJ8V+SG&K5dABn6!WiKl{|oPkq(9z8l&Mm%(=qGcFzI=eLu zWc_oCLyf;hVlB@dnwY98?75B20=n$>u3b|NB28H0u-6Rpl((%KWEBOfElVWJx+5yg z#SGqwza7f}$z;n~g%4HDU{;V{gXIhft*q2=4zSezGK~nBgu9-Q*rZ#2f=Q}i2|qOp z!!y4p)4o=LVUNhlkp#JL{tfkhXNbB=Ox>M=n6soptJw-IDI|_$is2w}(XY>a=H52d z3zE$tjPUhWWS+5h=KVH&uqQS=$v3nRs&p$%11b%5qtF}S2#Pc`IiyBIF4%A!;AVoI zXU8-Rpv!DQNcF~(qQnyyMy=-AN~U>#&X1j5BLDP{?K!%h!;hfJI>$mdLSvktEr*89 zdJHvby^$xEX0^l9g$xW-d?J;L0#(`UT~zpL&*cEh$L|HPAu=P8`OQZV!-}l`noSp_ zQ-1$q$R-gDL)?6YaM!=8H=QGW$NT2SeZlb8PKJdc=F-cT@j7Xags+Pr*jPtlHFnf- zh?q<6;)27IdPc^Wdy-mX%2s84C1xZq9Xms+==F4);O`VUASmu3(RlgE#0+#giLh-& zcxm3_e}n4{%|X zJp{G_j+%`j_q5}k{eW&TlP}J2wtZ2^<^E(O)4OQX8FDp6RJq!F{(6eHWSD3=f~(h} zJXCf7=r<16X{pHkm%yzYI_=VDP&9bmI1*)YXZeB}F? z(%QsB5fo*FUZxK$oX~X^69;x~j7ms8xlzpt-T15e9}$4T-pC z6PFg@;B-j|Ywajpe4~bk#S6(fO^|mm1hKOPfA%8-_iGCfICE|=P_~e;Wz6my&)h_~ zkv&_xSAw7AZ%ThYF(4jADW4vg=oEdJGVOs>FqamoL3Np8>?!W#!R-0%2Bg4h?kz5I zKV-rKN2n(vUL%D<4oj@|`eJ>0i#TmYBtYmfla;c!ATW%;xGQ0*TW@PTlGG><@dxUI zg>+3SiGdZ%?5N=8uoLA|$4isK$aJ%i{hECP$bK{J#0W2gQ3YEa zZQ50Stn6hqdfxJ*9#NuSLwKFCUGk@c=(igyVL;;2^wi4o30YXSIb2g_ud$ zgpCr@H0qWtk2hK8Q|&wx)}4+hTYlf;$a4#oUM=V@Cw#!$(nOFFpZ;0lc!qd=c$S}Z zGGI-0jg~S~cgVT=4Vo)b)|4phjStD49*EqC)IPwyeKBLcN;Wu@Aeph;emROAwJ-0< z_#>wVm$)ygH|qyxZaet&(Vf%pVdnvKWJn9`%DAxj3ot;v>S$I}jJ$FLBF*~iZ!ZXE zkvui&p}fI0Y=IDX)mm0@tAd|fEHl~J&K}ZX(Mm3cm1UAuwJ42+AO5@HwYfDH7ipIc zmI;1J;J@+aCNG1M`Btf>YT>~c&3j~Qi@Py5JT6;zjx$cvOQW@3oQ>|}GH?TW-E z1R;q^QFjm5W~7f}c3Ww|awg1BAJ^slEV~Pk`Kd`PS$7;SqJZNj->it4DW2l15}xP6 zoCl$kyEF%yJni0(L!Z&14m!1urXh6Btj_5JYt1{#+H8w?5QI%% zo-$KYWNMJVH?Hh@1n7OSu~QhSswL8x0=$<8QG_zepi_`y_79=nK=_ZP_`Em2UI*tyQoB+r{1QYZCpb?2OrgUw#oRH$?^Tj!Req>XiE#~B|~ z+%HB;=ic+R@px4Ld8mwpY;W^A%8%l8$@B@1m5n`TlKI6bz2mp*^^^1mK$COW$HOfp zUGTz-cN9?BGEp}5A!mDFjaiWa2_J2Iq8qj0mXzk; z66JBKRP{p%wN7XobR0YjhAuW9T1Gw3FDvR5dWJ8ElNYF94eF3ebu+QwKjtvVu4L zI9ip#mQ@4uqVdkl-TUQMb^XBJVLW(-$s;Nq;@5gr4`UfLgF$adIhd?rHOa%D);whv z=;krPp~@I+-Z|r#s3yCH+c1US?dnm+C*)r{m+86sTJusLdNu^sqLrfWed^ndHXH`m zd3#cOe3>w-ga(Dus_^ppG9AC>Iq{y%%CK+Cro_sqLCs{VLuK=dev>OL1dis4(PQ5R zcz)>DjEkfV+MO;~>VUlYF00SgfUo~@(&9$Iy2|G0T9BSP?&T22>K46D zL*~j#yJ?)^*%J3!16f)@Y2Z^kS*BzwfAQ7K96rFRIh>#$*$_Io;z>ux@}G98!fWR@ zGTFxv4r~v)Gsd|pF91*-eaZ3Qw1MH$K^7JhWIdX%o$2kCbvGDXy)a?@8T&1dY4`;L z4Kn+f%SSFWE_rpEpL9bnlmYq`D!6F%di<&Hh=+!VI~j)2mfil03T#jJ_s?}VV0_hp z7T9bWxc>Jm2Z0WMU?`Z$xE74Gu~%s{mW!d4uvKCx@WD+gPUQ zV0vQS(Ig++z=EHN)BR44*EDSWIyT~R4$FcF*VEY*8@l=218Q05D2$|fXKFhRgBIEE zdDFB}1dKkoO^7}{5crKX!p?dZWNz$m>1icsXG2N+((x0OIST9Zo^DW_tytvlwXGpn zs8?pJXjEG;T@qrZi%#h93?FP$!&P4JA(&H61tqQi=opRzNpm zkrG}$^t9&XduK*Qa1?355wd8G2CI6QEh@Ua>AsD;7oRUNLPb76m4HG3K?)wF~IyS3`fXuNM>${?wmB zpVz;?6_(Fiadfd{vUCBM*_kt$+F3J+IojI;9L(gc9n3{sEZyzR9o!_mOwFC#tQ{Q~ zP3-`#uK#tP3Q7~Q;4H|wjZHO8h7e4IuBxl&vz2w~D8)w=Wtg31zpZhz%+kzSzL*dV zwp@{WU4i;hJ7c2f1O;7Mz6qRKeASoIv0_bV=i@NMG*l<#+;INk-^`5w@}Dj~;k=|}qM1vq_P z|GpBGe_IKq|LNy9SJhKOQ$c=5L{Dv|Q_lZl=-ky*BFBJLW9&y_C|!vyM~rQx=!vun z?rZJQB5t}Dctmui5i31C_;_}CEn}_W%>oSXtt>@kE1=JW*4*v4tPp;O6 zmAk{)m!)}34pTWg8{i>($%NQ(Tl;QC@J@FfBoc%Gr&m560^kgSfodAFrIjF}aIw)X zoXZ`@IsMkc8_=w%-7`D6Y4e*CG8k%Ud=GXhsTR50jUnm+R*0A(O3UKFg0`K;qp1bl z7``HN=?39ic_kR|^R^~w-*pa?Vj#7|e9F1iRx{GN2?wK!xR1GW!qa=~pjJb-#u1K8 zeR?Y2i-pt}yJq;SCiVHODIvQJX|ZJaT8nO+(?HXbLefulKKgM^B(UIO1r+S=7;kLJ zcH}1J=Px2jsh3Tec&v8Jcbng8;V-`#*UHt?hB(pmOipKwf3Lz8rG$heEB30Sg*2rx zV<|KN86$soN(I!BwO`1n^^uF2*x&vJ$2d$>+`(romzHP|)K_KkO6Hc>_dwMW-M(#S zK(~SiXT1@fvc#U+?|?PniDRm01)f^#55;nhM|wi?oG>yBsa?~?^xTU|fX-R(sTA+5 zaq}-8Tx7zrOy#3*JLIIVsBmHYLdD}!0NP!+ITW+Thn0)8SS!$@)HXwB3tY!fMxc#1 zMp3H?q3eD?u&Njx4;KQ5G>32+GRp1Ee5qMO0lZjaRRu&{W<&~DoJNGkcYF<5(Ab+J zgO>VhBl{okDPn78<%&e2mR{jwVCz5Og;*Z;;3%VvoGo_;HaGLWYF7q#jDX=Z#Ml`H z858YVV$%J|e<1n`%6Vsvq7GmnAV0wW4$5qQ3uR@1i>tW{xrl|ExywIc?fNgYlA?C5 zh$ezAFb5{rQu6i7BSS5*J-|9DQ{6^BVQ{b*lq`xS@RyrsJN?-t=MTMPY;WYeKBCNg z^2|pN!Q^WPJuuO4!|P@jzt&tY1Y8d%FNK5xK(!@`jO2aEA*4 zkO6b|UVBipci?){-Ke=+1;mGlND8)6+P;8sq}UXw2hn;fc7nM>g}GSMWu&v&fqh

iViYT=fZ(|3Ox^$aWPp4a8h24tD<|8-!aK0lHgL$N7Efw}J zVIB!7=T$U`ao1?upi5V4Et*-lTG0XvExbf!ya{cua==$WJyVG(CmA6Of*8E@DSE%L z`V^$qz&RU$7G5mg;8;=#`@rRG`-uS18$0WPN@!v2d{H2sOqP|!(cQ@ zUHo!d>>yFArLPf1q`uBvY32miqShLT1B@gDL4XoVTK&@owOoD)OIHXrYK-a1d$B{v zF^}8D3Y^g%^cnvScOSJR5QNH+BI%d|;J;wWM3~l>${fb8DNPg)wrf|GBP8p%LNGN# z3EaIiItgwtGgT&iYCFy9-LG}bMI|4LdmmJt@V@% zb6B)1kc=T)(|L@0;wr<>=?r04N;E&ef+7C^`wPWtyQe(*pD1pI_&XHy|0gIGHMekd zF_*M4yi6J&Z4LQj65)S zXwdM{SwUo%3SbPwFsHgqF@V|6afT|R6?&S;lw=8% z3}@9B=#JI3@B*#4s!O))~z zc>2_4Q_#&+5V`GFd?88^;c1i7;Vv_I*qt!_Yx*n=;rj!82rrR2rQ8u5(Ejlo{15P% zs~!{%XJ>FmJ})H^I9bn^Re&38H{xA!0l3^89k(oU;bZWXM@kn$#aoS&Y4l^-WEn-fH39Jb9lA%s*WsKJQl?n9B7_~P z-XM&WL7Z!PcoF6_D>V@$CvUIEy=+Z&0kt{szMk=f1|M+r*a43^$$B^MidrT0J;RI` z(?f!O<8UZkm$_Ny$Hth1J#^4ni+im8M9mr&k|3cIgwvjAgjH z8`N&h25xV#v*d$qBX5jkI|xOhQn!>IYZK7l5#^P4M&twe9&Ey@@GxYMxBZq2e7?`q z$~Szs0!g{2fGcp9PZEt|rdQ6bhAgpcLHPz?f-vB?$dc*!9OL?Q8mn7->bFD2Si60* z!O%y)fCdMSV|lkF9w%x~J*A&srMyYY3{=&$}H zGQ4VG_?$2X(0|vT0{=;W$~icCI{b6W{B!Q8xdGhF|D{25G_5_+%s(46lhvNLkik~R z>nr(&C#5wwOzJZQo9m|U<;&Wk!_#q|V>fsmj1g<6%hB{jGoNUPjgJslld>xmODzGjYc?7JSuA?A_QzjDw5AsRgi@Y|Z0{F{!1=!NES-#*f^s4l0Hu zz468))2IY5dmD9pa*(yT5{EyP^G>@ZWumealS-*WeRcZ}B%gxq{MiJ|RyX-^C1V=0 z@iKdrGi1jTe8Ya^x7yyH$kBNvM4R~`fbPq$BzHum-3Zo8C6=KW@||>zsA8-Y9uV5V z#oq-f5L5}V<&wF4@X@<3^C%ptp6+Ce)~hGl`kwj)bsAjmo_GU^r940Z-|`<)oGnh7 zFF0Tde3>ui?8Yj{sF-Z@)yQd~CGZ*w-6p2U<8}JO-sRsVI5dBji`01W8A&3$?}lxBaC&vn0E$c5tW* zX>5(zzZ=qn&!J~KdsPl;P@bmA-Pr8T*)eh_+Dv5=Ma|XSle6t(k8qcgNyar{*ReQ8 zTXwi=8vr>!3Ywr+BhggHDw8ke==NTQVMCK`$69fhzEFB*4+H9LIvdt-#IbhZvpS}} zO3lz;P?zr0*0$%-Rq_y^k(?I{Mk}h@w}cZpMUp|ucs55bcloL2)($u%mXQw({Wzc~ z;6nu5MkjP)0C(@%6Q_I_vsWrfhl7Zpoxw#WoE~r&GOSCz;_ro6i(^hM>I$8y>`!wW z*U^@?B!MMmb89I}2(hcE4zN2G^kwyWCZp5JG>$Ez7zP~D=J^LMjSM)27_0B_X^C(M z`fFT+%DcKlu?^)FCK>QzSnV%IsXVcUFhFdBP!6~se&xxrIxsvySAWu++IrH;FbcY$ z2DWTvSBRfLwdhr0nMx+URA$j3i7_*6BWv#DXfym?ZRDcX9C?cY9sD3q)uBDR3uWg= z(lUIzB)G$Hr!){>E{s4Dew+tb9kvToZp-1&c?y2wn@Z~(VBhqz`cB;{E4(P3N2*nJ z_>~g@;UF2iG{Kt(<1PyePTKahF8<)pozZ*xH~U-kfoAayCwJViIrnqwqO}7{0pHw$ zs2Kx?s#vQr7XZ264>5RNKSL8|Ty^=PsIx^}QqOOcfpGUU4tRkUc|kc7-!Ae6!+B{o~7nFpm3|G5^=0#Bnm6`V}oSQlrX(u%OWnC zoLPy&Q;1Jui&7ST0~#+}I^&?vcE*t47~Xq#YwvA^6^} z`WkC)$AkNub|t@S!$8CBlwbV~?yp&@9h{D|3z-vJXgzRC5^nYm+PyPcgRzAnEi6Q^gslXYRv4nycsy-SJu?lMps-? zV`U*#WnFsdPLL)Q$AmD|0`UaC4ND07+&UmOu!eHruzV|OUox<+Jl|Mr@6~C`T@P%s zW7sgXLF2SSe9Fl^O(I*{9wsFSYb2l%-;&Pi^dpv!{)C3d0AlNY6!4fgmSgj_wQ*7Am7&$z;Jg&wgR-Ih;lUvWS|KTSg!&s_E9_bXBkZvGiC6bFKDWZxsD$*NZ#_8bl zG1P-#@?OQzED7@jlMJTH@V!6k;W>auvft)}g zhoV{7$q=*;=l{O>Q4a@ ziMjf_u*o^PsO)#BjC%0^h>Xp@;5$p{JSYDt)zbb}s{Kbt!T*I@Pk@X0zds6wsefuU zW$XY%yyRGC94=6mf?x+bbA5CDQ2AgW1T-jVAJbm7K(gp+;v6E0WI#kuACgV$r}6L? zd|Tj?^%^*N&b>Dd{Wr$FS2qI#Ucs1yd4N+RBUQiSZGujH`#I)mG&VKoDh=KKFl4=G z&MagXl6*<)$6P}*Tiebpz5L=oMaPrN+caUXRJ`D?=K9!e0f{@D&cZLKN?iNP@X0aF zE(^pl+;*T5qt?1jRC=5PMgV!XNITRLS_=9{CJExaQj;lt!&pdzpK?8p>%Mb+D z?yO*uSung=-`QQ@yX@Hyd4@CI^r{2oiu`%^bNkz+Nkk!IunjwNC|WcqvX~k=><-I3 zDQdbdb|!v+Iz01$w@aMl!R)koD77Xp;eZwzSl-AT zr@Vu{=xvgfq9akRrrM)}=!=xcs+U1JO}{t(avgz`6RqiiX<|hGG1pmop8k6Q+G_mv zJv|RfDheUp2L3=^C=4aCBMBn0aRCU(DQwX-W(RkRwmLeuJYF<0urcaf(=7)JPg<3P zQs!~G)9CT18o!J4{zX{_e}4eS)U-E)0FAt}wEI(c0%HkxgggW;(1E=>J17_hsH^sP z%lT0LGgbUXHx-K*CI-MCrP66UP0PvGqM$MkeLyqHdbgP|_Cm!7te~b8p+e6sQ_3k| zVcwTh6d83ltdnR>D^)BYQpDKlLk3g0Hdcgz2}%qUs9~~Rie)A-BV1mS&naYai#xcZ z(d{8=-LVpTp}2*y)|gR~;qc7fp26}lPcLZ#=JpYcn3AT9(UIdOyg+d(P5T7D&*P}# zQCYplZO5|7+r19%9e`v^vfSS1sbX1c%=w1;oyruXB%Kl$ACgKQ6=qNWLsc=28xJjg zwvsI5-%SGU|3p>&zXVl^vVtQT3o-#$UT9LI@Npz~6=4!>mc431VRNN8od&Ul^+G_kHC`G=6WVWM z%9eWNyy(FTO|A+@x}Ou3CH)oi;t#7rAxdIXfNFwOj_@Y&TGz6P_sqiB`Q6Lxy|Q{`|fgmRG(k+!#b*M+Z9zFce)f-7;?Km5O=LHV9f9_87; zF7%R2B+$?@sH&&-$@tzaPYkw0;=i|;vWdI|Wl3q_Zu>l;XdIw2FjV=;Mq5t1Q0|f< zs08j54Bp`3RzqE=2enlkZxmX6OF+@|2<)A^RNQpBd6o@OXl+i)zO%D4iGiQNuXd+zIR{_lb96{lc~bxsBveIw6umhShTX+3@ZJ=YHh@ zWY3(d0azg;7oHn>H<>?4@*RQbi>SmM=JrHvIG(~BrvI)#W(EAeO6fS+}mxxcc+X~W6&YVl86W9WFSS}Vz-f9vS?XUDBk)3TcF z8V?$4Q)`uKFq>xT=)Y9mMFVTUk*NIA!0$?RP6Ig0TBmUFrq*Q-Agq~DzxjStQyJ({ zBeZ;o5qUUKg=4Hypm|}>>L=XKsZ!F$yNTDO)jt4H0gdQ5$f|d&bnVCMMXhNh)~mN z@_UV6D7MVlsWz+zM+inZZp&P4fj=tm6fX)SG5H>OsQf_I8c~uGCig$GzuwViK54bcgL;VN|FnyQl>Ed7(@>=8$a_UKIz|V6CeVSd2(P z0Uu>A8A+muM%HLFJQ9UZ5c)BSAv_zH#1f02x?h9C}@pN@6{>UiAp>({Fn(T9Q8B z^`zB;kJ5b`>%dLm+Ol}ty!3;8f1XDSVX0AUe5P#@I+FQ-`$(a;zNgz)4x5hz$Hfbg z!Q(z26wHLXko(1`;(BAOg_wShpX0ixfWq3ponndY+u%1gyX)_h=v1zR#V}#q{au6; z!3K=7fQwnRfg6FXtNQmP>`<;!N137paFS%y?;lb1@BEdbvQHYC{976l`cLqn;b8lp zIDY>~m{gDj(wfnK!lpW6pli)HyLEiUrNc%eXTil|F2s(AY+LW5hkKb>TQ3|Q4S9rr zpDs4uK_co6XPsn_z$LeS{K4jFF`2>U`tbgKdyDne`xmR<@6AA+_hPNKCOR-Zqv;xk zu5!HsBUb^!4uJ7v0RuH-7?l?}b=w5lzzXJ~gZcxRKOovSk@|#V+MuX%Y+=;14i*%{)_gSW9(#4%)AV#3__kac1|qUy!uyP{>?U#5wYNq}y$S9pCc zFc~4mgSC*G~j0u#qqp9 z${>3HV~@->GqEhr_Xwoxq?Hjn#=s2;i~g^&Hn|aDKpA>Oc%HlW(KA1?BXqpxB;Ydx)w;2z^MpjJ(Qi(X!$5RC z*P{~%JGDQqojV>2JbEeCE*OEu!$XJ>bWA9Oa_Hd;y)F%MhBRi*LPcdqR8X`NQ&1L# z5#9L*@qxrx8n}LfeB^J{%-?SU{FCwiWyHp682F+|pa+CQa3ZLzBqN1{)h4d6+vBbV zC#NEbQLC;}me3eeYnOG*nXOJZEU$xLZ1<1Y=7r0(-U0P6-AqwMAM`a(Ed#7vJkn6plb4eI4?2y3yOTGmmDQ!z9`wzbf z_OY#0@5=bnep;MV0X_;;SJJWEf^E6Bd^tVJ9znWx&Ks8t*B>AM@?;D4oWUGc z!H*`6d7Cxo6VuyS4Eye&L1ZRhrRmN6Lr`{NL(wDbif|y&z)JN>Fl5#Wi&mMIr5i;x zBx}3YfF>>8EC(fYnmpu~)CYHuHCyr5*`ECap%t@y=jD>!_%3iiE|LN$mK9>- zHdtpy8fGZtkZF?%TW~29JIAfi2jZT8>OA7=h;8T{{k?c2`nCEx9$r zS+*&vt~2o^^J+}RDG@+9&M^K*z4p{5#IEVbz`1%`m5c2};aGt=V?~vIM}ZdPECDI)47|CWBCfDWUbxBCnmYivQ*0Nu_xb*C>~C9(VjHM zxe<*D<#dQ8TlpMX2c@M<9$w!RP$hpG4cs%AI){jp*Sj|*`m)5(Bw*A0$*i-(CA5#%>a)$+jI2C9r6|(>J8InryENI z$NohnxDUB;wAYDwrb*!N3noBTKPpPN}~09SEL18tkG zxgz(RYU_;DPT{l?Q$+eaZaxnsWCA^ds^0PVRkIM%bOd|G2IEBBiz{&^JtNsODs;5z zICt_Zj8wo^KT$7Bg4H+y!Df#3mbl%%?|EXe!&(Vmac1DJ*y~3+kRKAD=Ovde4^^%~ zw<9av18HLyrf*_>Slp;^i`Uy~`mvBjZ|?Ad63yQa#YK`4+c6;pW4?XIY9G1(Xh9WO8{F-Aju+nS9Vmv=$Ac0ienZ+p9*O%NG zMZKy5?%Z6TAJTE?o5vEr0r>f>hb#2w2U3DL64*au_@P!J!TL`oH2r*{>ffu6|A7tv zL4juf$DZ1MW5ZPsG!5)`k8d8c$J$o;%EIL0va9&GzWvkS%ZsGb#S(?{!UFOZ9<$a| zY|a+5kmD5N&{vRqkgY>aHsBT&`rg|&kezoD)gP0fsNYHsO#TRc_$n6Lf1Z{?+DLziXlHrq4sf(!>O{?Tj;Eh@%)+nRE_2VxbN&&%%caU#JDU%vL3}Cb zsb4AazPI{>8H&d=jUaZDS$-0^AxE@utGs;-Ez_F(qC9T=UZX=>ok2k2 ziTn{K?y~a5reD2A)P${NoI^>JXn>`IeArow(41c-Wm~)wiryEP(OS{YXWi7;%dG9v zI?mwu1MxD{yp_rrk!j^cKM)dc4@p4Ezyo%lRN|XyD}}>v=Xoib0gOcdXrQ^*61HNj z=NP|pd>@yfvr-=m{8$3A8TQGMTE7g=z!%yt`8`Bk-0MMwW~h^++;qyUP!J~ykh1GO z(FZ59xuFR$(WE;F@UUyE@Sp>`aVNjyj=Ty>_Vo}xf`e7`F;j-IgL5`1~-#70$9_=uBMq!2&1l zomRgpD58@)YYfvLtPW}{C5B35R;ZVvB<<#)x%srmc_S=A7F@DW8>QOEGwD6suhwCg z>Pa+YyULhmw%BA*4yjDp|2{!T98~<6Yfd(wo1mQ!KWwq0eg+6)o1>W~f~kL<-S+P@$wx*zeI|1t7z#Sxr5 zt6w+;YblPQNplq4Z#T$GLX#j6yldXAqj>4gAnnWtBICUnA&-dtnlh=t0Ho_vEKwV` z)DlJi#!@nkYV#$!)@>udAU*hF?V`2$Hf=V&6PP_|r#Iv*J$9)pF@X3`k;5})9^o4y z&)~?EjX5yX12O(BsFy-l6}nYeuKkiq`u9145&3Ssg^y{5G3Pse z9w(YVa0)N-fLaBq1`P!_#>SS(8fh_5!f{UrgZ~uEdeMJIz7DzI5!NHHqQtm~#CPij z?=N|J>nPR6_sL7!f4hD_|KH`vf8(Wpnj-(gPWH+ZvID}%?~68SwhPTC3u1_cB`otq z)U?6qo!ZLi5b>*KnYHWW=3F!p%h1;h{L&(Q&{qY6)_qxNfbP6E3yYpW!EO+IW3?@J z);4>g4gnl^8klu7uA>eGF6rIGSynacogr)KUwE_R4E5Xzi*Qir@b-jy55-JPC8c~( zo!W8y9OGZ&`xmc8;=4-U9=h{vCqfCNzYirONmGbRQlR`WWlgnY+1wCXbMz&NT~9*| z6@FrzP!LX&{no2!Ln_3|I==_4`@}V?4a;YZKTdw;vT<+K+z=uWbW(&bXEaWJ^W8Td z-3&1bY^Z*oM<=M}LVt>_j+p=2Iu7pZmbXrhQ_k)ysE9yXKygFNw$5hwDn(M>H+e1&9BM5!|81vd%r%vEm zqxY3?F@fb6O#5UunwgAHR9jp_W2zZ}NGp2%mTW@(hz7$^+a`A?mb8|_G*GNMJ) zjqegXQio=i@AINre&%ofexAr95aop5C+0MZ0m-l=MeO8m3epm7U%vZB8+I+C*iNFM z#T3l`gknX;D$-`2XT^Cg*vrv=RH+P;_dfF++cP?B_msQI4j+lt&rX2)3GaJx%W*Nn zkML%D{z5tpHH=dksQ*gzc|}gzW;lwAbxoR07VNgS*-c3d&8J|;@3t^ zVUz*J*&r7DFRuFVDCJDK8V9NN5hvpgGjwx+5n)qa;YCKe8TKtdnh{I7NU9BCN!0dq zczrBk8pE{{@vJa9ywR@mq*J=v+PG;?fwqlJVhijG!3VmIKs>9T6r7MJpC)m!Tc#>g zMtVsU>wbwFJEfwZ{vB|ZlttNe83)$iz`~#8UJ^r)lJ@HA&G#}W&ZH*;k{=TavpjWE z7hdyLZPf*X%Gm}i`Y{OGeeu^~nB8=`{r#TUrM-`;1cBvEd#d!kPqIgYySYhN-*1;L z^byj%Yi}Gx)Wnkosi337BKs}+5H5dth1JA{Ir-JKN$7zC)*}hqeoD(WfaUDPT>0`- z(6sa0AoIqASwF`>hP}^|)a_j2s^PQn*qVC{Q}htR z5-)duBFXT_V56-+UohKXlq~^6uf!6sA#ttk1o~*QEy_Y-S$gAvq47J9Vtk$5oA$Ct zYhYJ@8{hsC^98${!#Ho?4y5MCa7iGnfz}b9jE~h%EAAv~Qxu)_rAV;^cygV~5r_~?l=B`zObj7S=H=~$W zPtI_m%g$`kL_fVUk9J@>EiBH zOO&jtn~&`hIFMS5S`g8w94R4H40mdNUH4W@@XQk1sr17b{@y|JB*G9z1|CrQjd+GX z6+KyURG3;!*BQrentw{B2R&@2&`2}n(z-2&X7#r!{yg@Soy}cRD~j zj9@UBW+N|4HW4AWapy4wfUI- zZ`gSL6DUlgj*f1hSOGXG0IVH8HxK?o2|3HZ;KW{K+yPAlxtb)NV_2AwJm|E)FRs&& z=c^e7bvUsztY|+f^k7NXs$o1EUq>cR7C0$UKi6IooHWlK_#?IWDkvywnzg&ThWo^? z2O_N{5X39#?eV9l)xI(>@!vSB{DLt*oY!K1R8}_?%+0^C{d9a%N4 zoxHVT1&Lm|uDX%$QrBun5e-F`HJ^T$ zmzv)p@4ZHd_w9!%Hf9UYNvGCw2TTTbrj9pl+T9%-_-}L(tES>Or-}Z4F*{##n3~L~TuxjirGuIY#H7{%$E${?p{Q01 zi6T`n;rbK1yIB9jmQNycD~yZq&mbIsFWHo|ZAChSFPQa<(%d8mGw*V3fh|yFoxOOiWJd(qvVb!Z$b88cg->N=qO*4k~6;R==|9ihg&riu#P~s4Oap9O7f%crSr^rljeIfXDEg>wi)&v*a%7zpz<9w z*r!3q9J|390x`Zk;g$&OeN&ctp)VKRpDSV@kU2Q>jtok($Y-*x8_$2piTxun81@vt z!Vj?COa0fg2RPXMSIo26T=~0d`{oGP*eV+$!0I<(4azk&Vj3SiG=Q!6mX0p$z7I}; z9BJUFgT-K9MQQ-0@Z=^7R<{bn2Fm48endsSs`V7_@%8?Bxkqv>BDoVcj?K#dV#uUP zL1ND~?D-|VGKe3Rw_7-Idpht>H6XRLh*U7epS6byiGvJpr%d}XwfusjH9g;Z98H`x zyde%%5mhGOiL4wljCaWCk-&uE4_OOccb9c!ZaWt4B(wYl!?vyzl%7n~QepN&eFUrw zFIOl9c({``6~QD+43*_tzP{f2x41h(?b43^y6=iwyB)2os5hBE!@YUS5?N_tXd=h( z)WE286Fbd>R4M^P{!G)f;h<3Q>Fipuy+d2q-)!RyTgt;wr$(?9ox3;q+{E*ZQHhOn;lM`cjnu9 zXa48ks-v(~b*;MAI<>YZH(^NV8vjb34beE<_cwKlJoR;k6lJNSP6v}uiyRD?|0w+X@o1ONrH8a$fCxXpf? z?$DL0)7|X}Oc%h^zrMKWc-NS9I0Utu@>*j}b@tJ=ixQSJ={4@854wzW@E>VSL+Y{i z#0b=WpbCZS>kUCO_iQz)LoE>P5LIG-hv9E+oG}DtlIDF>$tJ1aw9^LuhLEHt?BCj& z(O4I8v1s#HUi5A>nIS-JK{v!7dJx)^Yg%XjNmlkWAq2*cv#tHgz`Y(bETc6CuO1VkN^L-L3j_x<4NqYb5rzrLC-7uOv z!5e`GZt%B782C5-fGnn*GhDF$%(qP<74Z}3xx+{$4cYKy2ikxI7B2N+2r07DN;|-T->nU&!=Cm#rZt%O_5c&1Z%nlWq3TKAW0w zQqemZw_ue--2uKQsx+niCUou?HjD`xhEjjQd3%rrBi82crq*~#uA4+>vR<_S{~5ce z-2EIl?~s z1=GVL{NxP1N3%=AOaC}j_Fv=ur&THz zyO!d9kHq|c73kpq`$+t+8Bw7MgeR5~`d7ChYyGCBWSteTB>8WAU(NPYt2Dk`@#+}= zI4SvLlyk#pBgVigEe`?NG*vl7V6m+<}%FwPV=~PvvA)=#ths==DRTDEYh4V5}Cf$z@#;< zyWfLY_5sP$gc3LLl2x+Ii)#b2nhNXJ{R~vk`s5U7Nyu^3yFg&D%Txwj6QezMX`V(x z=C`{76*mNb!qHHs)#GgGZ_7|vkt9izl_&PBrsu@}L`X{95-2jf99K)0=*N)VxBX2q z((vkpP2RneSIiIUEnGb?VqbMb=Zia+rF~+iqslydE34cSLJ&BJW^3knX@M;t*b=EA zNvGzv41Ld_T+WT#XjDB840vovUU^FtN_)G}7v)1lPetgpEK9YS^OWFkPoE{ovj^=@ zO9N$S=G$1ecndT_=5ehth2Lmd1II-PuT~C9`XVePw$y8J#dpZ?Tss<6wtVglm(Ok7 z3?^oi@pPio6l&!z8JY(pJvG=*pI?GIOu}e^EB6QYk$#FJQ%^AIK$I4epJ+9t?KjqA+bkj&PQ*|vLttme+`9G=L% ziadyMw_7-M)hS(3E$QGNCu|o23|%O+VN7;Qggp?PB3K-iSeBa2b}V4_wY`G1Jsfz4 z9|SdB^;|I8E8gWqHKx!vj_@SMY^hLEIbSMCuE?WKq=c2mJK z8LoG-pnY!uhqFv&L?yEuxo{dpMTsmCn)95xanqBrNPTgXP((H$9N${Ow~Is-FBg%h z53;|Y5$MUN)9W2HBe2TD`ct^LHI<(xWrw}$qSoei?}s)&w$;&!14w6B6>Yr6Y8b)S z0r71`WmAvJJ`1h&poLftLUS6Ir zC$bG9!Im_4Zjse)#K=oJM9mHW1{%l8sz$1o?ltdKlLTxWWPB>Vk22czVt|1%^wnN@*!l)}?EgtvhC>vlHm^t+ogpgHI1_$1ox9e;>0!+b(tBrmXRB`PY1vp-R**8N7 zGP|QqI$m(Rdu#=(?!(N}G9QhQ%o!aXE=aN{&wtGP8|_qh+7a_j_sU5|J^)vxq;# zjvzLn%_QPHZZIWu1&mRAj;Sa_97p_lLq_{~j!M9N^1yp3U_SxRqK&JnR%6VI#^E12 z>CdOVI^_9aPK2eZ4h&^{pQs}xsijXgFYRIxJ~N7&BB9jUR1fm!(xl)mvy|3e6-B3j zJn#ajL;bFTYJ2+Q)tDjx=3IklO@Q+FFM}6UJr6km7hj7th9n_&JR7fnqC!hTZoM~T zBeaVFp%)0cbPhejX<8pf5HyRUj2>aXnXBqDJe73~J%P(2C?-RT{c3NjE`)om! zl$uewSgWkE66$Kb34+QZZvRn`fob~Cl9=cRk@Es}KQm=?E~CE%spXaMO6YmrMl%9Q zlA3Q$3|L1QJ4?->UjT&CBd!~ru{Ih^in&JXO=|<6J!&qp zRe*OZ*cj5bHYlz!!~iEKcuE|;U4vN1rk$xq6>bUWD*u(V@8sG^7>kVuo(QL@Ki;yL zWC!FT(q{E8#on>%1iAS0HMZDJg{Z{^!De(vSIq&;1$+b)oRMwA3nc3mdTSG#3uYO_ z>+x;7p4I;uHz?ZB>dA-BKl+t-3IB!jBRgdvAbW!aJ(Q{aT>+iz?91`C-xbe)IBoND z9_Xth{6?(y3rddwY$GD65IT#f3<(0o#`di{sh2gm{dw*#-Vnc3r=4==&PU^hCv$qd zjw;>i&?L*Wq#TxG$mFIUf>eK+170KG;~+o&1;Tom9}}mKo23KwdEM6UonXgc z!6N(@k8q@HPw{O8O!lAyi{rZv|DpgfU{py+j(X_cwpKqcalcqKIr0kM^%Br3SdeD> zHSKV94Yxw;pjzDHo!Q?8^0bb%L|wC;4U^9I#pd5O&eexX+Im{ z?jKnCcsE|H?{uGMqVie_C~w7GX)kYGWAg%-?8|N_1#W-|4F)3YTDC+QSq1s!DnOML3@d`mG%o2YbYd#jww|jD$gotpa)kntakp#K;+yo-_ZF9qrNZw<%#C zuPE@#3RocLgPyiBZ+R_-FJ_$xP!RzWm|aN)S+{$LY9vvN+IW~Kf3TsEIvP+B9Mtm! zpfNNxObWQpLoaO&cJh5>%slZnHl_Q~(-Tfh!DMz(dTWld@LG1VRF`9`DYKhyNv z2pU|UZ$#_yUx_B_|MxUq^glT}O5Xt(Vm4Mr02><%C)@v;vPb@pT$*yzJ4aPc_FZ3z z3}PLoMBIM>q_9U2rl^sGhk1VUJ89=*?7|v`{!Z{6bqFMq(mYiA?%KbsI~JwuqVA9$H5vDE+VocjX+G^%bieqx->s;XWlKcuv(s%y%D5Xbc9+ zc(_2nYS1&^yL*ey664&4`IoOeDIig}y-E~_GS?m;D!xv5-xwz+G`5l6V+}CpeJDi^ z%4ed$qowm88=iYG+(`ld5Uh&>Dgs4uPHSJ^TngXP_V6fPyl~>2bhi20QB%lSd#yYn zO05?KT1z@?^-bqO8Cg`;ft>ilejsw@2%RR7;`$Vs;FmO(Yr3Fp`pHGr@P2hC%QcA|X&N2Dn zYf`MqXdHi%cGR@%y7Rg7?d3?an){s$zA{!H;Ie5exE#c~@NhQUFG8V=SQh%UxUeiV zd7#UcYqD=lk-}sEwlpu&H^T_V0{#G?lZMxL7ih_&{(g)MWBnCZxtXg znr#}>U^6!jA%e}@Gj49LWG@*&t0V>Cxc3?oO7LSG%~)Y5}f7vqUUnQ;STjdDU}P9IF9d9<$;=QaXc zL1^X7>fa^jHBu_}9}J~#-oz3Oq^JmGR#?GO7b9a(=R@fw@}Q{{@`Wy1vIQ#Bw?>@X z-_RGG@wt|%u`XUc%W{J z>iSeiz8C3H7@St3mOr_mU+&bL#Uif;+Xw-aZdNYUpdf>Rvu0i0t6k*}vwU`XNO2he z%miH|1tQ8~ZK!zmL&wa3E;l?!!XzgV#%PMVU!0xrDsNNZUWKlbiOjzH-1Uoxm8E#r`#2Sz;-o&qcqB zC-O_R{QGuynW14@)7&@yw1U}uP(1cov)twxeLus0s|7ayrtT8c#`&2~Fiu2=R;1_4bCaD=*E@cYI>7YSnt)nQc zohw5CsK%m?8Ack)qNx`W0_v$5S}nO|(V|RZKBD+btO?JXe|~^Qqur%@eO~<8-L^9d z=GA3-V14ng9L29~XJ>a5k~xT2152zLhM*@zlp2P5Eu}bywkcqR;ISbas&#T#;HZSf z2m69qTV(V@EkY(1Dk3`}j)JMo%ZVJ*5eB zYOjIisi+igK0#yW*gBGj?@I{~mUOvRFQR^pJbEbzFxTubnrw(Muk%}jI+vXmJ;{Q6 zrSobKD>T%}jV4Ub?L1+MGOD~0Ir%-`iTnWZN^~YPrcP5y3VMAzQ+&en^VzKEb$K!Q z<7Dbg&DNXuow*eD5yMr+#08nF!;%4vGrJI++5HdCFcGLfMW!KS*Oi@=7hFwDG!h2< zPunUEAF+HncQkbfFj&pbzp|MU*~60Z(|Ik%Tn{BXMN!hZOosNIseT?R;A`W?=d?5X zK(FB=9mZusYahp|K-wyb={rOpdn=@;4YI2W0EcbMKyo~-#^?h`BA9~o285%oY zfifCh5Lk$SY@|2A@a!T2V+{^!psQkx4?x0HSV`(w9{l75QxMk!)U52Lbhn{8ol?S) zCKo*7R(z!uk<6*qO=wh!Pul{(qq6g6xW;X68GI_CXp`XwO zxuSgPRAtM8K7}5E#-GM!*ydOOG_{A{)hkCII<|2=ma*71ci_-}VPARm3crFQjLYV! z9zbz82$|l01mv`$WahE2$=fAGWkd^X2kY(J7iz}WGS z@%MyBEO=A?HB9=^?nX`@nh;7;laAjs+fbo!|K^mE!tOB>$2a_O0y-*uaIn8k^6Y zSbuv;5~##*4Y~+y7Z5O*3w4qgI5V^17u*ZeupVGH^nM&$qmAk|anf*>r zWc5CV;-JY-Z@Uq1Irpb^O`L_7AGiqd*YpGUShb==os$uN3yYvb`wm6d=?T*it&pDk zo`vhw)RZX|91^^Wa_ti2zBFyWy4cJu#g)_S6~jT}CC{DJ_kKpT`$oAL%b^!2M;JgT zM3ZNbUB?}kP(*YYvXDIH8^7LUxz5oE%kMhF!rnPqv!GiY0o}NR$OD=ITDo9r%4E>E0Y^R(rS^~XjWyVI6 zMOR5rPXhTp*G*M&X#NTL`Hu*R+u*QNoiOKg4CtNPrjgH>c?Hi4MUG#I917fx**+pJfOo!zFM&*da&G_x)L(`k&TPI*t3e^{crd zX<4I$5nBQ8Ax_lmNRa~E*zS-R0sxkz`|>7q_?*e%7bxqNm3_eRG#1ae3gtV9!fQpY z+!^a38o4ZGy9!J5sylDxZTx$JmG!wg7;>&5H1)>f4dXj;B+@6tMlL=)cLl={jLMxY zbbf1ax3S4>bwB9-$;SN2?+GULu;UA-35;VY*^9Blx)Jwyb$=U!D>HhB&=jSsd^6yw zL)?a|>GxU!W}ocTC(?-%z3!IUhw^uzc`Vz_g>-tv)(XA#JK^)ZnC|l1`@CdX1@|!| z_9gQ)7uOf?cR@KDp97*>6X|;t@Y`k_N@)aH7gY27)COv^P3ya9I{4z~vUjLR9~z1Z z5=G{mVtKH*&$*t0@}-i_v|3B$AHHYale7>E+jP`ClqG%L{u;*ff_h@)al?RuL7tOO z->;I}>%WI{;vbLP3VIQ^iA$4wl6@0sDj|~112Y4OFjMs`13!$JGkp%b&E8QzJw_L5 zOnw9joc0^;O%OpF$Qp)W1HI!$4BaXX84`%@#^dk^hFp^pQ@rx4g(8Xjy#!X%+X5Jd@fs3amGT`}mhq#L97R>OwT5-m|h#yT_-v@(k$q7P*9X~T*3)LTdzP!*B} z+SldbVWrrwQo9wX*%FyK+sRXTa@O?WM^FGWOE?S`R(0P{<6p#f?0NJvnBia?k^fX2 zNQs7K-?EijgHJY}&zsr;qJ<*PCZUd*x|dD=IQPUK_nn)@X4KWtqoJNHkT?ZWL_hF? zS8lp2(q>;RXR|F;1O}EE#}gCrY~#n^O`_I&?&z5~7N;zL0)3Tup`%)oHMK-^r$NT% zbFg|o?b9w(q@)6w5V%si<$!U<#}s#x@0aX-hP>zwS#9*75VXA4K*%gUc>+yzupTDBOKH8WR4V0pM(HrfbQ&eJ79>HdCvE=F z|J>s;;iDLB^3(9}?biKbxf1$lI!*Z%*0&8UUq}wMyPs_hclyQQi4;NUY+x2qy|0J; zhn8;5)4ED1oHwg+VZF|80<4MrL97tGGXc5Sw$wAI#|2*cvQ=jB5+{AjMiDHmhUC*a zlmiZ`LAuAn_}hftXh;`Kq0zblDk8?O-`tnilIh|;3lZp@F_osJUV9`*R29M?7H{Fy z`nfVEIDIWXmU&YW;NjU8)EJpXhxe5t+scf|VXM!^bBlwNh)~7|3?fWwo_~ZFk(22% zTMesYw+LNx3J-_|DM~`v93yXe=jPD{q;li;5PD?Dyk+b? zo21|XpT@)$BM$%F=P9J19Vi&1#{jM3!^Y&fr&_`toi`XB1!n>sbL%U9I5<7!@?t)~ z;&H%z>bAaQ4f$wIzkjH70;<8tpUoxzKrPhn#IQfS%9l5=Iu))^XC<58D!-O z{B+o5R^Z21H0T9JQ5gNJnqh#qH^na|z92=hONIM~@_iuOi|F>jBh-?aA20}Qx~EpDGElELNn~|7WRXRFnw+Wdo`|# zBpU=Cz3z%cUJ0mx_1($X<40XEIYz(`noWeO+x#yb_pwj6)R(__%@_Cf>txOQ74wSJ z0#F3(zWWaR-jMEY$7C*3HJrohc79>MCUu26mfYN)f4M~4gD`}EX4e}A!U}QV8!S47 z6y-U-%+h`1n`*pQuKE%Av0@)+wBZr9mH}@vH@i{v(m-6QK7Ncf17x_D=)32`FOjjo zg|^VPf5c6-!FxN{25dvVh#fog=NNpXz zfB$o+0jbRkHH{!TKhE709f+jI^$3#v1Nmf80w`@7-5$1Iv_`)W^px8P-({xwb;D0y z7LKDAHgX<84?l!I*Dvi2#D@oAE^J|g$3!)x1Ua;_;<@#l1fD}lqU2_tS^6Ht$1Wl} zBESo7o^)9-Tjuz$8YQSGhfs{BQV6zW7dA?0b(Dbt=UnQs&4zHfe_sj{RJ4uS-vQpC zX;Bbsuju4%!o8?&m4UZU@~ZZjeFF6ex2ss5_60_JS_|iNc+R0GIjH1@Z z=rLT9%B|WWgOrR7IiIwr2=T;Ne?30M!@{%Qf8o`!>=s<2CBpCK_TWc(DX51>e^xh8 z&@$^b6CgOd7KXQV&Y4%}_#uN*mbanXq(2=Nj`L7H7*k(6F8s6{FOw@(DzU`4-*77{ zF+dxpv}%mFpYK?>N_2*#Y?oB*qEKB}VoQ@bzm>ptmVS_EC(#}Lxxx730trt0G)#$b zE=wVvtqOct1%*9}U{q<)2?{+0TzZzP0jgf9*)arV)*e!f`|jgT{7_9iS@e)recI#z zbzolURQ+TOzE!ymqvBY7+5NnAbWxvMLsLTwEbFqW=CPyCsmJ}P1^V30|D5E|p3BC5 z)3|qgw@ra7aXb-wsa|l^in~1_fm{7bS9jhVRkYVO#U{qMp z)Wce+|DJ}4<2gp8r0_xfZpMo#{Hl2MfjLcZdRB9(B(A(f;+4s*FxV{1F|4d`*sRNd zp4#@sEY|?^FIJ;tmH{@keZ$P(sLh5IdOk@k^0uB^BWr@pk6mHy$qf&~rI>P*a;h0C{%oA*i!VjWn&D~O#MxN&f@1Po# zKN+ zrGrkSjcr?^R#nGl<#Q722^wbYcgW@{+6CBS<1@%dPA8HC!~a`jTz<`g_l5N1M@9wn9GOAZ>nqNgq!yOCbZ@1z`U_N`Z>}+1HIZxk*5RDc&rd5{3qjRh8QmT$VyS;jK z;AF+r6XnnCp=wQYoG|rT2@8&IvKq*IB_WvS%nt%e{MCFm`&W*#LXc|HrD?nVBo=(8*=Aq?u$sDA_sC_RPDUiQ+wnIJET8vx$&fxkW~kP9qXKt zozR)@xGC!P)CTkjeWvXW5&@2?)qt)jiYWWBU?AUtzAN}{JE1I)dfz~7$;}~BmQF`k zpn11qmObXwRB8&rnEG*#4Xax3XBkKlw(;tb?Np^i+H8m(Wyz9k{~ogba@laiEk;2! zV*QV^6g6(QG%vX5Um#^sT&_e`B1pBW5yVth~xUs#0}nv?~C#l?W+9Lsb_5)!71rirGvY zTIJ$OPOY516Y|_014sNv+Z8cc5t_V=i>lWV=vNu#!58y9Zl&GsMEW#pPYPYGHQ|;vFvd*9eM==$_=vc7xnyz0~ zY}r??$<`wAO?JQk@?RGvkWVJlq2dk9vB(yV^vm{=NVI8dhsX<)O(#nr9YD?I?(VmQ z^r7VfUBn<~p3()8yOBjm$#KWx!5hRW)5Jl7wY@ky9lNM^jaT##8QGVsYeaVywmpv>X|Xj7gWE1Ezai&wVLt3p)k4w~yrskT-!PR!kiyQlaxl(( zXhF%Q9x}1TMt3~u@|#wWm-Vq?ZerK={8@~&@9r5JW}r#45#rWii};t`{5#&3$W)|@ zbAf2yDNe0q}NEUvq_Quq3cTjcw z@H_;$hu&xllCI9CFDLuScEMg|x{S7GdV8<&Mq=ezDnRZAyX-8gv97YTm0bg=d)(>N z+B2FcqvI9>jGtnK%eO%y zoBPkJTk%y`8TLf4)IXPBn`U|9>O~WL2C~C$z~9|0m*YH<-vg2CD^SX#&)B4ngOSG$ zV^wmy_iQk>dfN@Pv(ckfy&#ak@MLC7&Q6Ro#!ezM*VEh`+b3Jt%m(^T&p&WJ2Oqvj zs-4nq0TW6cv~(YI$n0UkfwN}kg3_fp?(ijSV#tR9L0}l2qjc7W?i*q01=St0eZ=4h zyGQbEw`9OEH>NMuIe)hVwYHsGERWOD;JxEiO7cQv%pFCeR+IyhwQ|y@&^24k+|8fD zLiOWFNJ2&vu2&`Jv96_z-Cd5RLgmeY3*4rDOQo?Jm`;I_(+ejsPM03!ly!*Cu}Cco zrQSrEDHNyzT(D5s1rZq!8#?f6@v6dB7a-aWs(Qk>N?UGAo{gytlh$%_IhyL7h?DLXDGx zgxGEBQoCAWo-$LRvM=F5MTle`M})t3vVv;2j0HZY&G z22^iGhV@uaJh(XyyY%} zd4iH_UfdV#T=3n}(Lj^|n;O4|$;xhu*8T3hR1mc_A}fK}jfZ7LX~*n5+`8N2q#rI$ z@<_2VANlYF$vIH$ zl<)+*tIWW78IIINA7Rr7i{<;#^yzxoLNkXL)eSs=%|P>$YQIh+ea_3k z_s7r4%j7%&*NHSl?R4k%1>Z=M9o#zxY!n8sL5>BO-ZP;T3Gut>iLS@U%IBrX6BA3k z)&@q}V8a{X<5B}K5s(c(LQ=%v1ocr`t$EqqY0EqVjr65usa=0bkf|O#ky{j3)WBR(((L^wmyHRzoWuL2~WTC=`yZ zn%VX`L=|Ok0v7?s>IHg?yArBcync5rG#^+u)>a%qjES%dRZoIyA8gQ;StH z1Ao7{<&}6U=5}4v<)1T7t!J_CL%U}CKNs-0xWoTTeqj{5{?Be$L0_tk>M9o8 zo371}S#30rKZFM{`H_(L`EM9DGp+Mifk&IP|C2Zu_)Ghr4Qtpmkm1osCf@%Z$%t+7 zYH$Cr)Ro@3-QDeQJ8m+x6%;?YYT;k6Z0E-?kr>x33`H%*ueBD7Zx~3&HtWn0?2Wt} zTG}*|v?{$ajzt}xPzV%lL1t-URi8*Zn)YljXNGDb>;!905Td|mpa@mHjIH%VIiGx- zd@MqhpYFu4_?y5N4xiHn3vX&|e6r~Xt> zZG`aGq|yTNjv;9E+Txuoa@A(9V7g?1_T5FzRI;!=NP1Kqou1z5?%X~Wwb{trRfd>i z8&y^H)8YnKyA_Fyx>}RNmQIczT?w2J4SNvI{5J&}Wto|8FR(W;Qw#b1G<1%#tmYzQ zQ2mZA-PAdi%RQOhkHy9Ea#TPSw?WxwL@H@cbkZwIq0B!@ns}niALidmn&W?!Vd4Gj zO7FiuV4*6Mr^2xlFSvM;Cp_#r8UaqIzHJQg_z^rEJw&OMm_8NGAY2)rKvki|o1bH~ z$2IbfVeY2L(^*rMRU1lM5Y_sgrDS`Z??nR2lX;zyR=c%UyGb*%TC-Dil?SihkjrQy~TMv6;BMs7P8il`H7DmpVm@rJ;b)hW)BL)GjS154b*xq-NXq2cwE z^;VP7ua2pxvCmxrnqUYQMH%a%nHmwmI33nJM(>4LznvY*k&C0{8f*%?zggpDgkuz&JBx{9mfb@wegEl2v!=}Sq2Gaty0<)UrOT0{MZtZ~j5y&w zXlYa_jY)I_+VA-^#mEox#+G>UgvM!Ac8zI<%JRXM_73Q!#i3O|)lOP*qBeJG#BST0 zqohi)O!|$|2SeJQo(w6w7%*92S})XfnhrH_Z8qe!G5>CglP=nI7JAOW?(Z29;pXJ9 zR9`KzQ=WEhy*)WH>$;7Cdz|>*i>=##0bB)oU0OR>>N<21e4rMCHDemNi2LD>Nc$;& zQRFthpWniC1J6@Zh~iJCoLOxN`oCKD5Q4r%ynwgUKPlIEd#?QViIqovY|czyK8>6B zSP%{2-<;%;1`#0mG^B(8KbtXF;Nf>K#Di72UWE4gQ%(_26Koiad)q$xRL~?pN71ZZ zujaaCx~jXjygw;rI!WB=xrOJO6HJ!!w}7eiivtCg5K|F6$EXa)=xUC za^JXSX98W`7g-tm@uo|BKj39Dl;sg5ta;4qjo^pCh~{-HdLl6qI9Ix6f$+qiZ$}s= zNguKrU;u+T@ko(Vr1>)Q%h$?UKXCY>3se%&;h2osl2D zE4A9bd7_|^njDd)6cI*FupHpE3){4NQ*$k*cOWZ_?CZ>Z4_fl@n(mMnYK62Q1d@+I zr&O))G4hMihgBqRIAJkLdk(p(D~X{-oBUA+If@B}j& zsHbeJ3RzTq96lB7d($h$xTeZ^gP0c{t!Y0c)aQE;$FY2!mACg!GDEMKXFOPI^)nHZ z`aSPJpvV0|bbrzhWWkuPURlDeN%VT8tndV8?d)eN*i4I@u zVKl^6{?}A?P)Fsy?3oi#clf}L18t;TjNI2>eI&(ezDK7RyqFxcv%>?oxUlonv(px) z$vnPzRH`y5A(x!yOIfL0bmgeMQB$H5wenx~!ujQK*nUBW;@Em&6Xv2%s(~H5WcU2R z;%Nw<$tI)a`Ve!>x+qegJnQsN2N7HaKzrFqM>`6R*gvh%O*-%THt zrB$Nk;lE;z{s{r^PPm5qz(&lM{sO*g+W{sK+m3M_z=4=&CC>T`{X}1Vg2PEfSj2x_ zmT*(x;ov%3F?qoEeeM>dUn$a*?SIGyO8m806J1W1o+4HRhc2`9$s6hM#qAm zChQ87b~GEw{ADfs+5}FJ8+|bIlIv(jT$Ap#hSHoXdd9#w<#cA<1Rkq^*EEkknUd4& zoIWIY)sAswy6fSERVm&!SO~#iN$OgOX*{9@_BWFyJTvC%S++ilSfCrO(?u=Dc?CXZ zzCG&0yVR{Z`|ZF0eEApWEo#s9osV>F{uK{QA@BES#&;#KsScf>y zvs?vIbI>VrT<*!;XmQS=bhq%46-aambZ(8KU-wOO2=en~D}MCToB_u;Yz{)1ySrPZ z@=$}EvjTdzTWU7c0ZI6L8=yP+YRD_eMMos}b5vY^S*~VZysrkq<`cK3>>v%uy7jgq z0ilW9KjVDHLv0b<1K_`1IkbTOINs0=m-22c%M~l=^S}%hbli-3?BnNq?b`hx^HX2J zIe6ECljRL0uBWb`%{EA=%!i^4sMcj+U_TaTZRb+~GOk z^ZW!nky0n*Wb*r+Q|9H@ml@Z5gU&W`(z4-j!OzC1wOke`TRAYGZVl$PmQ16{3196( zO*?`--I}Qf(2HIwb2&1FB^!faPA2=sLg(@6P4mN)>Dc3i(B0;@O-y2;lM4akD>@^v z=u>*|!s&9zem70g7zfw9FXl1bpJW(C#5w#uy5!V?Q(U35A~$dR%LDVnq@}kQm13{} zd53q3N(s$Eu{R}k2esbftfjfOITCL;jWa$}(mmm}d(&7JZ6d3%IABCapFFYjdEjdK z&4Edqf$G^MNAtL=uCDRs&Fu@FXRgX{*0<(@c3|PNHa>L%zvxWS={L8%qw`STm+=Rd zA}FLspESSIpE_^41~#5yI2bJ=9`oc;GIL!JuW&7YetZ?0H}$$%8rW@*J37L-~Rsx!)8($nI4 zZhcZ2^=Y+p4YPl%j!nFJA|*M^gc(0o$i3nlphe+~-_m}jVkRN{spFs(o0ajW@f3K{ zDV!#BwL322CET$}Y}^0ixYj2w>&Xh12|R8&yEw|wLDvF!lZ#dOTHM9pK6@Nm-@9Lnng4ZHBgBSrr7KI8YCC9DX5Kg|`HsiwJHg2(7#nS;A{b3tVO?Z% za{m5b3rFV6EpX;=;n#wltDv1LE*|g5pQ+OY&*6qCJZc5oDS6Z6JD#6F)bWxZSF@q% z+1WV;m!lRB!n^PC>RgQCI#D1br_o^#iPk>;K2hB~0^<~)?p}LG%kigm@moD#q3PE+ zA^Qca)(xnqw6x>XFhV6ku9r$E>bWNrVH9fum0?4s?Rn2LG{Vm_+QJHse6xa%nzQ?k zKug4PW~#Gtb;#5+9!QBgyB@q=sk9=$S{4T>wjFICStOM?__fr+Kei1 z3j~xPqW;W@YkiUM;HngG!;>@AITg}vAE`M2Pj9Irl4w1fo4w<|Bu!%rh%a(Ai^Zhi zs92>v5;@Y(Zi#RI*ua*h`d_7;byQSa*v9E{2x$<-_=5Z<7{%)}4XExANcz@rK69T0x3%H<@frW>RA8^swA+^a(FxK| zFl3LD*ImHN=XDUkrRhp6RY5$rQ{bRgSO*(vEHYV)3Mo6Jy3puiLmU&g82p{qr0F?ohmbz)f2r{X2|T2 z$4fdQ=>0BeKbiVM!e-lIIs8wVTuC_m7}y4A_%ikI;Wm5$9j(^Y z(cD%U%k)X>_>9~t8;pGzL6L-fmQO@K; zo&vQzMlgY95;1BSkngY)e{`n0!NfVgf}2mB3t}D9@*N;FQ{HZ3Pb%BK6;5#-O|WI( zb6h@qTLU~AbVW#_6?c!?Dj65Now7*pU{h!1+eCV^KCuPAGs28~3k@ueL5+u|Z-7}t z9|lskE`4B7W8wMs@xJa{#bsCGDFoRSNSnmNYB&U7 zVGKWe%+kFB6kb)e;TyHfqtU6~fRg)f|>=5(N36)0+C z`hv65J<$B}WUc!wFAb^QtY31yNleq4dzmG`1wHTj=c*=hay9iD071Hc?oYoUk|M*_ zU1GihAMBsM@5rUJ(qS?9ZYJ6@{bNqJ`2Mr+5#hKf?doa?F|+^IR!8lq9)wS3tF_9n zW_?hm)G(M+MYb?V9YoX^_mu5h-LP^TL^!Q9Z7|@sO(rg_4+@=PdI)WL(B7`!K^ND- z-uIuVDCVEdH_C@c71YGYT^_Scf_dhB8Z2Xy6vGtBSlYud9vggOqv^L~F{BraSE_t} zIkP+Hp2&nH^-MNEs}^`oMLy11`PQW$T|K(`Bu*(f@)mv1-qY(_YG&J2M2<7k;;RK~ zL{Fqj9yCz8(S{}@c)S!65aF<=&eLI{hAMErCx&>i7OeDN>okvegO87OaG{Jmi<|}D zaT@b|0X{d@OIJ7zvT>r+eTzgLq~|Dpu)Z&db-P4z*`M$UL51lf>FLlq6rfG)%doyp z)3kk_YIM!03eQ8Vu_2fg{+osaEJPtJ-s36R+5_AEG12`NG)IQ#TF9c@$99%0iye+ zUzZ57=m2)$D(5Nx!n)=5Au&O0BBgwxIBaeI(mro$#&UGCr<;C{UjJVAbVi%|+WP(a zL$U@TYCxJ=1{Z~}rnW;7UVb7+ZnzgmrogDxhjLGo>c~MiJAWs&&;AGg@%U?Y^0JhL ze(x6Z74JG6FlOFK(T}SXQfhr}RIFl@QXKnIcXYF)5|V~e-}suHILKT-k|<*~Ij|VF zC;t@=uj=hot~*!C68G8hTA%8SzOfETOXQ|3FSaIEjvBJp(A)7SWUi5!Eu#yWgY+;n zlm<$+UDou*V+246_o#V4kMdto8hF%%Lki#zPh}KYXmMf?hrN0;>Mv%`@{0Qn`Ujp) z=lZe+13>^Q!9zT);H<(#bIeRWz%#*}sgUX9P|9($kexOyKIOc`dLux}c$7It4u|Rl z6SSkY*V~g_B-hMPo_ak>>z@AVQ(_N)VY2kB3IZ0G(iDUYw+2d7W^~(Jq}KY=JnWS( z#rzEa&0uNhJ>QE8iiyz;n2H|SV#Og+wEZv=f2%1ELX!SX-(d3tEj$5$1}70Mp<&eI zCkfbByL7af=qQE@5vDVxx1}FSGt_a1DoE3SDI+G)mBAna)KBG4p8Epxl9QZ4BfdAN zFnF|Y(umr;gRgG6NLQ$?ZWgllEeeq~z^ZS7L?<(~O&$5|y)Al^iMKy}&W+eMm1W z7EMU)u^ke(A1#XCV>CZ71}P}0x)4wtHO8#JRG3MA-6g=`ZM!FcICCZ{IEw8Dm2&LQ z1|r)BUG^0GzI6f946RrBlfB1Vs)~8toZf~7)+G;pv&XiUO(%5bm)pl=p>nV^o*;&T z;}@oZSibzto$arQgfkp|z4Z($P>dTXE{4O=vY0!)kDO* zGF8a4wq#VaFpLfK!iELy@?-SeRrdz%F*}hjKcA*y@mj~VD3!it9lhRhX}5YOaR9$} z3mS%$2Be7{l(+MVx3 z(4?h;P!jnRmX9J9sYN#7i=iyj_5q7n#X(!cdqI2lnr8T$IfOW<_v`eB!d9xY1P=2q&WtOXY=D9QYteP)De?S4}FK6#6Ma z=E*V+#s8>L;8aVroK^6iKo=MH{4yEZ_>N-N z`(|;aOATba1^asjxlILk<4}f~`39dBFlxj>Dw(hMYKPO3EEt1@S`1lxFNM+J@uB7T zZ8WKjz7HF1-5&2=l=fqF-*@>n5J}jIxdDwpT?oKM3s8Nr`x8JnN-kCE?~aM1H!hAE z%%w(3kHfGwMnMmNj(SU(w42OrC-euI>Dsjk&jz3ts}WHqmMpzQ3vZrsXrZ|}+MHA7 z068obeXZTsO*6RS@o3x80E4ok``rV^Y3hr&C1;|ZZ0|*EKO`$lECUYG2gVFtUTw)R z4Um<0ZzlON`zTdvVdL#KFoMFQX*a5wM0Czp%wTtfK4Sjs)P**RW&?lP$(<}q%r68Z zS53Y!d@&~ne9O)A^tNrXHhXBkj~$8j%pT1%%mypa9AW5E&s9)rjF4@O3ytH{0z6riz|@< zB~UPh*wRFg2^7EbQrHf0y?E~dHlkOxof_a?M{LqQ^C!i2dawHTPYUE=X@2(3<=OOxs8qn_(y>pU>u^}3y&df{JarR0@VJn0f+U%UiF=$Wyq zQvnVHESil@d|8&R<%}uidGh7@u^(%?$#|&J$pvFC-n8&A>utA=n3#)yMkz+qnG3wd zP7xCnF|$9Dif@N~L)Vde3hW8W!UY0BgT2v(wzp;tlLmyk2%N|0jfG$%<;A&IVrOI< z!L)o>j>;dFaqA3pL}b-Je(bB@VJ4%!JeX@3x!i{yIeIso^=n?fDX`3bU=eG7sTc%g%ye8$v8P@yKE^XD=NYxTb zbf!Mk=h|otpqjFaA-vs5YOF-*GwWPc7VbaOW&stlANnCN8iftFMMrUdYNJ_Bnn5Vt zxfz@Ah|+4&P;reZxp;MmEI7C|FOv8NKUm8njF7Wb6Gi7DeODLl&G~}G4be&*Hi0Qw z5}77vL0P+7-B%UL@3n1&JPxW^d@vVwp?u#gVcJqY9#@-3X{ok#UfW3<1fb%FT`|)V~ggq z(3AUoUS-;7)^hCjdT0Kf{i}h)mBg4qhtHHBti=~h^n^OTH5U*XMgDLIR@sre`AaB$ zg)IGBET_4??m@cx&c~bA80O7B8CHR7(LX7%HThkeC*@vi{-pL%e)yXp!B2InafbDF zjPXf1mko3h59{lT6EEbxKO1Z5GF71)WwowO6kY|6tjSVSWdQ}NsK2x{>i|MKZK8%Q zfu&_0D;CO-Jg0#YmyfctyJ!mRJp)e#@O0mYdp|8x;G1%OZQ3Q847YWTyy|%^cpA;m zze0(5p{tMu^lDkpe?HynyO?a1$_LJl2L&mpeKu%8YvgRNr=%2z${%WThHG=vrWY@4 zsA`OP#O&)TetZ>s%h!=+CE15lOOls&nvC~$Qz0Ph7tHiP;O$i|eDwpT{cp>+)0-|; zY$|bB+Gbel>5aRN3>c0x)4U=|X+z+{ zn*_p*EQoquRL+=+p;=lm`d71&1NqBz&_ph)MXu(Nv6&XE7(RsS)^MGj5Q?Fwude-(sq zjJ>aOq!7!EN>@(fK7EE#;i_BGvli`5U;r!YA{JRodLBc6-`n8K+Fjgwb%sX;j=qHQ z7&Tr!)!{HXoO<2BQrV9Sw?JRaLXV8HrsNevvnf>Y-6|{T!pYLl7jp$-nEE z#X!4G4L#K0qG_4Z;Cj6=;b|Be$hi4JvMH!-voxqx^@8cXp`B??eFBz2lLD8RRaRGh zn7kUfy!YV~p(R|p7iC1Rdgt$_24i0cd-S8HpG|`@my70g^y`gu%#Tf_L21-k?sRRZHK&at(*ED0P8iw{7?R$9~OF$Ko;Iu5)ur5<->x!m93Eb zFYpIx60s=Wxxw=`$aS-O&dCO_9?b1yKiPCQmSQb>T)963`*U+Ydj5kI(B(B?HNP8r z*bfSBpSu)w(Z3j7HQoRjUG(+d=IaE~tv}y14zHHs|0UcN52fT8V_<@2ep_ee{QgZG zmgp8iv4V{k;~8@I%M3<#B;2R>Ef(Gg_cQM7%}0s*^)SK6!Ym+~P^58*wnwV1BW@eG z4sZLqsUvBbFsr#8u7S1r4teQ;t)Y@jnn_m5jS$CsW1um!p&PqAcc8!zyiXHVta9QC zY~wCwCF0U%xiQPD_INKtTb;A|Zf29(mu9NI;E zc-e>*1%(LSXB`g}kd`#}O;veb<(sk~RWL|f3ljxCnEZDdNSTDV6#Td({6l&y4IjKF z^}lIUq*ZUqgTPumD)RrCN{M^jhY>E~1pn|KOZ5((%F)G|*ZQ|r4zIbrEiV%42hJV8 z3xS)=!X1+=olbdGJ=yZil?oXLct8FM{(6ikLL3E%=q#O6(H$p~gQu6T8N!plf!96| z&Q3=`L~>U0zZh;z(pGR2^S^{#PrPxTRHD1RQOON&f)Siaf`GLj#UOk&(|@0?zm;Sx ztsGt8=29-MZs5CSf1l1jNFtNt5rFNZxJPvkNu~2}7*9468TWm>nN9TP&^!;J{-h)_ z7WsHH9|F%I`Pb!>KAS3jQWKfGivTVkMJLO-HUGM_a4UQ_%RgL6WZvrW+Z4ujZn;y@ zz9$=oO!7qVTaQAA^BhX&ZxS*|5dj803M=k&2%QrXda`-Q#IoZL6E(g+tN!6CA!CP* zCpWtCujIea)ENl0liwVfj)Nc<9mV%+e@=d`haoZ*`B7+PNjEbXBkv=B+Pi^~L#EO$D$ZqTiD8f<5$eyb54-(=3 zh)6i8i|jp(@OnRrY5B8t|LFXFQVQ895n*P16cEKTrT*~yLH6Z4e*bZ5otpRDri&+A zfNbK1D5@O=sm`fN=WzWyse!za5n%^+6dHPGX#8DyIK>?9qyX}2XvBWVqbP%%D)7$= z=#$WulZlZR<{m#gU7lwqK4WS1Ne$#_P{b17qe$~UOXCl>5b|6WVh;5vVnR<%d+Lnp z$uEmML38}U4vaW8>shm6CzB(Wei3s#NAWE3)a2)z@i{4jTn;;aQS)O@l{rUM`J@K& l00vQ5JBs~;vo!vr%%-k{2_Fq1Mn4QF81S)AQ99zk{{c4yR+0b! literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a80b22c --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..1aa94a4 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..25da30d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts new file mode 100644 index 0000000..6e8f86e --- /dev/null +++ b/lib/build.gradle.kts @@ -0,0 +1,47 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Kotlin library project to get you started. + * For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.6/userguide/building_java_projects.html in the Gradle documentation. + */ + +plugins { + // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. + alias(libs.plugins.jvm) + + // Apply the java-library plugin for API and implementation separation. + `java-library` +} + +repositories { + // Use Maven Central for resolving dependencies. + mavenCentral() +} + +dependencies { + // Use the Kotlin JUnit 5 integration. + testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") + + // Use the JUnit 5 integration. + testImplementation(libs.junit.jupiter.engine) + + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + + // This dependency is exported to consumers, that is to say found on their compile classpath. + api(libs.commons.math3) + + // This dependency is used internally, and not exposed to consumers on their own compile classpath. + implementation(libs.guava) +} + +// Apply a specific Java toolchain to ease working on different environments. +java { + toolchain { + languageVersion = JavaLanguageVersion.of(11) + } +} + +tasks.named("test") { + // Use JUnit Platform for unit tests. + useJUnitPlatform() +} diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..5073bcb --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,14 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.6/userguide/multi_project_builds.html in the Gradle documentation. + */ + +plugins { + // Apply the foojay-resolver plugin to allow automatic download of JDKs + id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" +} + +rootProject.name = "trees-9" +include("lib") From 4c5509e86628fbd0ea268da70956d51318cadf3f Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 15:46:59 +0300 Subject: [PATCH 004/227] feat: add library architecture --- lib/src/main/AVLSearchTree.kt | 10 ++++++ lib/src/main/AVLVertex.kt | 18 ++++++++++ lib/src/main/AbstractBinarySearchTree.kt | 45 ++++++++++++++++++++++++ lib/src/main/InterfaceBSTVertex.kt | 7 ++++ lib/src/main/Pair.kt | 1 + lib/src/main/RBSearchTree.kt | 10 ++++++ lib/src/main/RBVertex.kt | 22 ++++++++++++ lib/src/main/SimpleBSTVertex.kt | 17 +++++++++ lib/src/main/SimpleBinarySearchTree.kt | 10 ++++++ lib/src/main/TreeIterator.kt | 7 ++++ 10 files changed, 147 insertions(+) create mode 100644 lib/src/main/AVLSearchTree.kt create mode 100644 lib/src/main/AVLVertex.kt create mode 100644 lib/src/main/AbstractBinarySearchTree.kt create mode 100644 lib/src/main/InterfaceBSTVertex.kt create mode 100644 lib/src/main/Pair.kt create mode 100644 lib/src/main/RBSearchTree.kt create mode 100644 lib/src/main/RBVertex.kt create mode 100644 lib/src/main/SimpleBSTVertex.kt create mode 100644 lib/src/main/SimpleBinarySearchTree.kt create mode 100644 lib/src/main/TreeIterator.kt diff --git a/lib/src/main/AVLSearchTree.kt b/lib/src/main/AVLSearchTree.kt new file mode 100644 index 0000000..d74e393 --- /dev/null +++ b/lib/src/main/AVLSearchTree.kt @@ -0,0 +1,10 @@ +class AVLSearchTree : AbstractBinarySearchTree> { + + override fun put(key: K, value: V) {TODO()} + + override fun remove(key: K): V? {TODO()} + + constructor (comparator: Comparator? = null) : super(comparator) + + constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) +} diff --git a/lib/src/main/AVLVertex.kt b/lib/src/main/AVLVertex.kt new file mode 100644 index 0000000..75c2162 --- /dev/null +++ b/lib/src/main/AVLVertex.kt @@ -0,0 +1,18 @@ +class AVLVertex( + override var key: K, + override var value: V +): InterfaceBSTVertex> { + + override var leftSon: AVLVertex? = null + override var rightSon: AVLVertex? = null + var sonsHeightDiff: Int = 0 + + constructor( + key: K, + value: V, + leftSon: AVLVertex?, + rightSon: AVLVertex? + ) : this(key, value) { + this.leftSon = leftSon; this.rightSon = rightSon + } +} diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt new file mode 100644 index 0000000..3eaf106 --- /dev/null +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -0,0 +1,45 @@ +abstract class AbstractBinarySearchTree> { + + protected var comparator: Comparator? = null + protected var size : Long = 0L + protected var root : InterfaceBSTVertex? = null + + operator fun iterator(): Iterator> {TODO()} + + fun size(): Long {TODO()} + + fun isEmpty(): Boolean {TODO()} + + fun get(key: K): V? {TODO()} + + fun getPair(key: K): Pair? {TODO()} + + fun getMin(): V? {TODO()} + + fun getMax(): V?{TODO()} + + fun getMinKeyPair(): Pair? {TODO()} + + fun getMaxKeyPair(): Pair? {TODO()} + + abstract fun put(key: K, value: V) + + fun putAll(map: Map){TODO()} + + abstract fun remove(key: K): V? + + fun removeAndReturnPair(key: K): Pair? {TODO()} + + protected fun getMinKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} + + protected fun getMaxKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} + + constructor(comparator: Comparator? = null) { + this.comparator = comparator + } + + constructor(map: Map, comparator: Comparator? = null) { + putAll(map) + this.comparator = comparator + } +} diff --git a/lib/src/main/InterfaceBSTVertex.kt b/lib/src/main/InterfaceBSTVertex.kt new file mode 100644 index 0000000..703b199 --- /dev/null +++ b/lib/src/main/InterfaceBSTVertex.kt @@ -0,0 +1,7 @@ +interface InterfaceBSTVertex { + + var key: K + var value: V + var leftSon: N? + var rightSon: N? +} diff --git a/lib/src/main/Pair.kt b/lib/src/main/Pair.kt new file mode 100644 index 0000000..52b8b45 --- /dev/null +++ b/lib/src/main/Pair.kt @@ -0,0 +1 @@ +class Pair(var key: K, var value: V) diff --git a/lib/src/main/RBSearchTree.kt b/lib/src/main/RBSearchTree.kt new file mode 100644 index 0000000..994c25a --- /dev/null +++ b/lib/src/main/RBSearchTree.kt @@ -0,0 +1,10 @@ +class RBSearchTree : AbstractBinarySearchTree> { + + override fun put(key: K, value: V) {TODO()} + + override fun remove(key: K): V? {TODO()} + + constructor(comparator: Comparator? = null) : super(comparator) + + constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) +} diff --git a/lib/src/main/RBVertex.kt b/lib/src/main/RBVertex.kt new file mode 100644 index 0000000..a267e19 --- /dev/null +++ b/lib/src/main/RBVertex.kt @@ -0,0 +1,22 @@ +class RBVertex( + override var key: K, + override var value: V +) : InterfaceBSTVertex> { + + var isRed = false + var parent: RBVertex? = null + override var leftSon: RBVertex? = null + override var rightSon: RBVertex? = null + + constructor( + key: K, + value: V, + leftSon: RBVertex?, + rightSon: RBVertex?, + isRed: Boolean, + parent: RBVertex? + ) : this(key, value) { + this.leftSon = leftSon; this.rightSon = rightSon; this.parent = parent; this.isRed = isRed + } +} + diff --git a/lib/src/main/SimpleBSTVertex.kt b/lib/src/main/SimpleBSTVertex.kt new file mode 100644 index 0000000..62583c6 --- /dev/null +++ b/lib/src/main/SimpleBSTVertex.kt @@ -0,0 +1,17 @@ +class SimpleBSTVertex( + override var key: K, + override var value: V +): InterfaceBSTVertex> { + + override var leftSon: SimpleBSTVertex? = null + override var rightSon: SimpleBSTVertex? = null + + constructor( + key: K, + value: V, + leftSon: SimpleBSTVertex?, + rightSon: SimpleBSTVertex? + ) : this(key, value) { + this.leftSon = leftSon; this.rightSon = rightSon + } +} diff --git a/lib/src/main/SimpleBinarySearchTree.kt b/lib/src/main/SimpleBinarySearchTree.kt new file mode 100644 index 0000000..e04af09 --- /dev/null +++ b/lib/src/main/SimpleBinarySearchTree.kt @@ -0,0 +1,10 @@ +class SimpleBinarySearchTree : AbstractBinarySearchTree> { + + override fun put(key: K, value: V) {TODO()} + + override fun remove(key: K): V? {TODO()} + + constructor(comparator: Comparator?) : super(comparator) + + constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) +} diff --git a/lib/src/main/TreeIterator.kt b/lib/src/main/TreeIterator.kt new file mode 100644 index 0000000..65a1f42 --- /dev/null +++ b/lib/src/main/TreeIterator.kt @@ -0,0 +1,7 @@ +internal class TreeIterator>( + vertex: InterfaceBSTVertex?): Iterator> { + + override fun hasNext(): Boolean {TODO()} + + override fun next(): Pair {TODO()} +} From 6e36688aa91601b8d87812c25797fd737a438cbc Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 16:41:41 +0300 Subject: [PATCH 005/227] feat: implement AbstractBinarySearchTree method size() --- lib/src/main/AbstractBinarySearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 3eaf106..7d13cf8 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -6,7 +6,7 @@ abstract class AbstractBinarySearchTree> { operator fun iterator(): Iterator> {TODO()} - fun size(): Long {TODO()} + fun size(): Long {return size} fun isEmpty(): Boolean {TODO()} From 047985130c1634390a2ea50eaf4a4077d57dff36 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 16:43:08 +0300 Subject: [PATCH 006/227] feat: implement AbstractBinarySearchTree method isEmpty() --- lib/src/main/AbstractBinarySearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 7d13cf8..cafef2b 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -8,7 +8,7 @@ abstract class AbstractBinarySearchTree> { fun size(): Long {return size} - fun isEmpty(): Boolean {TODO()} + fun isEmpty(): Boolean {return size == 0L} fun get(key: K): V? {TODO()} From c6403832f6cc0053b4f78bb585cc919162f19b79 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 16:44:59 +0300 Subject: [PATCH 007/227] feat: implement AbstractBinarySearchTree method get() --- lib/src/main/AbstractBinarySearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index cafef2b..0e2f834 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -10,7 +10,7 @@ abstract class AbstractBinarySearchTree> { fun isEmpty(): Boolean {return size == 0L} - fun get(key: K): V? {TODO()} + fun get(key: K): V? {return getRec(key)} fun getPair(key: K): Pair? {TODO()} From 15cf5be8d9345629ab6f41f36d4c1add4f760dd2 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 16:57:30 +0300 Subject: [PATCH 008/227] feat: implement AbstractBinarySearchTree method getPair() --- lib/src/main/AbstractBinarySearchTree.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 0e2f834..d5efcc1 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -12,7 +12,10 @@ abstract class AbstractBinarySearchTree> { fun get(key: K): V? {return getRec(key)} - fun getPair(key: K): Pair? {TODO()} + fun getPair(key: K): Pair? { + val value = get(key) + return if (value == null) null else Pair(key, value) + } fun getMin(): V? {TODO()} From 1eeb3cc2b278c9e06954f192ec2f891019bf3ddb Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 17:09:07 +0300 Subject: [PATCH 009/227] feat: implement AbstractBinarySearchTree method getMin() --- lib/src/main/AbstractBinarySearchTree.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index d5efcc1..03d6fb9 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -17,7 +17,10 @@ abstract class AbstractBinarySearchTree> { return if (value == null) null else Pair(key, value) } - fun getMin(): V? {TODO()} + fun getMin(): V? { + val minKeyNode = getMinKeyNodeRec() + return if (minKeyNode == null) null else minKeyNode.value + } fun getMax(): V?{TODO()} From 6bea25debfa9688edc28d914450941fff5f4f975 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 17:10:38 +0300 Subject: [PATCH 010/227] feat: implement AbstractBinarySearchTree method getMax() --- lib/src/main/AbstractBinarySearchTree.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 03d6fb9..105f067 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -22,7 +22,10 @@ abstract class AbstractBinarySearchTree> { return if (minKeyNode == null) null else minKeyNode.value } - fun getMax(): V?{TODO()} + fun getMax(): V?{ + val maxKeyNode = getMaxKeyNodeRec() + return if (maxKeyNode == null) null else maxKeyNode.value + } fun getMinKeyPair(): Pair? {TODO()} From d997d733da6d3cba798575c42d59fdfaf5d48814 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 17:12:01 +0300 Subject: [PATCH 011/227] feat: implement AbstractBinarySearchTree method getMinKeyPair() --- lib/src/main/AbstractBinarySearchTree.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 105f067..57d2e9b 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -27,7 +27,10 @@ abstract class AbstractBinarySearchTree> { return if (maxKeyNode == null) null else maxKeyNode.value } - fun getMinKeyPair(): Pair? {TODO()} + fun getMinKeyPair(): Pair? { + val minKeyNode = getMinKeyNodeRec() + return if (minKeyNode == null) null else Pair(minKeyNode.key, minKeyNode.value) + } fun getMaxKeyPair(): Pair? {TODO()} From 518bc9123d49289c0f23677775f1f745ad1fd248 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 17:13:04 +0300 Subject: [PATCH 012/227] feat: implement AbstractBinarySearchTree method getMaxKeyPair() --- lib/src/main/AbstractBinarySearchTree.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 57d2e9b..b6b5863 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -32,7 +32,10 @@ abstract class AbstractBinarySearchTree> { return if (minKeyNode == null) null else Pair(minKeyNode.key, minKeyNode.value) } - fun getMaxKeyPair(): Pair? {TODO()} + fun getMaxKeyPair(): Pair? { + val maxKeyNode = getMaxKeyNodeRec() + return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) + } abstract fun put(key: K, value: V) From 870fb492dbcd09c2d47a87ed367f9e96180efb8c Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 17:15:05 +0300 Subject: [PATCH 013/227] feat: implement AbstractBinarySearchTree method putAll() --- lib/src/main/AbstractBinarySearchTree.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index b6b5863..9624340 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -39,7 +39,9 @@ abstract class AbstractBinarySearchTree> { abstract fun put(key: K, value: V) - fun putAll(map: Map){TODO()} + fun putAll(map: Map) { + for (pair in map) put(pair.key, pair.value) + } abstract fun remove(key: K): V? From aafd9dd9ed55b75c4a2341e8640791d79768319d Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 17:16:08 +0300 Subject: [PATCH 014/227] feat: implement AbstractBinarySearchTree method removeAndReturnPair() --- lib/src/main/AbstractBinarySearchTree.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 9624340..7de41e7 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -45,7 +45,10 @@ abstract class AbstractBinarySearchTree> { abstract fun remove(key: K): V? - fun removeAndReturnPair(key: K): Pair? {TODO()} + fun removeAndReturnPair(key: K): Pair? { + val value = remove(key) + return if (value == null) null else Pair(key, value) + } protected fun getMinKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} From 7a525ae0c8a6b647e1a3b23c62afdb5a5801b0f4 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 17:27:00 +0300 Subject: [PATCH 015/227] fix: add replaseIfExists param to AbstractBInarySearchTree put() constructor --- lib/src/main/AbstractBinarySearchTree.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 7de41e7..0178e5e 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -37,7 +37,8 @@ abstract class AbstractBinarySearchTree> { return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) } - abstract fun put(key: K, value: V) + abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) +// возможно нужен комментарий fun putAll(map: Map) { for (pair in map) put(pair.key, pair.value) From 3102e7a4f3b68b215b92ee218887aeef5c745f5f Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 16 Mar 2024 17:54:35 +0300 Subject: [PATCH 016/227] feat: implement 'with comparator' part of AbstractBinarySearchTree getRec() --- lib/src/main/AbstractBinarySearchTree.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 3eaf106..aa4b2a9 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -30,6 +30,12 @@ abstract class AbstractBinarySearchTree> { fun removeAndReturnPair(key: K): Pair? {TODO()} + private fun getRec(key: K, vertex: InterfaceBSTVertex? = root): V? { + if (vertex == null) return null + if (vertex.key == key) return vertex.value + val cpr = comparator + if (cpr != null) {TODO()} + protected fun getMinKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} protected fun getMaxKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} From af0ba95d81c426eb9508f0d9d396ff2a29bf721c Mon Sep 17 00:00:00 2001 From: Oreshin Kostya Date: Sun, 17 Mar 2024 15:01:24 +0300 Subject: [PATCH 017/227] ci: create workflow and first test --- .github/workflows/ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6c00c85 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,8 @@ +name: CI Tests Demo +on: workflow_dispatch +jobs: + first_test: + runs-on: ubuntu-latest + steps: + - name: Print to console + run: echo first test completed \ No newline at end of file From 47e08b5e032a6dc06a61c25eb7551b809feee936 Mon Sep 17 00:00:00 2001 From: Oreshin Kostya Date: Sun, 17 Mar 2024 19:52:00 +0300 Subject: [PATCH 018/227] feat: add connection with code in repository, SDK and gradle --- .github/workflows/ci.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c00c85..4d7a9db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,17 @@ -name: CI Tests Demo +name: Build on: workflow_dispatch jobs: - first_test: + build: runs-on: ubuntu-latest steps: - - name: Print to console - run: echo first test completed \ No newline at end of file + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Java JDK + uses: actions/setup-java@v4 + with: + java-version: 21 + cache: gradle + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + - name: Build with Gradle + run: .gradlew build \ No newline at end of file From c49a9c2aeff1395a80ac4709a9381a38980c5c43 Mon Sep 17 00:00:00 2001 From: Oreshin Kostya Date: Mon, 18 Mar 2024 00:45:13 +0300 Subject: [PATCH 019/227] feat: add case when comparator not a null in fun getRec --- lib/src/main/AbstractBinarySearchTree.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index aa4b2a9..40e9c2a 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -34,7 +34,16 @@ abstract class AbstractBinarySearchTree> { if (vertex == null) return null if (vertex.key == key) return vertex.value val cpr = comparator - if (cpr != null) {TODO()} + if (cpr != null) { + return if (cpr.compare(key, vertex.key) < 0) getRec(key, vertex.leftSon) + else getRec(key, vertex.rightSon) + } + else { + val comparableKey: Comparable = key as Comparable + return if (comparableKey.compareTo(vertex.key) < 0) getRec(key, vertex.leftSon) + else getRec(key, vertex.rightSon) + } + } protected fun getMinKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} From 5ae2be10de08c18726e53a414b5232ce99c0156d Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 19 Mar 2024 10:17:04 +0300 Subject: [PATCH 020/227] fix: change root/vertex type in AbstractTree change root/vertex type from InterfaceBSTVertex? to N? --- lib/src/main/AbstractBinarySearchTree.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt index 82fac86..3599dad 100644 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ b/lib/src/main/AbstractBinarySearchTree.kt @@ -2,7 +2,7 @@ abstract class AbstractBinarySearchTree> { protected var comparator: Comparator? = null protected var size : Long = 0L - protected var root : InterfaceBSTVertex? = null + protected var root : N? = null operator fun iterator(): Iterator> {TODO()} @@ -51,7 +51,7 @@ abstract class AbstractBinarySearchTree> { return if (value == null) null else Pair(key, value) } - private fun getRec(key: K, vertex: InterfaceBSTVertex? = root): V? { + private fun getRec(key: K, vertex: N? = root): V? { if (vertex == null) return null if (vertex.key == key) return vertex.value val cpr = comparator @@ -66,9 +66,9 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMinKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} + protected fun getMinKeyNodeRec(vertex: N? = root) : N? {TODO()} - protected fun getMaxKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} + protected fun getMaxKeyNodeRec(vertex: N? = root) : N? {TODO()} constructor(comparator: Comparator? = null) { this.comparator = comparator From c1a6f0ef06680fa604d43f40b99bb470c9fce76b Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 19 Mar 2024 17:02:59 +0300 Subject: [PATCH 021/227] fix: change AVLVertex constructor add sonsHeightDiff to the AVLVertex constructor --- lib/src/main/AVLVertex.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/src/main/AVLVertex.kt b/lib/src/main/AVLVertex.kt index 75c2162..763df33 100644 --- a/lib/src/main/AVLVertex.kt +++ b/lib/src/main/AVLVertex.kt @@ -11,8 +11,11 @@ class AVLVertex( key: K, value: V, leftSon: AVLVertex?, - rightSon: AVLVertex? + rightSon: AVLVertex?, + sonsHeightDiff : Int = 0 ) : this(key, value) { - this.leftSon = leftSon; this.rightSon = rightSon + this.leftSon = leftSon + this.rightSon = rightSon + this.sonsHeightDiff = sonsHeightDiff } } From 235c14bae95576e3bd52b40e8c58be7f9feb910d Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 19 Mar 2024 17:08:29 +0300 Subject: [PATCH 022/227] fix: add replaceIfExist param to AVLTree put() --- lib/src/main/AVLSearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/AVLSearchTree.kt b/lib/src/main/AVLSearchTree.kt index d74e393..2221256 100644 --- a/lib/src/main/AVLSearchTree.kt +++ b/lib/src/main/AVLSearchTree.kt @@ -1,6 +1,6 @@ class AVLSearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean ) {TODO()} override fun remove(key: K): V? {TODO()} From 7f6baf265323bce1c59c4f288d935789350cb9d3 Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 19 Mar 2024 21:14:29 +0300 Subject: [PATCH 023/227] add AVLTree rotateLeft() --- lib/src/main/AVLSearchTree.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/src/main/AVLSearchTree.kt b/lib/src/main/AVLSearchTree.kt index 2221256..d7e6dc7 100644 --- a/lib/src/main/AVLSearchTree.kt +++ b/lib/src/main/AVLSearchTree.kt @@ -4,6 +4,16 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun remove(key: K): V? {TODO()} + private fun rotateLeft(curVertex: AVLVertex) { + val rightSon : AVLVertex = (curVertex.rightSon as AVLVertex) + curVertex.rightSon = rightSon.leftSon + rightSon.leftSon = curVertex + when (rightSon.sonsHeightDiff){ + 0 -> rightSon.sonsHeightDiff = 1 + -1 -> {curVertex.sonsHeightDiff = 0; rightSon.sonsHeightDiff = 0} + } + } + constructor (comparator: Comparator? = null) : super(comparator) constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) From ed0ff252a33c479395d35b9715a414b9b58df02c Mon Sep 17 00:00:00 2001 From: = Date: Wed, 20 Mar 2024 00:30:09 +0300 Subject: [PATCH 024/227] feat: implement funs put and remove a little --- lib/src/main/RBSearchTree.kt | 113 +++++++++++++++++++++++++++++++++-- lib/src/main/RBVertex.kt | 2 +- 2 files changed, 110 insertions(+), 5 deletions(-) diff --git a/lib/src/main/RBSearchTree.kt b/lib/src/main/RBSearchTree.kt index 994c25a..4f12e8d 100644 --- a/lib/src/main/RBSearchTree.kt +++ b/lib/src/main/RBSearchTree.kt @@ -1,8 +1,113 @@ -class RBSearchTree : AbstractBinarySearchTree> { - - override fun put(key: K, value: V) {TODO()} +class RBSearchTree : AbstractBinarySearchTree> { - override fun remove(key: K): V? {TODO()} + override fun remove(key: K): V? { TODO() +// var currentVertex: RBVertex? = root +// var parent: RBVertex? = null +// var isLeft: Boolean = false +// val cpr = comparator +// +// while (currentVertex != null) { +// if (cpr != null) { +// +// if (cpr.compare(currentVertex.key, key) == 0) { +// if (countChildren(currentVertex) < 2){ +// parent?.key = currentVertex.key +// parent?.key = currentVertex.key +// parent?.key = currentVertex.key +// } +// break +// } +// +// parent = currentVertex +// if (cpr.compare(currentVertex.key, key) < 0){ +// currentVertex = currentVertex.rightSon +// isLeft = false +// } +// +// else if (cpr.compare(currentVertex.key, key) > 0){ +// currentVertex = currentVertex.leftSon +// isLeft = true +// } +// } else { +// +// val comparableKey = key as Comparable +// if (comparableKey.compareTo(currentVertex.key) == 0) { +// currentVertex.value = value +// break +// } +// +// parent = currentVertex +// if (comparableKey.compareTo(currentVertex.key) < 0){ +// currentVertex = currentVertex.rightSon +// isLeft = false +// } +// +// else if (comparableKey.compareTo(currentVertex.key) > 0){ +// currentVertex = currentVertex.leftSon +// isLeft = true +// } +// } +// } + } + + override fun put(key: K, value: V, replaceIfExists: Boolean) { + var currentVertex: RBVertex? = root + var parent: RBVertex? = null + var isLeft: Boolean = false + val cpr = comparator + + while (currentVertex != null) { + if (cpr != null) { + + if (cpr.compare(currentVertex.key, key) == 0) { + currentVertex.value = value + break + } + + parent = currentVertex + if (cpr.compare(currentVertex.key, key) < 0){ + currentVertex = currentVertex.rightSon + isLeft = false + } + + else if (cpr.compare(currentVertex.key, key) > 0){ + currentVertex = currentVertex.leftSon + isLeft = true + } + } else { + + val comparableKey = key as Comparable + if (comparableKey.compareTo(currentVertex.key) == 0) { + currentVertex.value = value + break + } + + parent = currentVertex + if (comparableKey.compareTo(currentVertex.key) < 0){ + currentVertex = currentVertex.rightSon + isLeft = false + } + + else if (comparableKey.compareTo(currentVertex.key) > 0){ + currentVertex = currentVertex.leftSon + isLeft = true + } + } + } + + if (currentVertex == null){ + currentVertex = RBVertex(key, value, null, null, true, parent) + if (isLeft) parent?.let { parent.leftSon = currentVertex } + else parent?.let { parent.rightSon = currentVertex } + } + } + + private fun countChildren(vertex: RBVertex): Int { + var numOfChild = 0 + if (vertex.leftSon != null) ++numOfChild + if (vertex.rightSon != null) ++numOfChild + return numOfChild + } constructor(comparator: Comparator? = null) : super(comparator) diff --git a/lib/src/main/RBVertex.kt b/lib/src/main/RBVertex.kt index a267e19..66200ff 100644 --- a/lib/src/main/RBVertex.kt +++ b/lib/src/main/RBVertex.kt @@ -3,7 +3,7 @@ class RBVertex( override var value: V ) : InterfaceBSTVertex> { - var isRed = false + var isRed = true var parent: RBVertex? = null override var leftSon: RBVertex? = null override var rightSon: RBVertex? = null From 223b75c5a89a08b7ba9b1074760e617ca178b3c3 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 20 Mar 2024 01:46:05 +0300 Subject: [PATCH 025/227] chore: sort the code files into thematic folders --- lib/src/main/iterator/TreeIterator.kt | 10 +++ lib/src/main/nodes/AVLVertex.kt | 19 +++++ lib/src/main/nodes/InterfaceBSTVertex.kt | 8 +++ lib/src/main/nodes/RBVertex.kt | 23 +++++++ lib/src/main/nodes/SimpleBSTVertex.kt | 18 +++++ lib/src/main/pair/Pair.kt | 2 + lib/src/main/trees/AVLSearchTree.kt | 13 ++++ .../main/trees/AbstractBinarySearchTree.kt | 69 +++++++++++++++++++ lib/src/main/trees/RBSearchTree.kt | 12 ++++ lib/src/main/trees/SimpleBinarySearchTree.kt | 12 ++++ 10 files changed, 186 insertions(+) create mode 100644 lib/src/main/iterator/TreeIterator.kt create mode 100644 lib/src/main/nodes/AVLVertex.kt create mode 100644 lib/src/main/nodes/InterfaceBSTVertex.kt create mode 100644 lib/src/main/nodes/RBVertex.kt create mode 100644 lib/src/main/nodes/SimpleBSTVertex.kt create mode 100644 lib/src/main/pair/Pair.kt create mode 100644 lib/src/main/trees/AVLSearchTree.kt create mode 100644 lib/src/main/trees/AbstractBinarySearchTree.kt create mode 100644 lib/src/main/trees/RBSearchTree.kt create mode 100644 lib/src/main/trees/SimpleBinarySearchTree.kt diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt new file mode 100644 index 0000000..7797f4a --- /dev/null +++ b/lib/src/main/iterator/TreeIterator.kt @@ -0,0 +1,10 @@ +package main.iterator +import nodes.InterfaceBSTVertex +import pair.Pair +internal class TreeIterator>( + vertex: InterfaceBSTVertex?): Iterator> { + + override fun hasNext(): Boolean {TODO()} + + override fun next(): Pair {TODO()} +} diff --git a/lib/src/main/nodes/AVLVertex.kt b/lib/src/main/nodes/AVLVertex.kt new file mode 100644 index 0000000..240de69 --- /dev/null +++ b/lib/src/main/nodes/AVLVertex.kt @@ -0,0 +1,19 @@ +package main.nodes +class AVLVertex( + override var key: K, + override var value: V +): InterfaceBSTVertex> { + + override var leftSon: AVLVertex? = null + override var rightSon: AVLVertex? = null + var sonsHeightDiff: Int = 0 + + constructor( + key: K, + value: V, + leftSon: AVLVertex?, + rightSon: AVLVertex? + ) : this(key, value) { + this.leftSon = leftSon; this.rightSon = rightSon + } +} diff --git a/lib/src/main/nodes/InterfaceBSTVertex.kt b/lib/src/main/nodes/InterfaceBSTVertex.kt new file mode 100644 index 0000000..fe990a8 --- /dev/null +++ b/lib/src/main/nodes/InterfaceBSTVertex.kt @@ -0,0 +1,8 @@ +package main.nodes +interface InterfaceBSTVertex { + + var key: K + var value: V + var leftSon: N? + var rightSon: N? +} diff --git a/lib/src/main/nodes/RBVertex.kt b/lib/src/main/nodes/RBVertex.kt new file mode 100644 index 0000000..d3115d2 --- /dev/null +++ b/lib/src/main/nodes/RBVertex.kt @@ -0,0 +1,23 @@ +package main.nodes +class RBVertex( + override var key: K, + override var value: V +) : InterfaceBSTVertex> { + + var isRed = false + var parent: RBVertex? = null + override var leftSon: RBVertex? = null + override var rightSon: RBVertex? = null + + constructor( + key: K, + value: V, + leftSon: RBVertex?, + rightSon: RBVertex?, + isRed: Boolean, + parent: RBVertex? + ) : this(key, value) { + this.leftSon = leftSon; this.rightSon = rightSon; this.parent = parent; this.isRed = isRed + } +} + diff --git a/lib/src/main/nodes/SimpleBSTVertex.kt b/lib/src/main/nodes/SimpleBSTVertex.kt new file mode 100644 index 0000000..dfd68a9 --- /dev/null +++ b/lib/src/main/nodes/SimpleBSTVertex.kt @@ -0,0 +1,18 @@ +package main.nodes +class SimpleBSTVertex( + override var key: K, + override var value: V +): InterfaceBSTVertex> { + + override var leftSon: SimpleBSTVertex? = null + override var rightSon: SimpleBSTVertex? = null + + constructor( + key: K, + value: V, + leftSon: SimpleBSTVertex?, + rightSon: SimpleBSTVertex? + ) : this(key, value) { + this.leftSon = leftSon; this.rightSon = rightSon + } +} diff --git a/lib/src/main/pair/Pair.kt b/lib/src/main/pair/Pair.kt new file mode 100644 index 0000000..c1b511f --- /dev/null +++ b/lib/src/main/pair/Pair.kt @@ -0,0 +1,2 @@ +package main.pair +class Pair(var key: K, var value: V) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt new file mode 100644 index 0000000..093d5ca --- /dev/null +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -0,0 +1,13 @@ +package main.trees +import nodes.AVLVertex + +class AVLSearchTree : AbstractBinarySearchTree> { + + override fun put(key: K, value: V) {TODO()} + + override fun remove(key: K): V? {TODO()} + + constructor (comparator: Comparator? = null) : super(comparator) + + constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) +} diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt new file mode 100644 index 0000000..d5e6437 --- /dev/null +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -0,0 +1,69 @@ +package main.trees +import nodes.InterfaceBSTVertex +import pair.Pair +abstract class AbstractBinarySearchTree> { + + protected var comparator: Comparator? = null + protected var size : Long = 0L + protected var root : InterfaceBSTVertex? = null + + operator fun iterator(): Iterator> {TODO()} + + fun size(): Long {return size} + + fun isEmpty(): Boolean {return size == 0L} + + fun get(key: K): V? {return getRec(key)} + + fun getPair(key: K): Pair? { + val value = get(key) + return if (value == null) null else Pair(key, value) + } + + fun getMin(): V? { + val minKeyNode = getMinKeyNodeRec() + return if (minKeyNode == null) null else minKeyNode.value + } + + fun getMax(): V?{ + val maxKeyNode = getMaxKeyNodeRec() + return if (maxKeyNode == null) null else maxKeyNode.value + } + + fun getMinKeyPair(): Pair? { + val minKeyNode = getMinKeyNodeRec() + return if (minKeyNode == null) null else Pair(minKeyNode.key, minKeyNode.value) + } + + fun getMaxKeyPair(): Pair? { + val maxKeyNode = getMaxKeyNodeRec() + return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) + } + + abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) +// возможно нужен комментарий + + fun putAll(map: Map) { + for (pair in map) put(pair.key, pair.value) + } + + abstract fun remove(key: K): V? + + fun removeAndReturnPair(key: K): Pair? { + val value = remove(key) + return if (value == null) null else Pair(key, value) + } + + protected fun getMinKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} + + protected fun getMaxKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} + + constructor(comparator: Comparator? = null) { + this.comparator = comparator + } + + constructor(map: Map, comparator: Comparator? = null) { + putAll(map) + this.comparator = comparator + } +} diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt new file mode 100644 index 0000000..deb406f --- /dev/null +++ b/lib/src/main/trees/RBSearchTree.kt @@ -0,0 +1,12 @@ +package main.trees +import nodes.RBVertex +class RBSearchTree : AbstractBinarySearchTree> { + + override fun put(key: K, value: V) {TODO()} + + override fun remove(key: K): V? {TODO()} + + constructor(comparator: Comparator? = null) : super(comparator) + + constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) +} diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt new file mode 100644 index 0000000..c3cbef4 --- /dev/null +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -0,0 +1,12 @@ +package main.trees +import nodes.SimpleBSTVertex +class SimpleBinarySearchTree : AbstractBinarySearchTree> { + + override fun put(key: K, value: V) {TODO()} + + override fun remove(key: K): V? {TODO()} + + constructor(comparator: Comparator?) : super(comparator) + + constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) +} From 9848b48f37c7e6b7dde7a18829fc521238b00be2 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 20 Mar 2024 01:56:33 +0300 Subject: [PATCH 026/227] style: add line breaks and implement changes in AbstractBinarySearchTree --- lib/src/main/iterator/TreeIterator.kt | 1 + lib/src/main/nodes/AVLVertex.kt | 1 + lib/src/main/nodes/RBVertex.kt | 1 + lib/src/main/nodes/SimpleBSTVertex.kt | 1 + lib/src/main/pair/Pair.kt | 1 + .../main/trees/AbstractBinarySearchTree.kt | 22 ++++++++++++++++--- lib/src/main/trees/RBSearchTree.kt | 3 ++- lib/src/main/trees/SimpleBinarySearchTree.kt | 3 ++- 8 files changed, 28 insertions(+), 5 deletions(-) diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt index 7797f4a..3178f10 100644 --- a/lib/src/main/iterator/TreeIterator.kt +++ b/lib/src/main/iterator/TreeIterator.kt @@ -1,6 +1,7 @@ package main.iterator import nodes.InterfaceBSTVertex import pair.Pair + internal class TreeIterator>( vertex: InterfaceBSTVertex?): Iterator> { diff --git a/lib/src/main/nodes/AVLVertex.kt b/lib/src/main/nodes/AVLVertex.kt index 240de69..733edbb 100644 --- a/lib/src/main/nodes/AVLVertex.kt +++ b/lib/src/main/nodes/AVLVertex.kt @@ -1,4 +1,5 @@ package main.nodes + class AVLVertex( override var key: K, override var value: V diff --git a/lib/src/main/nodes/RBVertex.kt b/lib/src/main/nodes/RBVertex.kt index d3115d2..118ae66 100644 --- a/lib/src/main/nodes/RBVertex.kt +++ b/lib/src/main/nodes/RBVertex.kt @@ -1,4 +1,5 @@ package main.nodes + class RBVertex( override var key: K, override var value: V diff --git a/lib/src/main/nodes/SimpleBSTVertex.kt b/lib/src/main/nodes/SimpleBSTVertex.kt index dfd68a9..f60adec 100644 --- a/lib/src/main/nodes/SimpleBSTVertex.kt +++ b/lib/src/main/nodes/SimpleBSTVertex.kt @@ -1,4 +1,5 @@ package main.nodes + class SimpleBSTVertex( override var key: K, override var value: V diff --git a/lib/src/main/pair/Pair.kt b/lib/src/main/pair/Pair.kt index c1b511f..3fe9580 100644 --- a/lib/src/main/pair/Pair.kt +++ b/lib/src/main/pair/Pair.kt @@ -1,2 +1,3 @@ package main.pair + class Pair(var key: K, var value: V) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index d5e6437..53700ca 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -1,11 +1,12 @@ package main.trees import nodes.InterfaceBSTVertex import pair.Pair + abstract class AbstractBinarySearchTree> { protected var comparator: Comparator? = null protected var size : Long = 0L - protected var root : InterfaceBSTVertex? = null + protected var root : N? = null operator fun iterator(): Iterator> {TODO()} @@ -54,9 +55,24 @@ abstract class AbstractBinarySearchTree> { return if (value == null) null else Pair(key, value) } - protected fun getMinKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} + private fun getRec(key: K, vertex: N? = root): V? { + if (vertex == null) return null + if (vertex.key == key) return vertex.value + val cpr = comparator + if (cpr != null) { + return if (cpr.compare(key, vertex.key) < 0) getRec(key, vertex.leftSon) + else getRec(key, vertex.rightSon) + } + else { + val comparableKey: Comparable = key as Comparable + return if (comparableKey.compareTo(vertex.key) < 0) getRec(key, vertex.leftSon) + else getRec(key, vertex.rightSon) + } + } + + protected fun getMinKeyNodeRec(vertex: N? = root) : N? {TODO()} - protected fun getMaxKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} + protected fun getMaxKeyNodeRec(vertex: N? = root) : N? {TODO()} constructor(comparator: Comparator? = null) { this.comparator = comparator diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index deb406f..0bf3057 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -1,7 +1,8 @@ package main.trees import nodes.RBVertex + class RBSearchTree : AbstractBinarySearchTree> { - + override fun put(key: K, value: V) {TODO()} override fun remove(key: K): V? {TODO()} diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index c3cbef4..dea84d2 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -1,5 +1,6 @@ package main.trees import nodes.SimpleBSTVertex + class SimpleBinarySearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V) {TODO()} @@ -7,6 +8,6 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree?) : super(comparator) - + constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) } From f123121ea22381778ffc76b51d55683d4a871455 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 20 Mar 2024 02:13:22 +0300 Subject: [PATCH 027/227] chore: delete extra files --- lib/src/main/AVLSearchTree.kt | 10 ---- lib/src/main/AVLVertex.kt | 18 ------- lib/src/main/AbstractBinarySearchTree.kt | 66 ------------------------ lib/src/main/InterfaceBSTVertex.kt | 7 --- lib/src/main/Pair.kt | 1 - lib/src/main/RBSearchTree.kt | 10 ---- lib/src/main/RBVertex.kt | 22 -------- lib/src/main/SimpleBSTVertex.kt | 17 ------ lib/src/main/SimpleBinarySearchTree.kt | 10 ---- lib/src/main/TreeIterator.kt | 7 --- 10 files changed, 168 deletions(-) delete mode 100644 lib/src/main/AVLSearchTree.kt delete mode 100644 lib/src/main/AVLVertex.kt delete mode 100644 lib/src/main/AbstractBinarySearchTree.kt delete mode 100644 lib/src/main/InterfaceBSTVertex.kt delete mode 100644 lib/src/main/Pair.kt delete mode 100644 lib/src/main/RBSearchTree.kt delete mode 100644 lib/src/main/RBVertex.kt delete mode 100644 lib/src/main/SimpleBSTVertex.kt delete mode 100644 lib/src/main/SimpleBinarySearchTree.kt delete mode 100644 lib/src/main/TreeIterator.kt diff --git a/lib/src/main/AVLSearchTree.kt b/lib/src/main/AVLSearchTree.kt deleted file mode 100644 index d74e393..0000000 --- a/lib/src/main/AVLSearchTree.kt +++ /dev/null @@ -1,10 +0,0 @@ -class AVLSearchTree : AbstractBinarySearchTree> { - - override fun put(key: K, value: V) {TODO()} - - override fun remove(key: K): V? {TODO()} - - constructor (comparator: Comparator? = null) : super(comparator) - - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) -} diff --git a/lib/src/main/AVLVertex.kt b/lib/src/main/AVLVertex.kt deleted file mode 100644 index 75c2162..0000000 --- a/lib/src/main/AVLVertex.kt +++ /dev/null @@ -1,18 +0,0 @@ -class AVLVertex( - override var key: K, - override var value: V -): InterfaceBSTVertex> { - - override var leftSon: AVLVertex? = null - override var rightSon: AVLVertex? = null - var sonsHeightDiff: Int = 0 - - constructor( - key: K, - value: V, - leftSon: AVLVertex?, - rightSon: AVLVertex? - ) : this(key, value) { - this.leftSon = leftSon; this.rightSon = rightSon - } -} diff --git a/lib/src/main/AbstractBinarySearchTree.kt b/lib/src/main/AbstractBinarySearchTree.kt deleted file mode 100644 index 0178e5e..0000000 --- a/lib/src/main/AbstractBinarySearchTree.kt +++ /dev/null @@ -1,66 +0,0 @@ -abstract class AbstractBinarySearchTree> { - - protected var comparator: Comparator? = null - protected var size : Long = 0L - protected var root : InterfaceBSTVertex? = null - - operator fun iterator(): Iterator> {TODO()} - - fun size(): Long {return size} - - fun isEmpty(): Boolean {return size == 0L} - - fun get(key: K): V? {return getRec(key)} - - fun getPair(key: K): Pair? { - val value = get(key) - return if (value == null) null else Pair(key, value) - } - - fun getMin(): V? { - val minKeyNode = getMinKeyNodeRec() - return if (minKeyNode == null) null else minKeyNode.value - } - - fun getMax(): V?{ - val maxKeyNode = getMaxKeyNodeRec() - return if (maxKeyNode == null) null else maxKeyNode.value - } - - fun getMinKeyPair(): Pair? { - val minKeyNode = getMinKeyNodeRec() - return if (minKeyNode == null) null else Pair(minKeyNode.key, minKeyNode.value) - } - - fun getMaxKeyPair(): Pair? { - val maxKeyNode = getMaxKeyNodeRec() - return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) - } - - abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) -// возможно нужен комментарий - - fun putAll(map: Map) { - for (pair in map) put(pair.key, pair.value) - } - - abstract fun remove(key: K): V? - - fun removeAndReturnPair(key: K): Pair? { - val value = remove(key) - return if (value == null) null else Pair(key, value) - } - - protected fun getMinKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} - - protected fun getMaxKeyNodeRec(vertex: InterfaceBSTVertex? = root) : InterfaceBSTVertex? {TODO()} - - constructor(comparator: Comparator? = null) { - this.comparator = comparator - } - - constructor(map: Map, comparator: Comparator? = null) { - putAll(map) - this.comparator = comparator - } -} diff --git a/lib/src/main/InterfaceBSTVertex.kt b/lib/src/main/InterfaceBSTVertex.kt deleted file mode 100644 index 703b199..0000000 --- a/lib/src/main/InterfaceBSTVertex.kt +++ /dev/null @@ -1,7 +0,0 @@ -interface InterfaceBSTVertex { - - var key: K - var value: V - var leftSon: N? - var rightSon: N? -} diff --git a/lib/src/main/Pair.kt b/lib/src/main/Pair.kt deleted file mode 100644 index 52b8b45..0000000 --- a/lib/src/main/Pair.kt +++ /dev/null @@ -1 +0,0 @@ -class Pair(var key: K, var value: V) diff --git a/lib/src/main/RBSearchTree.kt b/lib/src/main/RBSearchTree.kt deleted file mode 100644 index 994c25a..0000000 --- a/lib/src/main/RBSearchTree.kt +++ /dev/null @@ -1,10 +0,0 @@ -class RBSearchTree : AbstractBinarySearchTree> { - - override fun put(key: K, value: V) {TODO()} - - override fun remove(key: K): V? {TODO()} - - constructor(comparator: Comparator? = null) : super(comparator) - - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) -} diff --git a/lib/src/main/RBVertex.kt b/lib/src/main/RBVertex.kt deleted file mode 100644 index a267e19..0000000 --- a/lib/src/main/RBVertex.kt +++ /dev/null @@ -1,22 +0,0 @@ -class RBVertex( - override var key: K, - override var value: V -) : InterfaceBSTVertex> { - - var isRed = false - var parent: RBVertex? = null - override var leftSon: RBVertex? = null - override var rightSon: RBVertex? = null - - constructor( - key: K, - value: V, - leftSon: RBVertex?, - rightSon: RBVertex?, - isRed: Boolean, - parent: RBVertex? - ) : this(key, value) { - this.leftSon = leftSon; this.rightSon = rightSon; this.parent = parent; this.isRed = isRed - } -} - diff --git a/lib/src/main/SimpleBSTVertex.kt b/lib/src/main/SimpleBSTVertex.kt deleted file mode 100644 index 62583c6..0000000 --- a/lib/src/main/SimpleBSTVertex.kt +++ /dev/null @@ -1,17 +0,0 @@ -class SimpleBSTVertex( - override var key: K, - override var value: V -): InterfaceBSTVertex> { - - override var leftSon: SimpleBSTVertex? = null - override var rightSon: SimpleBSTVertex? = null - - constructor( - key: K, - value: V, - leftSon: SimpleBSTVertex?, - rightSon: SimpleBSTVertex? - ) : this(key, value) { - this.leftSon = leftSon; this.rightSon = rightSon - } -} diff --git a/lib/src/main/SimpleBinarySearchTree.kt b/lib/src/main/SimpleBinarySearchTree.kt deleted file mode 100644 index e04af09..0000000 --- a/lib/src/main/SimpleBinarySearchTree.kt +++ /dev/null @@ -1,10 +0,0 @@ -class SimpleBinarySearchTree : AbstractBinarySearchTree> { - - override fun put(key: K, value: V) {TODO()} - - override fun remove(key: K): V? {TODO()} - - constructor(comparator: Comparator?) : super(comparator) - - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) -} diff --git a/lib/src/main/TreeIterator.kt b/lib/src/main/TreeIterator.kt deleted file mode 100644 index 65a1f42..0000000 --- a/lib/src/main/TreeIterator.kt +++ /dev/null @@ -1,7 +0,0 @@ -internal class TreeIterator>( - vertex: InterfaceBSTVertex?): Iterator> { - - override fun hasNext(): Boolean {TODO()} - - override fun next(): Pair {TODO()} -} From 69ddb6ef897004b3893514cdc5c6b76f6d983d35 Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 20 Mar 2024 08:50:51 +0300 Subject: [PATCH 028/227] fix: add return to AVLTree rotateLeft() --- lib/src/main/trees/AVLSearchTree.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index c145c25..ae8ea9c 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -7,7 +7,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun remove(key: K): V? {TODO()} - private fun rotateLeft(curVertex: AVLVertex) { + private fun rotateLeft(curVertex: AVLVertex) : AVLVertex { val rightSon : AVLVertex = (curVertex.rightSon as AVLVertex) curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex @@ -15,8 +15,9 @@ class AVLSearchTree : AbstractBinarySearchTree> { 0 -> rightSon.sonsHeightDiff = 1 -1 -> {curVertex.sonsHeightDiff = 0; rightSon.sonsHeightDiff = 0} } + return(rightSon) } - + constructor (comparator: Comparator? = null) : super(comparator) constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) From 6ef3e063d78b7ca543c4983cf9352bcd8629eab6 Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 20 Mar 2024 08:53:31 +0300 Subject: [PATCH 029/227] feat: add AVLTree rotateRight() --- lib/src/main/trees/AVLSearchTree.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index ae8ea9c..961ee2c 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -11,13 +11,24 @@ class AVLSearchTree : AbstractBinarySearchTree> { val rightSon : AVLVertex = (curVertex.rightSon as AVLVertex) curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex - when (rightSon.sonsHeightDiff){ + when (rightSon.sonsHeightDiff) { 0 -> rightSon.sonsHeightDiff = 1 -1 -> {curVertex.sonsHeightDiff = 0; rightSon.sonsHeightDiff = 0} } - return(rightSon) + return rightSon } + private fun rotateRight(curVertex: AVLVertex) : AVLVertex { + val leftSon : AVLVertex = (curVertex.leftSon as AVLVertex) + curVertex.leftSon = leftSon.rightSon + leftSon.rightSon = curVertex + when (leftSon.sonsHeightDiff) { + 0 -> leftSon.sonsHeightDiff = 1 + -1 -> {curVertex.sonsHeightDiff = 0; leftSon.sonsHeightDiff = 0} + } + return leftSon + } + constructor (comparator: Comparator? = null) : super(comparator) constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) From aca70076c4d0ff7c1544cd49a3e0628dd1e37f93 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Wed, 20 Mar 2024 12:02:49 +0300 Subject: [PATCH 030/227] feat: add init block in TreeIterator class --- lib/src/main/iterator/TreeIterator.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt index 3178f10..3622362 100644 --- a/lib/src/main/iterator/TreeIterator.kt +++ b/lib/src/main/iterator/TreeIterator.kt @@ -1,9 +1,16 @@ package main.iterator -import nodes.InterfaceBSTVertex -import pair.Pair +import main.nodes.InterfaceBSTVertex +import main.pair.Pair +import java.util.LinkedList internal class TreeIterator>( - vertex: InterfaceBSTVertex?): Iterator> { + vertex: InterfaceBSTVertex? +): Iterator> { + private val stack = LinkedList() + + init { + vertex?.let { stack.add(it as N) } + } override fun hasNext(): Boolean {TODO()} From 746a01ab05fe063a4ccea60e6df3633204530a15 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Wed, 20 Mar 2024 12:04:00 +0300 Subject: [PATCH 031/227] feat: add TreeIterator's method hasNext() --- lib/src/main/iterator/TreeIterator.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt index 3622362..dedc8a1 100644 --- a/lib/src/main/iterator/TreeIterator.kt +++ b/lib/src/main/iterator/TreeIterator.kt @@ -12,7 +12,9 @@ internal class TreeIterator>( vertex?.let { stack.add(it as N) } } - override fun hasNext(): Boolean {TODO()} + override fun hasNext(): Boolean { + return stack.isNotEmpty() + } override fun next(): Pair {TODO()} } From 4a0d666fd5310c06df4aa94bdd368eabb9a3f93c Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Wed, 20 Mar 2024 12:04:48 +0300 Subject: [PATCH 032/227] feat: add TreeIterator's method next() --- lib/src/main/iterator/TreeIterator.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt index dedc8a1..31619cd 100644 --- a/lib/src/main/iterator/TreeIterator.kt +++ b/lib/src/main/iterator/TreeIterator.kt @@ -16,5 +16,10 @@ internal class TreeIterator>( return stack.isNotEmpty() } - override fun next(): Pair {TODO()} + override fun next(): Pair { + val nextVertex: N = stack.removeLast() + nextVertex.leftSon?.let { stack.add(it) } + nextVertex.rightSon?.let { stack.add(it) } + return Pair(nextVertex.key, nextVertex.value) + } } From 0951f005406718423d826467e7ac6ebc4a9601b9 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Wed, 20 Mar 2024 12:13:58 +0300 Subject: [PATCH 033/227] fix: change vertex type in primary constructor from InterfaceBSTVertex? to N? --- lib/src/main/iterator/TreeIterator.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt index 31619cd..7e2b39d 100644 --- a/lib/src/main/iterator/TreeIterator.kt +++ b/lib/src/main/iterator/TreeIterator.kt @@ -4,12 +4,12 @@ import main.pair.Pair import java.util.LinkedList internal class TreeIterator>( - vertex: InterfaceBSTVertex? + vertex: N? ): Iterator> { private val stack = LinkedList() init { - vertex?.let { stack.add(it as N) } + vertex?.let { stack.add(it) } } override fun hasNext(): Boolean { From 01753517a528320158e81946065eec658c9709a7 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Wed, 20 Mar 2024 12:18:50 +0300 Subject: [PATCH 034/227] feat: implement AbstractBinarySearchTree method iterator() and import TreeIterator class --- lib/src/main/trees/AbstractBinarySearchTree.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 53700ca..94b2be6 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -1,6 +1,7 @@ package main.trees import nodes.InterfaceBSTVertex import pair.Pair +import main.iterator.TreeIterator abstract class AbstractBinarySearchTree> { @@ -8,7 +9,9 @@ abstract class AbstractBinarySearchTree> { protected var size : Long = 0L protected var root : N? = null - operator fun iterator(): Iterator> {TODO()} + operator fun iterator(): Iterator> { + return TreeIterator(root) + } fun size(): Long {return size} From 49c3797841b40e5b4fe35a912727c5984a7231df Mon Sep 17 00:00:00 2001 From: Kostya Date: Wed, 20 Mar 2024 12:42:40 +0300 Subject: [PATCH 035/227] style: rename folder nodes to vertexes --- lib/src/main/iterator/TreeIterator.kt | 4 ++-- lib/src/main/trees/AVLSearchTree.kt | 4 ++-- lib/src/main/trees/AbstractBinarySearchTree.kt | 4 ++-- lib/src/main/trees/RBSearchTree.kt | 4 ++-- lib/src/main/trees/SimpleBinarySearchTree.kt | 4 ++-- lib/src/main/{nodes => vertexes}/AVLVertex.kt | 2 +- lib/src/main/{nodes => vertexes}/InterfaceBSTVertex.kt | 4 ++-- lib/src/main/{nodes => vertexes}/RBVertex.kt | 2 +- lib/src/main/{nodes => vertexes}/SimpleBSTVertex.kt | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) rename lib/src/main/{nodes => vertexes}/AVLVertex.kt (95%) rename lib/src/main/{nodes => vertexes}/InterfaceBSTVertex.kt (84%) rename lib/src/main/{nodes => vertexes}/RBVertex.kt (96%) rename lib/src/main/{nodes => vertexes}/SimpleBSTVertex.kt (95%) diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt index 3178f10..74e4f12 100644 --- a/lib/src/main/iterator/TreeIterator.kt +++ b/lib/src/main/iterator/TreeIterator.kt @@ -1,6 +1,6 @@ package main.iterator -import nodes.InterfaceBSTVertex -import pair.Pair +import main.vertexes.InterfaceBSTVertex +import main.pair.Pair internal class TreeIterator>( vertex: InterfaceBSTVertex?): Iterator> { diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 093d5ca..e6ebc12 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -1,9 +1,9 @@ package main.trees -import nodes.AVLVertex +import main.vertexes.AVLVertex class AVLSearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} override fun remove(key: K): V? {TODO()} diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 53700ca..5f9aa96 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -1,6 +1,6 @@ package main.trees -import nodes.InterfaceBSTVertex -import pair.Pair +import main.vertexes.InterfaceBSTVertex +import main.pair.Pair abstract class AbstractBinarySearchTree> { diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index 0bf3057..496f36d 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -1,9 +1,9 @@ package main.trees -import nodes.RBVertex +import main.vertexes.RBVertex class RBSearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} override fun remove(key: K): V? {TODO()} diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index dea84d2..9886147 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -1,9 +1,9 @@ package main.trees -import nodes.SimpleBSTVertex +import main.vertexes.SimpleBSTVertex class SimpleBinarySearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} override fun remove(key: K): V? {TODO()} diff --git a/lib/src/main/nodes/AVLVertex.kt b/lib/src/main/vertexes/AVLVertex.kt similarity index 95% rename from lib/src/main/nodes/AVLVertex.kt rename to lib/src/main/vertexes/AVLVertex.kt index 733edbb..c3a3819 100644 --- a/lib/src/main/nodes/AVLVertex.kt +++ b/lib/src/main/vertexes/AVLVertex.kt @@ -1,4 +1,4 @@ -package main.nodes +package main.vertexes class AVLVertex( override var key: K, diff --git a/lib/src/main/nodes/InterfaceBSTVertex.kt b/lib/src/main/vertexes/InterfaceBSTVertex.kt similarity index 84% rename from lib/src/main/nodes/InterfaceBSTVertex.kt rename to lib/src/main/vertexes/InterfaceBSTVertex.kt index fe990a8..2a657b1 100644 --- a/lib/src/main/nodes/InterfaceBSTVertex.kt +++ b/lib/src/main/vertexes/InterfaceBSTVertex.kt @@ -1,6 +1,6 @@ -package main.nodes -interface InterfaceBSTVertex { +package main.vertexes +interface InterfaceBSTVertex { var key: K var value: V var leftSon: N? diff --git a/lib/src/main/nodes/RBVertex.kt b/lib/src/main/vertexes/RBVertex.kt similarity index 96% rename from lib/src/main/nodes/RBVertex.kt rename to lib/src/main/vertexes/RBVertex.kt index 118ae66..f5dc211 100644 --- a/lib/src/main/nodes/RBVertex.kt +++ b/lib/src/main/vertexes/RBVertex.kt @@ -1,4 +1,4 @@ -package main.nodes +package main.vertexes class RBVertex( override var key: K, diff --git a/lib/src/main/nodes/SimpleBSTVertex.kt b/lib/src/main/vertexes/SimpleBSTVertex.kt similarity index 95% rename from lib/src/main/nodes/SimpleBSTVertex.kt rename to lib/src/main/vertexes/SimpleBSTVertex.kt index f60adec..2e76767 100644 --- a/lib/src/main/nodes/SimpleBSTVertex.kt +++ b/lib/src/main/vertexes/SimpleBSTVertex.kt @@ -1,4 +1,4 @@ -package main.nodes +package main.vertexes class SimpleBSTVertex( override var key: K, From 6c08841f6f2257f85d03f4d9912b96ac3800ffeb Mon Sep 17 00:00:00 2001 From: Kostya Date: Wed, 20 Mar 2024 13:25:40 +0300 Subject: [PATCH 036/227] feat: delete class pair --- lib/src/main/iterator/TreeIterator.kt | 1 - lib/src/main/pair/Pair.kt | 3 --- lib/src/main/trees/AbstractBinarySearchTree.kt | 1 - 3 files changed, 5 deletions(-) delete mode 100644 lib/src/main/pair/Pair.kt diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt index 74e4f12..5d659b4 100644 --- a/lib/src/main/iterator/TreeIterator.kt +++ b/lib/src/main/iterator/TreeIterator.kt @@ -1,6 +1,5 @@ package main.iterator import main.vertexes.InterfaceBSTVertex -import main.pair.Pair internal class TreeIterator>( vertex: InterfaceBSTVertex?): Iterator> { diff --git a/lib/src/main/pair/Pair.kt b/lib/src/main/pair/Pair.kt deleted file mode 100644 index 3fe9580..0000000 --- a/lib/src/main/pair/Pair.kt +++ /dev/null @@ -1,3 +0,0 @@ -package main.pair - -class Pair(var key: K, var value: V) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 5f9aa96..52a7117 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -1,6 +1,5 @@ package main.trees import main.vertexes.InterfaceBSTVertex -import main.pair.Pair abstract class AbstractBinarySearchTree> { From 035a038fbc3ecfa2f387ad4043fa3e4d03b603fa Mon Sep 17 00:00:00 2001 From: Kostya Date: Wed, 20 Mar 2024 21:29:04 +0300 Subject: [PATCH 037/227] feat: implement left and right rotates --- lib/src/main/trees/RBSearchTree.kt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index b04aea4..c1c79db 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -112,6 +112,32 @@ class RBSearchTree : AbstractBinarySearchTree> { return numOfChild } + //suppose that vertex has a rightSon + private fun rotateLeft(vertex: RBVertex) { + val rightVertex: RBVertex? = vertex.rightSon + vertex.rightSon = rightVertex?.leftSon + rightVertex?.leftSon.let { rightVertex?.leftSon?.parent = vertex } + rightVertex?.parent = vertex.parent + if (vertex.parent == null) root = rightVertex + else if (vertex == vertex.parent?.leftSon) vertex.parent?.leftSon = rightVertex + else vertex.parent?.rightSon = rightVertex + vertex.parent = rightVertex + rightVertex?.leftSon = vertex + } + + //suppose that vertex has a leftSon + private fun rotateRight(vertex: RBVertex) { + val leftVertex: RBVertex? = vertex.leftSon + vertex.leftSon = leftVertex?.rightSon + leftVertex?.rightSon.let { leftVertex?.rightSon?.parent = vertex} + leftVertex?.parent = vertex.parent + if (vertex.parent == null) root = leftVertex + else if (vertex == vertex.parent?.leftSon) vertex.parent?.leftSon = leftVertex + else vertex.parent?.rightSon = leftVertex + vertex.parent = leftVertex + leftVertex?.rightSon = vertex + } + constructor(comparator: Comparator? = null) : super(comparator) constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) From 32105d56f02e79a28e0f101184db03f5281cb5e0 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 12:22:25 +0300 Subject: [PATCH 038/227] feat: implement SimpleBinarySearchTree's private method putRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 61 +++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index dea84d2..2f63f32 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -1,9 +1,66 @@ package main.trees -import nodes.SimpleBSTVertex +import main.nodes.SimpleBSTVertex class SimpleBinarySearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} + + private fun putRec(key: K, value: V, replaceIfExists: Boolean, vertex: SimpleBSTVertex? = root) { + if (root == null) { + root = SimpleBSTVertex(key, value) + return + } + + val cpr = comparator + + if (cpr != null && vertex != null) { + if (vertex.key == key && replaceIfExists) { + vertex.value = value + return + } else if (vertex.key == key && !replaceIfExists) { + return + } + + if (cpr.compare(key, vertex.key) < 0) { + if (vertex.leftSon == null) { + vertex.leftSon = SimpleBSTVertex(key, value) + return + } + putRec(key, value, replaceIfExists, vertex.leftSon) + } + else { + if (vertex.rightSon == null) { + vertex.rightSon = SimpleBSTVertex(key, value) + return + } + putRec(key, value, replaceIfExists, vertex.rightSon) + } + } + else if (cpr == null && vertex != null) { + if (vertex.key == key && replaceIfExists) { + vertex.value = value + return + } else if (vertex.key == key && !replaceIfExists) { + return + } + + val comparableKey: Comparable = key as Comparable + if (comparableKey.compareTo(vertex.key) < 0) { + if (vertex.leftSon == null) { + vertex.leftSon = SimpleBSTVertex(key, value) + return + } + putRec(key, value, replaceIfExists, vertex.leftSon) + } + else { + if (vertex.rightSon == null) { + vertex.rightSon = SimpleBSTVertex(key, value) + return + } + putRec(key, value, replaceIfExists, vertex.rightSon) + } + } + } override fun remove(key: K): V? {TODO()} From 6ea1ee17f476ab4aa25bf5de3e5d2236d3cee161 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 12:22:54 +0300 Subject: [PATCH 039/227] feat: implement SimpleBinarySearchTree's method put() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 2f63f32..5e53cca 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -3,7 +3,9 @@ import main.nodes.SimpleBSTVertex class SimpleBinarySearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean) { + putRec(key, value, replaceIfExists) + } private fun putRec(key: K, value: V, replaceIfExists: Boolean, vertex: SimpleBSTVertex? = root) { if (root == null) { From 5f66f3d726c3d3c98fdb3876be29f98c09eb04ea Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 21 Mar 2024 12:34:55 +0300 Subject: [PATCH 040/227] feat: implement balance tree after put and add some changes in fun put --- lib/src/main/trees/RBSearchTree.kt | 170 +++++++++++++++-------------- lib/src/main/vertexes/RBVertex.kt | 1 - 2 files changed, 87 insertions(+), 84 deletions(-) diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index c1c79db..60caf50 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -3,98 +3,29 @@ import main.vertexes.RBVertex class RBSearchTree : AbstractBinarySearchTree> { - override fun remove(key: K): V? { TODO() -// var currentVertex: RBVertex? = root -// var parent: RBVertex? = null -// var isLeft: Boolean = false -// val cpr = comparator -// -// while (currentVertex != null) { -// if (cpr != null) { -// -// if (cpr.compare(currentVertex.key, key) == 0) { -// if (countChildren(currentVertex) < 2){ -// parent?.key = currentVertex.key -// parent?.key = currentVertex.key -// parent?.key = currentVertex.key -// } -// break -// } -// -// parent = currentVertex -// if (cpr.compare(currentVertex.key, key) < 0){ -// currentVertex = currentVertex.rightSon -// isLeft = false -// } -// -// else if (cpr.compare(currentVertex.key, key) > 0){ -// currentVertex = currentVertex.leftSon -// isLeft = true -// } -// } else { -// -// val comparableKey = key as Comparable -// if (comparableKey.compareTo(currentVertex.key) == 0) { -// currentVertex.value = value -// break -// } -// -// parent = currentVertex -// if (comparableKey.compareTo(currentVertex.key) < 0){ -// currentVertex = currentVertex.rightSon -// isLeft = false -// } -// -// else if (comparableKey.compareTo(currentVertex.key) > 0){ -// currentVertex = currentVertex.leftSon -// isLeft = true -// } -// } -// } - } + override fun remove(key: K): V? { TODO() } override fun put(key: K, value: V, replaceIfExists: Boolean) { var currentVertex: RBVertex? = root var parent: RBVertex? = null var isLeft: Boolean = false - val cpr = comparator while (currentVertex != null) { - if (cpr != null) { - - if (cpr.compare(currentVertex.key, key) == 0) { - currentVertex.value = value - break - } - - parent = currentVertex - if (cpr.compare(currentVertex.key, key) < 0){ - currentVertex = currentVertex.rightSon - isLeft = false - } - - else if (cpr.compare(currentVertex.key, key) > 0){ + when (compareKeys(comparator, key, currentVertex.key)){ + -1 -> { + parent = currentVertex currentVertex = currentVertex.leftSon isLeft = true } - } else { - - val comparableKey = key as Comparable - if (comparableKey.compareTo(currentVertex.key) == 0) { - currentVertex.value = value + 0 -> { + if (replaceIfExists) currentVertex.value = value break } - - parent = currentVertex - if (comparableKey.compareTo(currentVertex.key) < 0){ + 1 -> { + parent = currentVertex currentVertex = currentVertex.rightSon isLeft = false } - - else if (comparableKey.compareTo(currentVertex.key) > 0){ - currentVertex = currentVertex.leftSon - isLeft = true - } } } @@ -105,6 +36,61 @@ class RBSearchTree : AbstractBinarySearchTree> { } } + private fun balanceAfterPut(vertex: RBVertex) { + var currentVertex = vertex + + while (currentVertex.parent?.isRed == true){ + val grandparent = currentVertex.parent?.parent + + if (currentVertex.parent == grandparent?.leftSon){ + val uncle = grandparent?.rightSon + + if (uncle?.isRed == true){ + currentVertex.parent?.isRed = false + uncle.isRed = false + grandparent.isRed = true + currentVertex = grandparent + } + + else { + if (currentVertex == currentVertex.parent?.rightSon) { + currentVertex = currentVertex.parent ?: currentVertex + rotateLeft(currentVertex) + } + + currentVertex.parent?.isRed = false + currentVertex.parent?.parent?.isRed = true + val vertexForRightRotate = currentVertex.parent?.parent + vertexForRightRotate?.let { rotateRight(vertexForRightRotate) } + } + } + + else { + val uncle = grandparent?.leftSon + + if (uncle?.isRed == true){ + currentVertex.parent?.isRed = false + uncle.isRed = false + grandparent.isRed = true + currentVertex = grandparent + } + + else { + if (currentVertex == currentVertex.parent?.leftSon) { + currentVertex = currentVertex.parent ?: currentVertex + rotateRight(currentVertex) + } + + currentVertex.parent?.isRed = false + currentVertex.parent?.parent?.isRed = true + val vertexForLeftRotate = currentVertex.parent?.parent + vertexForLeftRotate?.let { rotateLeft(vertexForLeftRotate) } + } + } + } + root?.isRed = false + } + private fun countChildren(vertex: RBVertex): Int { var numOfChild = 0 if (vertex.leftSon != null) ++numOfChild @@ -118,9 +104,11 @@ class RBSearchTree : AbstractBinarySearchTree> { vertex.rightSon = rightVertex?.leftSon rightVertex?.leftSon.let { rightVertex?.leftSon?.parent = vertex } rightVertex?.parent = vertex.parent - if (vertex.parent == null) root = rightVertex - else if (vertex == vertex.parent?.leftSon) vertex.parent?.leftSon = rightVertex - else vertex.parent?.rightSon = rightVertex + when { + vertex.parent == null -> root = rightVertex + vertex == vertex.parent?.leftSon -> vertex.parent?.leftSon = rightVertex + else -> vertex.parent?.rightSon = rightVertex + } vertex.parent = rightVertex rightVertex?.leftSon = vertex } @@ -131,13 +119,29 @@ class RBSearchTree : AbstractBinarySearchTree> { vertex.leftSon = leftVertex?.rightSon leftVertex?.rightSon.let { leftVertex?.rightSon?.parent = vertex} leftVertex?.parent = vertex.parent - if (vertex.parent == null) root = leftVertex - else if (vertex == vertex.parent?.leftSon) vertex.parent?.leftSon = leftVertex - else vertex.parent?.rightSon = leftVertex + when { + vertex.parent == null -> root = leftVertex + vertex == vertex.parent?.leftSon -> vertex.parent?.leftSon = leftVertex + else -> vertex.parent?.rightSon = leftVertex + } vertex.parent = leftVertex leftVertex?.rightSon = vertex } + private fun compareKeys(cpr: Comparator?, firstKey: K, secondKey: K): Int{ + return if (cpr != null) { + if (cpr.compare(firstKey, secondKey) < 0) -1 + else if (cpr.compare(firstKey, secondKey) == 0) 0 + else 1 + } + else { + val comparableKey = firstKey as Comparable + if (comparableKey.compareTo(secondKey) < 0) -1 + else if (comparableKey.compareTo(secondKey) == 0) 0 + else 1 + } + } + constructor(comparator: Comparator? = null) : super(comparator) constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) diff --git a/lib/src/main/vertexes/RBVertex.kt b/lib/src/main/vertexes/RBVertex.kt index b1e1291..2f1d9b0 100644 --- a/lib/src/main/vertexes/RBVertex.kt +++ b/lib/src/main/vertexes/RBVertex.kt @@ -21,4 +21,3 @@ class RBVertex( this.leftSon = leftSon; this.rightSon = rightSon; this.parent = parent; this.isRed = isRed } } - From 16fbf36efc0cff0b9a87379c22ecbbe3ebe3bc60 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 12:59:22 +0300 Subject: [PATCH 041/227] feat: implement protected AbstractBinarySearchTree's method getMinKeyNodeRec() --- lib/src/main/trees/AbstractBinarySearchTree.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 94b2be6..d669ca7 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -73,7 +73,13 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMinKeyNodeRec(vertex: N? = root) : N? {TODO()} + protected fun getMinKeyNodeRec(vertex: N? = root) : N? { + if (vertex == null) return null + else { + return if (vertex.leftSon == null) vertex + else getMinKeyNodeRec(vertex.leftSon) + } + } protected fun getMaxKeyNodeRec(vertex: N? = root) : N? {TODO()} From 25d04efc6a61c194e111b377875b711d42e234fb Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 13:01:11 +0300 Subject: [PATCH 042/227] feat: implement protected AbstractBinarySearchTree's method getMaxKeyNodeRec() --- lib/src/main/trees/AbstractBinarySearchTree.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index d669ca7..8c950d1 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -81,7 +81,13 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMaxKeyNodeRec(vertex: N? = root) : N? {TODO()} + protected fun getMaxKeyNodeRec(vertex: N? = root) : N? { + if (vertex == null) return null + else { + return if (vertex.rightSon == null) vertex + else getMaxKeyNodeRec(vertex.rightSon) + } + } constructor(comparator: Comparator? = null) { this.comparator = comparator From 669c60119e6109f13b99d6bf1c4855e94876193e Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 13:13:25 +0300 Subject: [PATCH 043/227] feat: add the replaceIfExists parameter to the signature of putAll() method and to the constructor --- lib/src/main/trees/AbstractBinarySearchTree.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 8c950d1..a828f28 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -47,8 +47,8 @@ abstract class AbstractBinarySearchTree> { abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) // возможно нужен комментарий - fun putAll(map: Map) { - for (pair in map) put(pair.key, pair.value) + fun putAll(map: Map, replaceIfExists: Boolean = true) { + for (pair in map) put(pair.key, pair.value, replaceIfExists) } abstract fun remove(key: K): V? @@ -93,8 +93,8 @@ abstract class AbstractBinarySearchTree> { this.comparator = comparator } - constructor(map: Map, comparator: Comparator? = null) { - putAll(map) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) { + putAll(map, replaceIfExists) this.comparator = comparator } } From e9089316448fe60d90d0d0803792c1d9272b1d4d Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 14:27:14 +0300 Subject: [PATCH 044/227] fix: add replaceIfExists parameter to the constructors of AVLSearchTree, RBSearchTree and SimpleBinarySearchTree classes --- lib/src/main/trees/AVLSearchTree.kt | 2 +- lib/src/main/trees/RBSearchTree.kt | 2 +- lib/src/main/trees/SimpleBinarySearchTree.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index e6ebc12..80b54ce 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -9,5 +9,5 @@ class AVLSearchTree : AbstractBinarySearchTree> { constructor (comparator: Comparator? = null) : super(comparator) - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index 496f36d..2543155 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -9,5 +9,5 @@ class RBSearchTree : AbstractBinarySearchTree> { constructor(comparator: Comparator? = null) : super(comparator) - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 9886147..71259a0 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -9,5 +9,5 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree?) : super(comparator) - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } From e94adb7322dfc3afdb760c1014b80f8db3319c87 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 21 Mar 2024 14:52:39 +0300 Subject: [PATCH 045/227] fix: change sonsHeightDiff values fix sonsHeightDiff values in AVLTree rotateRight() --- lib/src/main/trees/AVLSearchTree.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 86da20a..8454ad5 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -23,11 +23,12 @@ class AVLSearchTree : AbstractBinarySearchTree> { curVertex.leftSon = leftSon.rightSon leftSon.rightSon = curVertex when (leftSon.sonsHeightDiff) { - 0 -> leftSon.sonsHeightDiff = 1 - -1 -> {curVertex.sonsHeightDiff = 0; leftSon.sonsHeightDiff = 0} + 0 -> leftSon.sonsHeightDiff = -1 + 1 -> {curVertex.sonsHeightDiff = 0; leftSon.sonsHeightDiff = 0} } return leftSon - } + } + constructor (comparator: Comparator? = null) : super(comparator) From 970bec44dbb87ed3c3ca99654215b51a4d0b42d9 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 21 Mar 2024 14:55:48 +0300 Subject: [PATCH 046/227] feat: add AVLTree bigRotateLeft() --- lib/src/main/trees/AVLSearchTree.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 8454ad5..1553cbb 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -29,6 +29,10 @@ class AVLSearchTree : AbstractBinarySearchTree> { return leftSon } + private fun bigRotateLeft(curVertex: AVLVertex) : AVLVertex { + curVertex.rightSon = rotateRight(curVertex.rightSon as AVLVertex) + return rotateLeft(curVertex) + } constructor (comparator: Comparator? = null) : super(comparator) From 6b8434b1ae114568e15a9f6bd6374e924e565445 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 21 Mar 2024 14:57:20 +0300 Subject: [PATCH 047/227] feat: add AVLTree bigRotateRight() --- lib/src/main/trees/AVLSearchTree.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 1553cbb..dce1352 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -28,12 +28,17 @@ class AVLSearchTree : AbstractBinarySearchTree> { } return leftSon } - + private fun bigRotateLeft(curVertex: AVLVertex) : AVLVertex { curVertex.rightSon = rotateRight(curVertex.rightSon as AVLVertex) return rotateLeft(curVertex) } + private fun bigRotateRight(curVertex: AVLVertex) : AVLVertex { + curVertex.leftSon = rotateLeft(curVertex.leftSon as AVLVertex) + return rotateRight(curVertex) + } + constructor (comparator: Comparator? = null) : super(comparator) constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) From 5cd53d33ce21e2da6bfeb36b0757f6eb10fb3f0f Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 18:16:27 +0300 Subject: [PATCH 048/227] refactor: simplified SimpleBinarySearchTree method putRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 57 +++++++------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 2e74787..3686e32 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -8,58 +8,37 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree? = root) { - if (root == null) { + if (vertex == null) { root = SimpleBSTVertex(key, value) return } val cpr = comparator + if (cpr != null) { + if (vertex.key == key && replaceIfExists) vertex.value = value + else if (vertex.key == key && !replaceIfExists) return - if (cpr != null && vertex != null) { - if (vertex.key == key && replaceIfExists) { - vertex.value = value - return - } else if (vertex.key == key && !replaceIfExists) { - return - } - - if (cpr.compare(key, vertex.key) < 0) { - if (vertex.leftSon == null) { - vertex.leftSon = SimpleBSTVertex(key, value) - return - } - putRec(key, value, replaceIfExists, vertex.leftSon) + else if (cpr.compare(key, vertex.key) < 0) { + if (vertex.leftSon == null) vertex.leftSon = SimpleBSTVertex(key, value) + else putRec(key, value, replaceIfExists, vertex.leftSon) } else { - if (vertex.rightSon == null) { - vertex.rightSon = SimpleBSTVertex(key, value) - return - } - putRec(key, value, replaceIfExists, vertex.rightSon) + if (vertex.rightSon == null) vertex.rightSon = SimpleBSTVertex(key, value) + else putRec(key, value, replaceIfExists, vertex.rightSon) } } - else if (cpr == null && vertex != null) { - if (vertex.key == key && replaceIfExists) { - vertex.value = value - return - } else if (vertex.key == key && !replaceIfExists) { - return - } - + else { val comparableKey: Comparable = key as Comparable - if (comparableKey.compareTo(vertex.key) < 0) { - if (vertex.leftSon == null) { - vertex.leftSon = SimpleBSTVertex(key, value) - return - } - putRec(key, value, replaceIfExists, vertex.leftSon) + if (vertex.key == key && replaceIfExists) vertex.value = value + else if (vertex.key == key && !replaceIfExists) return + + else if (comparableKey.compareTo(vertex.key) < 0) { + if (vertex.leftSon == null) vertex.leftSon = SimpleBSTVertex(key, value) + else putRec(key, value, replaceIfExists, vertex.leftSon) } else { - if (vertex.rightSon == null) { - vertex.rightSon = SimpleBSTVertex(key, value) - return - } - putRec(key, value, replaceIfExists, vertex.rightSon) + if (vertex.rightSon == null) vertex.rightSon = SimpleBSTVertex(key, value) + else putRec(key, value, replaceIfExists, vertex.rightSon) } } } From 251e689c65a0f45dc530569013ea7ab2c578f7d8 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 18:46:20 +0300 Subject: [PATCH 049/227] refactor: add default value for replaceIfExists parameter in primary constructor, edit condition for keys' equality in method putRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 3686e32..9c87011 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -7,7 +7,7 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree? = root) { + private fun putRec(key: K, value: V, replaceIfExists: Boolean = true, vertex: SimpleBSTVertex? = root) { if (vertex == null) { root = SimpleBSTVertex(key, value) return @@ -15,8 +15,8 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree : AbstractBinarySearchTree = key as Comparable - if (vertex.key == key && replaceIfExists) vertex.value = value - else if (vertex.key == key && !replaceIfExists) return + if (comparableKey.compareTo(vertex.key) == 0 && replaceIfExists) vertex.value = value + else if (comparableKey.compareTo(vertex.key) == 0 && !replaceIfExists) return else if (comparableKey.compareTo(vertex.key) < 0) { if (vertex.leftSon == null) vertex.leftSon = SimpleBSTVertex(key, value) From 308d49fa333a925b79eeb4ad418dd9f522421e3b Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 22 Mar 2024 08:08:13 +0300 Subject: [PATCH 050/227] fix: change AVLTree rotate funcs constructors --- lib/src/main/trees/AVLSearchTree.kt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index dce1352..0f181bc 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -7,8 +7,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun remove(key: K): V? {TODO()} - private fun rotateLeft(curVertex: AVLVertex) : AVLVertex { - val rightSon : AVLVertex = (curVertex.rightSon as AVLVertex) + private fun rotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex when (rightSon.sonsHeightDiff) { @@ -18,8 +17,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { return rightSon } - private fun rotateRight(curVertex: AVLVertex) : AVLVertex { - val leftSon : AVLVertex = (curVertex.leftSon as AVLVertex) + private fun rotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { curVertex.leftSon = leftSon.rightSon leftSon.rightSon = curVertex when (leftSon.sonsHeightDiff) { @@ -29,14 +27,16 @@ class AVLSearchTree : AbstractBinarySearchTree> { return leftSon } - private fun bigRotateLeft(curVertex: AVLVertex) : AVLVertex { - curVertex.rightSon = rotateRight(curVertex.rightSon as AVLVertex) - return rotateLeft(curVertex) + private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { + val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) + curVertex.rightSon = curRightSon + return rotateLeft(curVertex, curRightSon) } - private fun bigRotateRight(curVertex: AVLVertex) : AVLVertex { - curVertex.leftSon = rotateLeft(curVertex.leftSon as AVLVertex) - return rotateRight(curVertex) + private fun bigRotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { + val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) + curVertex.leftSon = curLeftSon + return rotateRight(curVertex, curLeftSon) } constructor (comparator: Comparator? = null) : super(comparator) From 03f2dd2222bb982d98226942cb5a90464a770322 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 22 Mar 2024 08:22:04 +0300 Subject: [PATCH 051/227] feat: add AVLTree balance() --- lib/src/main/trees/AVLSearchTree.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 0f181bc..e2a3f1c 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -7,6 +7,19 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun remove(key: K): V? {TODO()} + private fun balance(curVertex: AVLVertex) : AVLVertex{ + if(curVertex.sonsHeightDiff == -1) { + val rightSon = curVertex.rightSon as AVLVertex + return if (rightSon.sonsHeightDiff == 1) bigRotateLeft(curVertex, rightSon) + else rotateLeft(curVertex, rightSon) + } + else { + val leftSon = curVertex.leftSon as AVLVertex + return if (leftSon.sonsHeightDiff == -1) bigRotateRight(curVertex, leftSon) + else rotateRight(curVertex, leftSon) + } + } + private fun rotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex From a78b5f9c717d051a840a8e46bcb1c4eb5feeced7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 22 Mar 2024 10:02:34 +0300 Subject: [PATCH 052/227] feat: add AVLTree putRec() --- lib/src/main/trees/AVLSearchTree.kt | 64 ++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index e2a3f1c..0511e3f 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -4,9 +4,71 @@ import main.vertexes.AVLVertex class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} - + override fun remove(key: K): V? {TODO()} + private fun putRec + (key: K, value: V, replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { + fun putRecShort(vrtx : AVLVertex) : AVLVertex? { + return putRec(key, value, replaceIfExists, vrtx) + } + val nextCallReturned : AVLVertex? + when (compare(key, vertex.key)) { + -1 -> { + if (vertex.leftSon == null){ + vertex.leftSon = AVLVertex(key, value) + vertex.sonsHeightDiff++ + return vertex.leftSon + } + else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) + } + 0 -> { + if (replaceIfExists) { + vertex.key = key + vertex.value = value + } + return null + } + else -> { + if (vertex.rightSon == null) { + vertex.rightSon = AVLVertex(key, value) + vertex.sonsHeightDiff-- + return vertex.rightSon + } + else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) + } + } + if (nextCallReturned == null) return null + fun checkWhenLeftSubTreeChanged() : AVLVertex? { + if (nextCallReturned.sonsHeightDiff == 0) return null + if (vertex.sonsHeightDiff + 1 == 2) return balance(vertex) + vertex.sonsHeightDiff++ + return vertex + } + fun checkWhenRightSubTreeChanged() : AVLVertex? { + if (nextCallReturned.sonsHeightDiff == 0) return null + if (vertex.sonsHeightDiff - 1 == -2) return balance(vertex) + vertex.sonsHeightDiff-- + return vertex + } + when (nextCallReturned){ + vertex.leftSon -> return checkWhenLeftSubTreeChanged() + vertex.rightSon -> return checkWhenRightSubTreeChanged() + else -> { + when (compare(nextCallReturned.key, vertex.key)) { + -1 -> { + vertex.leftSon = nextCallReturned + return checkWhenLeftSubTreeChanged() + } + else -> { + vertex.rightSon = nextCallReturned + return checkWhenRightSubTreeChanged() + } + } + } + } + } + private fun balance(curVertex: AVLVertex) : AVLVertex{ if(curVertex.sonsHeightDiff == -1) { val rightSon = curVertex.rightSon as AVLVertex From e128fa98f9d8ef846042001d26f08447c160b7fa Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 22 Mar 2024 10:09:01 +0300 Subject: [PATCH 053/227] fix : add size enlargers in AVLTree putRec() --- lib/src/main/trees/AVLSearchTree.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 0511e3f..dda98b4 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -18,6 +18,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { if (vertex.leftSon == null){ vertex.leftSon = AVLVertex(key, value) vertex.sonsHeightDiff++ + size++ return vertex.leftSon } else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) @@ -33,6 +34,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { if (vertex.rightSon == null) { vertex.rightSon = AVLVertex(key, value) vertex.sonsHeightDiff-- + size++ return vertex.rightSon } else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) From 30c7c8ad44d1a06627bdcad6590074ec15676dcd Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 22 Mar 2024 10:13:36 +0300 Subject: [PATCH 054/227] fix: remove types after 'as' in some conctructors --- lib/src/main/trees/AVLSearchTree.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index dda98b4..21ad508 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -4,7 +4,7 @@ import main.vertexes.AVLVertex class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} - + override fun remove(key: K): V? {TODO()} private fun putRec @@ -21,7 +21,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex.leftSon } - else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) + else nextCallReturned = putRecShort(vertex.leftSon as) } 0 -> { if (replaceIfExists) { @@ -37,7 +37,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex.rightSon } - else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) + else nextCallReturned = putRecShort(vertex.leftSon as) } } if (nextCallReturned == null) return null @@ -105,13 +105,13 @@ class AVLSearchTree : AbstractBinarySearchTree> { } private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { - val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) + val curRightSon = rotateRight(rightSon, rightSon.leftSon as) curVertex.rightSon = curRightSon return rotateLeft(curVertex, curRightSon) } private fun bigRotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { - val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) + val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as) curVertex.leftSon = curLeftSon return rotateRight(curVertex, curLeftSon) } From 04add6ae6e86b774370b2aaff177a6415dbe4c5c Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Fri, 22 Mar 2024 11:25:43 +0300 Subject: [PATCH 055/227] feat: add partially written SimpleBinarySearchTree private method removeRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 9c87011..b73a032 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -45,6 +45,36 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree? = root): SimpleBSTVertex? { + if (vertex == null) return null + val cpr = comparator + if (cpr != null) { + if (cpr.compare(key, vertex.key) < 0) vertex.leftSon = removeRec(key, vertex.leftSon) + else if (cpr.compare(key, vertex.key) > 0) vertex.rightSon = removeRec(key, vertex.rightSon) + + else if (cpr.compare(key, vertex.key) == 0) { + if (vertex.leftSon == null || vertex.rightSon == null) { + vertex = if (vertex.leftSon == null) vertex.rightSon else vertex.leftSon +// vertex.key = vertexForSubstitution.key +// vertex.value = vertexForSubstitution.value +// vertex.leftSon = vertexForSubstitution.leftSon +// vertex.rightSon = vertexForSubstitution.rightSon + } + else if (vertex.leftSon != null && vertex.rightSon != null) { + val minKeyInRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) + vertex.key = minKeyInRightSubtreeNode.key + vertex.value = minKeyInRightSubtreeNode.value + vertex.rightSon = removeRec(minKeyInRightSubtreeNode.key, vertex.rightSon) + } + } + else error("this key isn't in this SimpleBinarySearchTree\n") + } + else { + TODO() + } + return vertex + } + constructor(comparator: Comparator?) : super(comparator) constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) From bd5273607a24d242c072a1692f4e5fc2b80be8a4 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 12:59:22 +0300 Subject: [PATCH 056/227] feat: implement protected AbstractBinarySearchTree's method getMinKeyNodeRec() --- lib/src/main/trees/AbstractBinarySearchTree.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 84b5e15..73b964a 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -72,7 +72,13 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMinKeyNodeRec(vertex: N? = root) : N? {TODO()} + protected fun getMinKeyNodeRec(vertex: N? = root) : N? { + if (vertex == null) return null + else { + return if (vertex.leftSon == null) vertex + else getMinKeyNodeRec(vertex.leftSon) + } + } protected fun getMaxKeyNodeRec(vertex: N? = root) : N? {TODO()} From e20ac1dc963111bf766039eaef2fc427260fa7f7 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 13:01:11 +0300 Subject: [PATCH 057/227] feat: implement protected AbstractBinarySearchTree's method getMaxKeyNodeRec() --- lib/src/main/trees/AbstractBinarySearchTree.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 73b964a..61a6b21 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -80,7 +80,13 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMaxKeyNodeRec(vertex: N? = root) : N? {TODO()} + protected fun getMaxKeyNodeRec(vertex: N? = root) : N? { + if (vertex == null) return null + else { + return if (vertex.rightSon == null) vertex + else getMaxKeyNodeRec(vertex.rightSon) + } + } constructor(comparator: Comparator? = null) { this.comparator = comparator From 1a3e45ae2cba5682b14c400f35ac16f31c1a37a8 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 13:13:25 +0300 Subject: [PATCH 058/227] feat: add the replaceIfExists parameter to the signature of putAll() method and to the constructor --- lib/src/main/trees/AbstractBinarySearchTree.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 61a6b21..2593a41 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -46,8 +46,8 @@ abstract class AbstractBinarySearchTree> { abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) // возможно нужен комментарий - fun putAll(map: Map) { - for (pair in map) put(pair.key, pair.value) + fun putAll(map: Map, replaceIfExists: Boolean = true) { + for (pair in map) put(pair.key, pair.value, replaceIfExists) } abstract fun remove(key: K): V? @@ -92,8 +92,8 @@ abstract class AbstractBinarySearchTree> { this.comparator = comparator } - constructor(map: Map, comparator: Comparator? = null) { - putAll(map) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) { + putAll(map, replaceIfExists) this.comparator = comparator } } From 636052e310d695f169cefa9f1076e3e2eb41ffa0 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Thu, 21 Mar 2024 14:27:14 +0300 Subject: [PATCH 059/227] fix: add replaceIfExists parameter to the constructors of AVLSearchTree, RBSearchTree and SimpleBinarySearchTree classes --- lib/src/main/trees/AVLSearchTree.kt | 2 +- lib/src/main/trees/RBSearchTree.kt | 2 +- lib/src/main/trees/SimpleBinarySearchTree.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index e6ebc12..80b54ce 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -9,5 +9,5 @@ class AVLSearchTree : AbstractBinarySearchTree> { constructor (comparator: Comparator? = null) : super(comparator) - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index 496f36d..2543155 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -9,5 +9,5 @@ class RBSearchTree : AbstractBinarySearchTree> { constructor(comparator: Comparator? = null) : super(comparator) - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 9886147..71259a0 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -9,5 +9,5 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree?) : super(comparator) - constructor(map: Map, comparator: Comparator? = null) : super(map, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } From be40aabf3da3c2bfebaa55b3130b479a2b63d24f Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 22 Mar 2024 14:07:31 +0300 Subject: [PATCH 060/227] feat: implement AVLTree put() --- lib/src/main/trees/AVLSearchTree.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 21ad508..f4863bc 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -3,7 +3,14 @@ import main.vertexes.AVLVertex class AVLSearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean) { + if (!isEmpty()) { + putRec(key, value, replaceIfExists, root as ) + return + } + root = AVLVertex(key, value) + size++ + } override fun remove(key: K): V? {TODO()} From c7efc86eb66b1567937a617cd1de9190619e9fe3 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 22 Mar 2024 21:19:59 +0300 Subject: [PATCH 061/227] feat: implement comparator fun --- lib/src/main/trees/AbstractBinarySearchTree.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 2593a41..62bafff 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -88,6 +88,20 @@ abstract class AbstractBinarySearchTree> { } } + private fun compareKeys(cpr: Comparator?, firstKey: K, secondKey: K): Int{ + return if (cpr != null) { + if (cpr.compare(firstKey, secondKey) < 0) -1 + else if (cpr.compare(firstKey, secondKey) == 0) 0 + else 1 + } + else { + val comparableKey = firstKey as Comparable + if (comparableKey.compareTo(secondKey) < 0) -1 + else if (comparableKey.compareTo(secondKey) == 0) 0 + else 1 + } + } + constructor(comparator: Comparator? = null) { this.comparator = comparator } From 40f9847e28d37c295a59c380861c1ee038b4458d Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 22 Mar 2024 22:43:11 +0300 Subject: [PATCH 062/227] fix: edit compareKeys() constructor; some style improvements --- .../main/trees/AbstractBinarySearchTree.kt | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 62bafff..72c4a31 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -88,17 +88,23 @@ abstract class AbstractBinarySearchTree> { } } - private fun compareKeys(cpr: Comparator?, firstKey: K, secondKey: K): Int{ + + private fun compareKeys(firstKey: K, secondKey: K): Int{ + val cpr = comparator return if (cpr != null) { - if (cpr.compare(firstKey, secondKey) < 0) -1 - else if (cpr.compare(firstKey, secondKey) == 0) 0 - else 1 + when (cpr.compare(firstKey, secondKey)) { + < 0 -> -1 + 0 -> 0 + else -> 1 } + } else { val comparableKey = firstKey as Comparable - if (comparableKey.compareTo(secondKey) < 0) -1 - else if (comparableKey.compareTo(secondKey) == 0) 0 - else 1 + when (comparableKey.compareTo(secondKey)) { + < 0 -> -1 + 0 -> 0 + else -> 1 + } } } From 15af7dd13ccba304187497f7d375c6b9c21c11fb Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 22 Mar 2024 21:19:59 +0300 Subject: [PATCH 063/227] feat: implement comparator fun --- lib/src/main/trees/AbstractBinarySearchTree.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 2593a41..62bafff 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -88,6 +88,20 @@ abstract class AbstractBinarySearchTree> { } } + private fun compareKeys(cpr: Comparator?, firstKey: K, secondKey: K): Int{ + return if (cpr != null) { + if (cpr.compare(firstKey, secondKey) < 0) -1 + else if (cpr.compare(firstKey, secondKey) == 0) 0 + else 1 + } + else { + val comparableKey = firstKey as Comparable + if (comparableKey.compareTo(secondKey) < 0) -1 + else if (comparableKey.compareTo(secondKey) == 0) 0 + else 1 + } + } + constructor(comparator: Comparator? = null) { this.comparator = comparator } From dc2ce55c2d02d588d1488deda290dac8830b7ac0 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 22 Mar 2024 22:43:11 +0300 Subject: [PATCH 064/227] fix: edit compareKeys() constructor; some style improvements --- .../main/trees/AbstractBinarySearchTree.kt | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 62bafff..72c4a31 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -88,17 +88,23 @@ abstract class AbstractBinarySearchTree> { } } - private fun compareKeys(cpr: Comparator?, firstKey: K, secondKey: K): Int{ + + private fun compareKeys(firstKey: K, secondKey: K): Int{ + val cpr = comparator return if (cpr != null) { - if (cpr.compare(firstKey, secondKey) < 0) -1 - else if (cpr.compare(firstKey, secondKey) == 0) 0 - else 1 + when (cpr.compare(firstKey, secondKey)) { + < 0 -> -1 + 0 -> 0 + else -> 1 } + } else { val comparableKey = firstKey as Comparable - if (comparableKey.compareTo(secondKey) < 0) -1 - else if (comparableKey.compareTo(secondKey) == 0) 0 - else 1 + when (comparableKey.compareTo(secondKey)) { + < 0 -> -1 + 0 -> 0 + else -> 1 + } } } From b50e2c77aca55c1ce6b82109e86bb01c52df53e9 Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Sat, 23 Mar 2024 12:51:11 +0300 Subject: [PATCH 065/227] fix: make protected AbstractTree compareKeys() --- lib/src/main/trees/AbstractBinarySearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 72c4a31..e5ac52b 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -89,7 +89,7 @@ abstract class AbstractBinarySearchTree> { } - private fun compareKeys(firstKey: K, secondKey: K): Int{ + protected fun compareKeys(firstKey: K, secondKey: K): Int{ val cpr = comparator return if (cpr != null) { when (cpr.compare(firstKey, secondKey)) { From 132dda434269aa7a4d36c7996dda2a9ffdbe64a3 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sat, 23 Mar 2024 13:59:45 +0300 Subject: [PATCH 066/227] feat: write SimpleBinarySearchTree private method removeRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 25 ++++++++------------ 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index b73a032..1e3ca31 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -53,24 +53,19 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree 0) vertex.rightSon = removeRec(key, vertex.rightSon) else if (cpr.compare(key, vertex.key) == 0) { - if (vertex.leftSon == null || vertex.rightSon == null) { - vertex = if (vertex.leftSon == null) vertex.rightSon else vertex.leftSon -// vertex.key = vertexForSubstitution.key -// vertex.value = vertexForSubstitution.value -// vertex.leftSon = vertexForSubstitution.leftSon -// vertex.rightSon = vertexForSubstitution.rightSon - } - else if (vertex.leftSon != null && vertex.rightSon != null) { - val minKeyInRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) - vertex.key = minKeyInRightSubtreeNode.key - vertex.value = minKeyInRightSubtreeNode.value - vertex.rightSon = removeRec(minKeyInRightSubtreeNode.key, vertex.rightSon) - } + if (vertex.leftSon == null || vertex.rightSon == null) return if (vertex.leftSon == null) vertex.rightSon else vertex.leftSon + else if (vertex.leftSon != null && vertex.rightSon != null) return getMinKeyNodeRec(vertex.rightSon) } - else error("this key isn't in this SimpleBinarySearchTree\n") } else { - TODO() + val comparableKey = key as Comparable + if (comparableKey.compareTo(vertex.key) < 0) vertex.leftSon = removeRec(key, vertex.leftSon) + else if (comparableKey.compareTo(vertex.key) > 0) vertex.rightSon = removeRec(key, vertex.rightSon) + + else if (comparableKey.compareTo(vertex.key) == 0) { + if (vertex.leftSon == null || vertex.rightSon == null) return if (vertex.leftSon == null) vertex.rightSon else vertex.leftSon + else if (vertex.leftSon != null && vertex.rightSon != null) return getMinKeyNodeRec(vertex.rightSon) + } } return vertex } From 396d19ce6812adc40847ffccf7a0750e44bed7b3 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sat, 23 Mar 2024 14:00:47 +0300 Subject: [PATCH 067/227] feat: write SimpleBinarySearchTree method remove() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 1e3ca31..9f2c198 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -43,7 +43,12 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree? = root): SimpleBSTVertex? { if (vertex == null) return null From 4ab8d39d7c9e29449b66bad57885594ddee749d4 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sat, 23 Mar 2024 14:44:07 +0300 Subject: [PATCH 068/227] feat: implement fun remove --- lib/src/main/trees/RBSearchTree.kt | 57 +++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index 60caf50..a4e309c 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -3,7 +3,51 @@ import main.vertexes.RBVertex class RBSearchTree : AbstractBinarySearchTree> { - override fun remove(key: K): V? { TODO() } + override fun remove(key: K): V? { + val vertex: RBVertex = getVertex(key) ?: return null + val value = vertex.value + var isVertexRed = vertex.isRed + var child: RBVertex? = null + + if (countChildren(vertex) < 2){ + child = getChild(vertex) + replaceVertexBy(vertex, child) + } + + else{ + val vertexForSwap = getMinKeyNodeRec(vertex.rightSon) + vertexForSwap?.let{ + vertex.key = it.key + vertex.value = it.value + isVertexRed = it.isRed + child = getChild(it) + replaceVertexBy(it, child) + } + } + + if (!isVertexRed) balanceAfterRemove(child) + + return value + } + + private fun balanceAfterRemove(vertex: RBVertex?){ TODO() } + + private fun getVertex(key: K): RBVertex? { + var currentVertex: RBVertex? = root + + while (currentVertex?.key != key){ + if (currentVertex == null) return null + when (compareKeys(comparator, key, currentVertex.key)){ + -1 -> { + currentVertex = currentVertex.leftSon + } + 1 -> { + currentVertex = currentVertex.rightSon + } + } + } + return currentVertex + } override fun put(key: K, value: V, replaceIfExists: Boolean) { var currentVertex: RBVertex? = root @@ -34,6 +78,8 @@ class RBSearchTree : AbstractBinarySearchTree> { if (isLeft) parent?.let { parent.leftSon = currentVertex } else parent?.let { parent.rightSon = currentVertex } } + + balanceAfterPut(currentVertex) } private fun balanceAfterPut(vertex: RBVertex) { @@ -98,6 +144,15 @@ class RBSearchTree : AbstractBinarySearchTree> { return numOfChild } + private fun getChild(vertex: RBVertex) = if (vertex.leftSon != null) vertex.leftSon else vertex.rightSon + + private fun replaceVertexBy(oldVertex: RBVertex, newVertex: RBVertex?){ + if (root == oldVertex) root = newVertex + else if (oldVertex == oldVertex.parent?.leftSon) oldVertex.parent?.leftSon = newVertex + else oldVertex.parent?.rightSon = newVertex + newVertex?.parent = oldVertex.parent + } + //suppose that vertex has a rightSon private fun rotateLeft(vertex: RBVertex) { val rightVertex: RBVertex? = vertex.rightSon From fb3b78623418e5d79ff7745cdbda6875132f3a5e Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 23 Mar 2024 15:06:32 +0300 Subject: [PATCH 069/227] fix: return types after 'as' --- lib/src/main/trees/AVLSearchTree.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index f4863bc..78b7684 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -5,7 +5,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { if (!isEmpty()) { - putRec(key, value, replaceIfExists, root as ) + putRec(key, value, replaceIfExists, root as AVLVertex ) return } root = AVLVertex(key, value) @@ -28,7 +28,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex.leftSon } - else nextCallReturned = putRecShort(vertex.leftSon as) + else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) } 0 -> { if (replaceIfExists) { @@ -44,7 +44,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex.rightSon } - else nextCallReturned = putRecShort(vertex.leftSon as) + else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex ) } } if (nextCallReturned == null) return null @@ -112,13 +112,13 @@ class AVLSearchTree : AbstractBinarySearchTree> { } private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { - val curRightSon = rotateRight(rightSon, rightSon.leftSon as) + val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) curVertex.rightSon = curRightSon return rotateLeft(curVertex, curRightSon) } private fun bigRotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { - val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as) + val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) curVertex.leftSon = curLeftSon return rotateRight(curVertex, curLeftSon) } From c3b64adb07f385035aeb73a9012b6a0e62588bf8 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 23 Mar 2024 15:10:40 +0300 Subject: [PATCH 070/227] fix: some style improvements --- lib/src/main/trees/AVLSearchTree.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 78b7684..9e031e0 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -8,7 +8,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { putRec(key, value, replaceIfExists, root as AVLVertex ) return } - root = AVLVertex(key, value) + root = AVLVertex(key, value) size++ } @@ -23,7 +23,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { when (compare(key, vertex.key)) { -1 -> { if (vertex.leftSon == null){ - vertex.leftSon = AVLVertex(key, value) + vertex.leftSon = AVLVertex(key, value) vertex.sonsHeightDiff++ size++ return vertex.leftSon @@ -39,7 +39,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { } else -> { if (vertex.rightSon == null) { - vertex.rightSon = AVLVertex(key, value) + vertex.rightSon = AVLVertex(key, value) vertex.sonsHeightDiff-- size++ return vertex.rightSon From a2965f1764e5115e8fbac1fb605830a873fe98c5 Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Sat, 23 Mar 2024 13:21:10 +0300 Subject: [PATCH 071/227] fix: edit 'when' expressions in AbstractTree compareKeys() --- lib/src/main/trees/AbstractBinarySearchTree.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 38d27c0..b110b1e 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -92,7 +92,7 @@ abstract class AbstractBinarySearchTree> { val cpr = comparator return if (cpr != null) { when (cpr.compare(firstKey, secondKey)) { - < 0 -> -1 + in Int.MIN_VALUE .. -1 -> -1 0 -> 0 else -> 1 } @@ -100,7 +100,7 @@ abstract class AbstractBinarySearchTree> { else { val comparableKey = firstKey as Comparable when (comparableKey.compareTo(secondKey)) { - < 0 -> -1 + in Int.MIN_VALUE .. -1 -> -1 0 -> 0 else -> 1 } From 113f20680cd5cb9f922c4cac881ce522ed43d5c1 Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Sat, 23 Mar 2024 15:18:07 +0300 Subject: [PATCH 072/227] fix : some style improvements in AbstractTree compareKeys() --- lib/src/main/trees/AbstractBinarySearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index b110b1e..0442b29 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -95,8 +95,8 @@ abstract class AbstractBinarySearchTree> { in Int.MIN_VALUE .. -1 -> -1 0 -> 0 else -> 1 + } } - } else { val comparableKey = firstKey as Comparable when (comparableKey.compareTo(secondKey)) { From 19fdac4d56789018953cd6bf5254c0fd624539bd Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 23 Mar 2024 16:09:05 +0300 Subject: [PATCH 073/227] fix: add 'when root changed' case in AVLTree put() --- lib/src/main/trees/AVLSearchTree.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 9e031e0..59cd83f 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -5,7 +5,10 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { if (!isEmpty()) { - putRec(key, value, replaceIfExists, root as AVLVertex ) + when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { + null, root -> {} + else -> root = putRecReturned + } return } root = AVLVertex(key, value) From 6056cf94c3ea01308992f04b1afcebed941561cd Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 23 Mar 2024 16:10:54 +0300 Subject: [PATCH 074/227] fix: fix typo in putRecShort() call --- lib/src/main/trees/AVLSearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 59cd83f..8f754b2 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -47,7 +47,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex.rightSon } - else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex ) + else nextCallReturned = putRecShort(vertex.rightSon as AVLVertex ) } } if (nextCallReturned == null) return null From 22320a2dd38c58d54e65ae73809692f41a9f0afa Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Sat, 23 Mar 2024 16:15:44 +0300 Subject: [PATCH 075/227] fix: change some return values in AVLTree putRec() --- lib/src/main/trees/AVLSearchTree.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 8f754b2..9e2d2fa 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -29,7 +29,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { vertex.leftSon = AVLVertex(key, value) vertex.sonsHeightDiff++ size++ - return vertex.leftSon + return vertex } else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) } @@ -45,7 +45,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { vertex.rightSon = AVLVertex(key, value) vertex.sonsHeightDiff-- size++ - return vertex.rightSon + return vertex } else nextCallReturned = putRecShort(vertex.rightSon as AVLVertex ) } From ff4b9f628af52f372d22c319b4fbf48ec6a973a4 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 23 Mar 2024 16:45:46 +0300 Subject: [PATCH 076/227] fix: rewrite AbstractTree getRec() using compareKeys() --- lib/src/main/trees/AbstractBinarySearchTree.kt | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index cc04a82..e01abf6 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -59,16 +59,10 @@ abstract class AbstractBinarySearchTree> { private fun getRec(key: K, vertex: N? = root): V? { if (vertex == null) return null - if (vertex.key == key) return vertex.value - val cpr = comparator - if (cpr != null) { - return if (cpr.compare(key, vertex.key) < 0) getRec(key, vertex.leftSon) - else getRec(key, vertex.rightSon) - } - else { - val comparableKey: Comparable = key as Comparable - return if (comparableKey.compareTo(vertex.key) < 0) getRec(key, vertex.leftSon) - else getRec(key, vertex.rightSon) + return when (compareKeys(vertex.key, key)) { + 0 -> vertex.value + -1 -> getRec(key, vertex.leftSon) + else -> getRec(key, vertex.rightSon) } } From 7819d6a80ad82f25979ddf493198a54555470bc5 Mon Sep 17 00:00:00 2001 From: Kostya Oreshin <84198636+TerrMen@users.noreply.github.com> Date: Sat, 23 Mar 2024 18:13:09 +0300 Subject: [PATCH 077/227] fix: swap vertex.key and key --- lib/src/main/trees/AbstractBinarySearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index e01abf6..e52e0e6 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -59,7 +59,7 @@ abstract class AbstractBinarySearchTree> { private fun getRec(key: K, vertex: N? = root): V? { if (vertex == null) return null - return when (compareKeys(vertex.key, key)) { + return when (compareKeys(key, vertex.key)) { 0 -> vertex.value -1 -> getRec(key, vertex.leftSon) else -> getRec(key, vertex.rightSon) From e5fcd15829afce61c74e675dc969c92ac3fd763e Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 23 Mar 2024 18:47:49 +0300 Subject: [PATCH 078/227] fix: remove unnecessary 'else's in AVLTree putRec() --- lib/src/main/trees/AVLSearchTree.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 9e2d2fa..7d650a6 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -31,7 +31,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex } - else nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) + nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) } 0 -> { if (replaceIfExists) { @@ -47,7 +47,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex } - else nextCallReturned = putRecShort(vertex.rightSon as AVLVertex ) + nextCallReturned = putRecShort(vertex.rightSon as AVLVertex ) } } if (nextCallReturned == null) return null @@ -81,7 +81,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { } } - private fun balance(curVertex: AVLVertex) : AVLVertex{ + private fun balance(curVertex: AVLVertex) : AVLVertex { if(curVertex.sonsHeightDiff == -1) { val rightSon = curVertex.rightSon as AVLVertex return if (rightSon.sonsHeightDiff == 1) bigRotateLeft(curVertex, rightSon) From 5841eee9492294dbfec8c9888e781c68ab13aefe Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 11:03:59 +0300 Subject: [PATCH 079/227] fix: rename some local functions --- lib/src/main/trees/AVLSearchTree.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 7d650a6..d033fab 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -15,8 +15,6 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ } - override fun remove(key: K): V? {TODO()} - private fun putRec (key: K, value: V, replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { fun putRecShort(vrtx : AVLVertex) : AVLVertex? { @@ -51,35 +49,37 @@ class AVLSearchTree : AbstractBinarySearchTree> { } } if (nextCallReturned == null) return null - fun checkWhenLeftSubTreeChanged() : AVLVertex? { + fun doBalanceChoreWhenLeftSubTreeChanged() : AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null if (vertex.sonsHeightDiff + 1 == 2) return balance(vertex) vertex.sonsHeightDiff++ return vertex } - fun checkWhenRightSubTreeChanged() : AVLVertex? { + fun doBalanceChoreWhenRightSubTreeChanged() : AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null if (vertex.sonsHeightDiff - 1 == -2) return balance(vertex) vertex.sonsHeightDiff-- return vertex } when (nextCallReturned){ - vertex.leftSon -> return checkWhenLeftSubTreeChanged() - vertex.rightSon -> return checkWhenRightSubTreeChanged() + vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() + vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() else -> { when (compare(nextCallReturned.key, vertex.key)) { -1 -> { vertex.leftSon = nextCallReturned - return checkWhenLeftSubTreeChanged() + return doBalanceChoreWhenLeftSubTreeChanged() } else -> { vertex.rightSon = nextCallReturned - return checkWhenRightSubTreeChanged() + return doBalanceChoreWhenRightSubTreeChanged() } } } } } + + override fun remove(key: K): V? {TODO()} private fun balance(curVertex: AVLVertex) : AVLVertex { if(curVertex.sonsHeightDiff == -1) { From f5eb6fcbb7612b099d49593f96e62d9b1517baf7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 11:22:45 +0300 Subject: [PATCH 080/227] feat (AVLTree): add enum RemoveStage with comments --- lib/src/main/trees/AVLSearchTree.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index d033fab..3e474a9 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -81,6 +81,12 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun remove(key: K): V? {TODO()} + enum class RemoveStage {a, b, c, d} + // a - don't need tree changes anymore + // b - probably need some tree changes, but only related to balancing + // c - need to null due "Son" property of (if exists) the parent of removed vertex + b + // d - need to change (but not to null) due "Son" property ... + b + private fun balance(curVertex: AVLVertex) : AVLVertex { if(curVertex.sonsHeightDiff == -1) { val rightSon = curVertex.rightSon as AVLVertex From 07fd75066585e375a72265a630d9dca2f61d38dc Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 11:23:53 +0300 Subject: [PATCH 081/227] feat: add AVLTree replaceByLargestLower() --- lib/src/main/trees/AVLSearchTree.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 3e474a9..2a8f52a 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -87,6 +87,15 @@ class AVLSearchTree : AbstractBinarySearchTree> { // c - need to null due "Son" property of (if exists) the parent of removed vertex + b // d - need to change (but not to null) due "Son" property ... + b + private fun replaceByLargestLower(vertex : AVLVertex ) : AVLVertex? { + val substitute = getMaxKeyNodeRec(vertex.leftSon) + if (substitute == null) return null + remove(substitute.key) + substitute.leftSon = vertex.leftSon + substitute.rightSon = vertex.rightSon + return substitute + } + private fun balance(curVertex: AVLVertex) : AVLVertex { if(curVertex.sonsHeightDiff == -1) { val rightSon = curVertex.rightSon as AVLVertex From c168c22bbfe9aa8e1f4d76df71e94aef3bdc8886 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 12:51:00 +0300 Subject: [PATCH 082/227] fix (AVLTree): change RemoveStage values --- lib/src/main/trees/AVLSearchTree.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 2a8f52a..60e2c00 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -81,11 +81,10 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun remove(key: K): V? {TODO()} - enum class RemoveStage {a, b, c, d} + enum class RemoveStage {a, b, c} // a - don't need tree changes anymore - // b - probably need some tree changes, but only related to balancing + // b - probably need some tree changes, but not nulling // c - need to null due "Son" property of (if exists) the parent of removed vertex + b - // d - need to change (but not to null) due "Son" property ... + b private fun replaceByLargestLower(vertex : AVLVertex ) : AVLVertex? { val substitute = getMaxKeyNodeRec(vertex.leftSon) From 5dddd20e841e58a271e163e245b4eb7590b7cff5 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 13:11:36 +0300 Subject: [PATCH 083/227] fix: rename AVLTree replaceByLargestLower() to prepareLargestLowerToReplaceVertex() --- lib/src/main/trees/AVLSearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 60e2c00..26e6ae0 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -86,7 +86,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { // b - probably need some tree changes, but not nulling // c - need to null due "Son" property of (if exists) the parent of removed vertex + b - private fun replaceByLargestLower(vertex : AVLVertex ) : AVLVertex? { + private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex? { val substitute = getMaxKeyNodeRec(vertex.leftSon) if (substitute == null) return null remove(substitute.key) From 357bd49f1e4e967fc7c4183e687f0712fac9cb45 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 13:15:09 +0300 Subject: [PATCH 084/227] feat: add AVLTree removeRec() --- lib/src/main/trees/AVLSearchTree.kt | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 26e6ae0..796dd38 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -86,6 +86,84 @@ class AVLSearchTree : AbstractBinarySearchTree> { // b - probably need some tree changes, but not nulling // c - need to null due "Son" property of (if exists) the parent of removed vertex + b + private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { + val nextCallReturned : Triple ?, V?> + // Triple consists of: + // 1) remove stage + // 2) if RemoveStage == a : just a vertex (don't need it later) + // if RemoveStage == b : the root of the changed subtree + // if RemoveStage == c : the removed vertex + // 3) a value of the removed vertex (or null if key not exists) + when (compare(key, vertex.key)) { + -1 -> { + if (vertex.leftSon == null) return Triple(RemoveStage.a, vertex, null) + nextCallReturned = removeRec(key, vertex.leftSon as AVLVertex) + } + 1 -> { + if (vertex.rightSon == null) return Triple(RemoveStage.a, vertex, null) + nextCallReturned = removeRec(key, vertex.rightSon as AVLVertex) + } + else -> { + size-- + return when ((vertex.leftSon == null) to (vertex.rightSon == null)) { + true to true -> Triple(RemoveStage.c, vertex, vertex.value) + true to false -> Triple(RemoveStage.b, + vertex.rightSon as AVLVertex, vertex.value) + false to true -> Triple(RemoveStage.b, + vertex.leftSon as AVLVertex, vertex.value) + else -> Triple(RemoveStage.b, + prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) + } + } + } + fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { + if (nextCallReturned.component2().sonsHeightDiff in listOf(-1,1)) + return Triple(RemoveStage.a, vertex, nextCallReturned.third) + if (vertex.sonsHeightDiff - 1 == -2) + return Triple(RemoveStage.b, balance(vertex), nextCallReturned.third) + vertex.sonsHeightDiff-- + return Triple(RemoveStage.b, vertex, nextCallReturned.third) + } + fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { + if (nextCallReturned.component2().sonsHeightDiff in listOf(-1,1)) + return Triple(RemoveStage.a, vertex, nextCallReturned.third) + if (vertex.sonsHeightDiff + 1 == 2) + return Triple(RemoveStage.b, balance(vertex), nextCallReturned.third) + vertex.sonsHeightDiff++ + return Triple(RemoveStage.b, vertex, nextCallReturned.third) + } + when (nextCallReturned.component1()) { + RemoveStage.a -> return nextCallReturned + RemoveStage.b -> when (nextCallReturned.component2()) { + vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() + vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() + else -> + when (compare(nextCallReturned.component2().key, vertex.key)) { + -1 -> { + vertex.leftSon = nextCallReturned.component2() + return doBalanceChoreWhenLeftSubTreeChanged() + } + else -> { + vertex.rightSon = nextCallReturned.component2() + return doBalanceChoreWhenRightSubTreeChanged() + } + } + } + RemoveStage.c -> + when (compare(nextCallReturned.component2().key, vertex.key)) { + -1 -> { + vertex.leftSon = null + return doBalanceChoreWhenLeftSubTreeChanged() + } + else -> { + vertex.rightSon = null + return doBalanceChoreWhenRightSubTreeChanged() + } + } + + } + } + private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex? { val substitute = getMaxKeyNodeRec(vertex.leftSon) if (substitute == null) return null From 7fba4c2390ba0f98c1dbe31cd1fff8902b5dfc74 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 13:17:05 +0300 Subject: [PATCH 085/227] fix: switch one when to if in AVLTree putRec() --- lib/src/main/trees/AVLSearchTree.kt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 796dd38..43a2d7e 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -65,16 +65,12 @@ class AVLSearchTree : AbstractBinarySearchTree> { vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() else -> { - when (compare(nextCallReturned.key, vertex.key)) { - -1 -> { + if (compare(nextCallReturned.key, vertex.key) == -1) { vertex.leftSon = nextCallReturned return doBalanceChoreWhenLeftSubTreeChanged() - } - else -> { + } vertex.rightSon = nextCallReturned return doBalanceChoreWhenRightSubTreeChanged() - } - } } } } From 4eb81d5018b10ffa4e2c8f389bbb2832c9bfc29b Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 24 Mar 2024 13:21:06 +0300 Subject: [PATCH 086/227] feat: implement fun balanceAfterDelete --- lib/src/main/trees/RBSearchTree.kt | 95 ++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 17 deletions(-) diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index f98b1dc..b65fffa 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -30,14 +30,89 @@ class RBSearchTree : AbstractBinarySearchTree> { return value } - private fun balanceAfterRemove(vertex: RBVertex?){ TODO() } + private fun balanceAfterRemove(vertex: RBVertex?){ + var currentVertex = vertex + while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)){ + var brother: RBVertex? + if (currentVertex == currentVertex?.parent?.leftSon){ + brother = currentVertex?.parent?.rightSon + + if (brother?.isRed == true){ + brother.isRed = false + currentVertex?.parent?.isRed = true + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateLeft(vertexForRotate) } + brother = currentVertex?.parent?.rightSon + } + + if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && + (brother?.rightSon?.isRed == false || brother?.rightSon == null)){ + brother?.isRed = true + currentVertex = currentVertex?.parent + } + + else{ + if (brother.rightSon?.isRed == false || brother.rightSon == null){ + brother.leftSon?.isRed = false + brother.isRed = true + rotateRight(brother) + brother = currentVertex?.parent?.rightSon + } + + val parentColor = currentVertex?.parent?.isRed + parentColor?.let { brother?.isRed = parentColor } + currentVertex?.parent?.isRed = false + brother?.rightSon?.isRed = false + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateLeft(vertexForRotate) } + currentVertex = root + } + } + + else{ + brother = currentVertex?.parent?.leftSon + + if (brother?.isRed == true){ + brother.isRed = false + currentVertex?.parent?.isRed = true + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateRight(vertexForRotate) } + brother = currentVertex?.parent?.leftSon + } + + if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && + (brother?.rightSon?.isRed == false || brother?.rightSon == null)){ + brother?.isRed = true + currentVertex = currentVertex?.parent + } + + else{ + if (brother.leftSon?.isRed == false || brother.leftSon == null){ + brother.rightSon?.isRed = false + brother.isRed = true + rotateLeft(brother) + brother = currentVertex?.parent?.leftSon + } + + val parentColor = currentVertex?.parent?.isRed + parentColor?.let { brother?.isRed = parentColor } + currentVertex?.parent?.isRed = false + brother?.rightSon?.isRed = false + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateRight(vertexForRotate) } + currentVertex = root + } + } + } + currentVertex?.isRed = false + } private fun getVertex(key: K): RBVertex? { var currentVertex: RBVertex? = root while (currentVertex?.key != key){ if (currentVertex == null) return null - when (compareKeys(comparator, key, currentVertex.key)){ + when (compareKeys(key, currentVertex.key)){ -1 -> { currentVertex = currentVertex.leftSon } @@ -55,7 +130,7 @@ class RBSearchTree : AbstractBinarySearchTree> { var isLeft: Boolean = false while (currentVertex != null) { - when (compareKeys(comparator, key, currentVertex.key)){ + when (compareKeys(key, currentVertex.key)){ -1 -> { parent = currentVertex currentVertex = currentVertex.leftSon @@ -183,20 +258,6 @@ class RBSearchTree : AbstractBinarySearchTree> { leftVertex?.rightSon = vertex } - private fun compareKeys(cpr: Comparator?, firstKey: K, secondKey: K): Int{ - return if (cpr != null) { - if (cpr.compare(firstKey, secondKey) < 0) -1 - else if (cpr.compare(firstKey, secondKey) == 0) 0 - else 1 - } - else { - val comparableKey = firstKey as Comparable - if (comparableKey.compareTo(secondKey) < 0) -1 - else if (comparableKey.compareTo(secondKey) == 0) 0 - else 1 - } - } - constructor(comparator: Comparator? = null) : super(comparator) constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) From 98a6416598b0bf206561749b378b94b4e5137f88 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 17:18:06 +0300 Subject: [PATCH 087/227] fix: rewrite AVLSearch balance() and rotate functions --- lib/src/main/trees/AVLSearchTree.kt | 85 +++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 43a2d7e..4846f05 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -15,8 +15,8 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ } - private fun putRec - (key: K, value: V, replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { + private fun putRec(key: K, value: V, + replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { fun putRecShort(vrtx : AVLVertex) : AVLVertex? { return putRec(key, value, replaceIfExists, vrtx) } @@ -104,16 +104,16 @@ class AVLSearchTree : AbstractBinarySearchTree> { return when ((vertex.leftSon == null) to (vertex.rightSon == null)) { true to true -> Triple(RemoveStage.c, vertex, vertex.value) true to false -> Triple(RemoveStage.b, - vertex.rightSon as AVLVertex, vertex.value) + vertex.rightSon as AVLVertex, vertex.value) false to true -> Triple(RemoveStage.b, - vertex.leftSon as AVLVertex, vertex.value) + vertex.leftSon as AVLVertex, vertex.value) else -> Triple(RemoveStage.b, - prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) + prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) } } } fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { - if (nextCallReturned.component2().sonsHeightDiff in listOf(-1,1)) + if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) return Triple(RemoveStage.a, vertex, nextCallReturned.third) if (vertex.sonsHeightDiff - 1 == -2) return Triple(RemoveStage.b, balance(vertex), nextCallReturned.third) @@ -121,7 +121,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { return Triple(RemoveStage.b, vertex, nextCallReturned.third) } fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { - if (nextCallReturned.component2().sonsHeightDiff in listOf(-1,1)) + if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) return Triple(RemoveStage.a, vertex, nextCallReturned.third) if (vertex.sonsHeightDiff + 1 == 2) return Triple(RemoveStage.b, balance(vertex), nextCallReturned.third) @@ -170,35 +170,74 @@ class AVLSearchTree : AbstractBinarySearchTree> { } private fun balance(curVertex: AVLVertex) : AVLVertex { + var (rightSon, leftSon) = List?>(2){null} + fun setTwoSonHeightDiffs(values : Pair) { + curVertex.sonsHeightDiff = values.component1() + if (rightSon != null){ + (rightSon as AVLVertex).sonsHeightDiff = values.component2() + return + } + (leftSon as AVLVertex).sonsHeightDiff = values.component1() + } + if(curVertex.sonsHeightDiff == -1) { - val rightSon = curVertex.rightSon as AVLVertex - return if (rightSon.sonsHeightDiff == 1) bigRotateLeft(curVertex, rightSon) - else rotateLeft(curVertex, rightSon) + rightSon = curVertex.rightSon as AVLVertex + return if (rightSon.sonsHeightDiff == 1) { + val rightSonSLeftSon = rightSon.leftSon as AVLVertex + var subtreeRoot = bigRotateLeft(curVertex, rightSon) + setTwoSonHeightDiffs( + when (rightSonSLeftSon.sonsHeightDiff) { + 1 -> 0 to -1 + -1 -> 1 to 0 + else -> 0 to 0 + } + ) + rightSonSLeftSon.sonsHeightDiff = 0 + subtreeRoot + } + else { + var subtreeRoot = rotateLeft(curVertex, rightSon) + setTwoSonHeightDiffs( + if (rightSon.sonsHeightDiff == 0) -1 to 1 + else 0 to 0 + ) + subtreeRoot + } + } - else { - val leftSon = curVertex.leftSon as AVLVertex - return if (leftSon.sonsHeightDiff == -1) bigRotateRight(curVertex, leftSon) - else rotateRight(curVertex, leftSon) - } + leftSon = curVertex.leftSon as AVLVertex + return if (leftSon.sonsHeightDiff == -1) { + val leftSonSRightSon = leftSon.rightSon as AVLVertex + var subtreeRoot = bigRotateRight(curVertex, leftSon) + setTwoSonHeightDiffs( + when (leftSonSRightSon.sonsHeightDiff) { + -1 -> 0 to 1 + 1 -> -1 to 0 + else -> 0 to 0 + } + ) + leftSonSRightSon.sonsHeightDiff = 0 + subtreeRoot + } + else { + var subtreeRoot = rotateRight(curVertex, leftSon) + setTwoSonHeightDiffs( + if (leftSon.sonsHeightDiff == 0) 1 to -1 + else 0 to 0 + ) + subtreeRoot + } } private fun rotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex - when (rightSon.sonsHeightDiff) { - 0 -> rightSon.sonsHeightDiff = 1 - -1 -> {curVertex.sonsHeightDiff = 0; rightSon.sonsHeightDiff = 0} - } return rightSon } private fun rotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { curVertex.leftSon = leftSon.rightSon leftSon.rightSon = curVertex - when (leftSon.sonsHeightDiff) { - 0 -> leftSon.sonsHeightDiff = -1 - 1 -> {curVertex.sonsHeightDiff = 0; leftSon.sonsHeightDiff = 0} - } return leftSon } From b395470f4ed10a1906c8aa5bacaa0d64e6a61add Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 19:05:09 +0300 Subject: [PATCH 088/227] fix: rename AVLTree RemoveStage to RemovalStage and change it's values writing --- lib/src/main/trees/AVLSearchTree.kt | 48 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 4846f05..e3690e2 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -77,60 +77,60 @@ class AVLSearchTree : AbstractBinarySearchTree> { override fun remove(key: K): V? {TODO()} - enum class RemoveStage {a, b, c} + enum class RemovalStage {A, B, C} // a - don't need tree changes anymore // b - probably need some tree changes, but not nulling // c - need to null due "Son" property of (if exists) the parent of removed vertex + b - private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { - val nextCallReturned : Triple ?, V?> + private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { + val nextCallReturned : Triple ?, V?> // Triple consists of: - // 1) remove stage - // 2) if RemoveStage == a : just a vertex (don't need it later) - // if RemoveStage == b : the root of the changed subtree - // if RemoveStage == c : the removed vertex + // 1) removal stage + // 2) if RemovalStage == a : just a vertex (don't need it later) + // if RemovalStage == b : the root of the changed subtree + // if RemovalStage == c : the removed vertex // 3) a value of the removed vertex (or null if key not exists) when (compare(key, vertex.key)) { -1 -> { - if (vertex.leftSon == null) return Triple(RemoveStage.a, vertex, null) + if (vertex.leftSon == null) return Triple(RemovalStage.A, vertex, null) nextCallReturned = removeRec(key, vertex.leftSon as AVLVertex) } 1 -> { - if (vertex.rightSon == null) return Triple(RemoveStage.a, vertex, null) + if (vertex.rightSon == null) return Triple(RemovalStage.A, vertex, null) nextCallReturned = removeRec(key, vertex.rightSon as AVLVertex) } else -> { size-- return when ((vertex.leftSon == null) to (vertex.rightSon == null)) { - true to true -> Triple(RemoveStage.c, vertex, vertex.value) - true to false -> Triple(RemoveStage.b, + true to true -> Triple(RemovalStage.C, vertex, vertex.value) + true to false -> Triple(RemovalStage.B, vertex.rightSon as AVLVertex, vertex.value) - false to true -> Triple(RemoveStage.b, + false to true -> Triple(RemovalStage.B, vertex.leftSon as AVLVertex, vertex.value) - else -> Triple(RemoveStage.b, + else -> Triple(RemovalStage.B, prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) } } } - fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { + fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) - return Triple(RemoveStage.a, vertex, nextCallReturned.third) + return Triple(RemovalStage.A, vertex, nextCallReturned.third) if (vertex.sonsHeightDiff - 1 == -2) - return Triple(RemoveStage.b, balance(vertex), nextCallReturned.third) + return Triple(RemovalStage.B, balance(vertex), nextCallReturned.third) vertex.sonsHeightDiff-- - return Triple(RemoveStage.b, vertex, nextCallReturned.third) + return Triple(RemovalStage.B, vertex, nextCallReturned.third) } - fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { + fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) - return Triple(RemoveStage.a, vertex, nextCallReturned.third) + return Triple(RemovalStage.A, vertex, nextCallReturned.third) if (vertex.sonsHeightDiff + 1 == 2) - return Triple(RemoveStage.b, balance(vertex), nextCallReturned.third) + return Triple(RemovalStage.B, balance(vertex), nextCallReturned.third) vertex.sonsHeightDiff++ - return Triple(RemoveStage.b, vertex, nextCallReturned.third) + return Triple(RemovalStage.B, vertex, nextCallReturned.third) } when (nextCallReturned.component1()) { - RemoveStage.a -> return nextCallReturned - RemoveStage.b -> when (nextCallReturned.component2()) { + RemovalStage.A -> return nextCallReturned + RemovalStage.B -> when (nextCallReturned.component2()) { vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() else -> @@ -145,7 +145,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { } } } - RemoveStage.c -> + RemovalStage.C -> when (compare(nextCallReturned.component2().key, vertex.key)) { -1 -> { vertex.leftSon = null From 6133e485b65315007cb6a25253ff43ec396be800 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 19:18:41 +0300 Subject: [PATCH 089/227] fix(AVLTree) : change some var keywords to val + style improvements --- lib/src/main/trees/AVLSearchTree.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index e3690e2..c0d94e4 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -114,19 +114,19 @@ class AVLSearchTree : AbstractBinarySearchTree> { } fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) - return Triple(RemovalStage.A, vertex, nextCallReturned.third) + return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) if (vertex.sonsHeightDiff - 1 == -2) - return Triple(RemovalStage.B, balance(vertex), nextCallReturned.third) + return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) vertex.sonsHeightDiff-- return Triple(RemovalStage.B, vertex, nextCallReturned.third) } fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) - return Triple(RemovalStage.A, vertex, nextCallReturned.third) + return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) if (vertex.sonsHeightDiff + 1 == 2) - return Triple(RemovalStage.B, balance(vertex), nextCallReturned.third) + return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) vertex.sonsHeightDiff++ - return Triple(RemovalStage.B, vertex, nextCallReturned.third) + return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) } when (nextCallReturned.component1()) { RemovalStage.A -> return nextCallReturned @@ -184,7 +184,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { rightSon = curVertex.rightSon as AVLVertex return if (rightSon.sonsHeightDiff == 1) { val rightSonSLeftSon = rightSon.leftSon as AVLVertex - var subtreeRoot = bigRotateLeft(curVertex, rightSon) + val subtreeRoot = bigRotateLeft(curVertex, rightSon) setTwoSonHeightDiffs( when (rightSonSLeftSon.sonsHeightDiff) { 1 -> 0 to -1 @@ -196,7 +196,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { subtreeRoot } else { - var subtreeRoot = rotateLeft(curVertex, rightSon) + val subtreeRoot = rotateLeft(curVertex, rightSon) setTwoSonHeightDiffs( if (rightSon.sonsHeightDiff == 0) -1 to 1 else 0 to 0 @@ -208,7 +208,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { leftSon = curVertex.leftSon as AVLVertex return if (leftSon.sonsHeightDiff == -1) { val leftSonSRightSon = leftSon.rightSon as AVLVertex - var subtreeRoot = bigRotateRight(curVertex, leftSon) + val subtreeRoot = bigRotateRight(curVertex, leftSon) setTwoSonHeightDiffs( when (leftSonSRightSon.sonsHeightDiff) { -1 -> 0 to 1 @@ -220,7 +220,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { subtreeRoot } else { - var subtreeRoot = rotateRight(curVertex, leftSon) + val subtreeRoot = rotateRight(curVertex, leftSon) setTwoSonHeightDiffs( if (leftSon.sonsHeightDiff == 0) 1 to -1 else 0 to 0 From 78c5d6df17cd8a91b5bea74680a292e6a7a0e558 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 19:46:50 +0300 Subject: [PATCH 090/227] fix (AVLTree) : change value of substitute.sonsHeightDiff in prepareLargestLowerToReplaceVertex() --- lib/src/main/trees/AVLSearchTree.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index c0d94e4..9ce81ce 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -166,6 +166,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { remove(substitute.key) substitute.leftSon = vertex.leftSon substitute.rightSon = vertex.rightSon + substitute.sonsHeightDiff = vertex.sonsHeightDiff return substitute } From 06ab766cd2a996ff8ad5d66b0b1a48ced23efc60 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 20:04:35 +0300 Subject: [PATCH 091/227] fix (AVLTree balance()): change calling for leftSon component in setTwoSonHeightDiffs() --- lib/src/main/trees/AVLSearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 9ce81ce..f74a256 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -178,7 +178,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { (rightSon as AVLVertex).sonsHeightDiff = values.component2() return } - (leftSon as AVLVertex).sonsHeightDiff = values.component1() + (leftSon as AVLVertex).sonsHeightDiff = values.component2() } if(curVertex.sonsHeightDiff == -1) { From 03675cd50c518f4b3b748ade894d86ae8032fa9b Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 20:27:00 +0300 Subject: [PATCH 092/227] fix: remove double size decrease in removeRec() --- lib/src/main/trees/AVLSearchTree.kt | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index f74a256..d0e524a 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -100,14 +100,20 @@ class AVLSearchTree : AbstractBinarySearchTree> { nextCallReturned = removeRec(key, vertex.rightSon as AVLVertex) } else -> { - size-- return when ((vertex.leftSon == null) to (vertex.rightSon == null)) { - true to true -> Triple(RemovalStage.C, vertex, vertex.value) - true to false -> Triple(RemovalStage.B, - vertex.rightSon as AVLVertex, vertex.value) - false to true -> Triple(RemovalStage.B, - vertex.leftSon as AVLVertex, vertex.value) - else -> Triple(RemovalStage.B, + true to true -> { + size-- + Triple(RemovalStage.C, vertex, vertex.value) + } + true to false -> { + size-- + Triple(RemovalStage.C, vertex.rightSon as AVLVertex, vertex.value) + } + false to true -> { + size-- + Triple(RemovalStage.C, vertex.leftSon as AVLVertex, vertex.value) + } + else -> Triple(RemovalStage.C, prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) } } From 559ea88d9310e4da6e4a7b0638b1dc55ad83c618 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 24 Mar 2024 20:31:18 +0300 Subject: [PATCH 093/227] feat : implement AVLTree remove() --- lib/src/main/trees/AVLSearchTree.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index d0e524a..2985667 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -75,7 +75,21 @@ class AVLSearchTree : AbstractBinarySearchTree> { } } - override fun remove(key: K): V? {TODO()} + override fun remove(key: K): V? { + if (!isEmpty()) { + val removeRecReturned = removeRec(key, root as AVLVertex) + when (removeRecReturned.first) { + RemovalStage.A -> {} + RemovalStage.B -> { + if (removeRecReturned.component2() != root) + root = removeRecReturned.component2() + } + RemovalStage.C -> root = null + } + return removeRecReturned.component3() + } + return null + } enum class RemovalStage {A, B, C} // a - don't need tree changes anymore From c74da98ea928462999595069848d7ad5e8f32391 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 24 Mar 2024 21:20:54 +0300 Subject: [PATCH 094/227] fix: rewrite in SimpleBinarySearchTree private method removeRec() case where deleted vertex has 2 sons --- lib/src/main/trees/SimpleBinarySearchTree.kt | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 10c227b..6e40a66 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -59,7 +59,14 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree : AbstractBinarySearchTree 0) vertex.rightSon = removeRec(key, vertex.rightSon) - else if (comparableKey.compareTo(vertex.key) == 0) { - if (vertex.leftSon == null || vertex.rightSon == null) return if (vertex.leftSon == null) vertex.rightSon else vertex.leftSon - else if (vertex.leftSon != null && vertex.rightSon != null) return getMinKeyNodeRec(vertex.rightSon) + else if (vertex.leftSon != null && vertex.rightSon != null) { + val minKeyRightSubtreeNode = getMinKeyNodeRec(vertex.rightSon) + if (minKeyRightSubtreeNode != null) { + vertex.key = minKeyRightSubtreeNode.key + vertex.value = minKeyRightSubtreeNode.value + removeRec(minKeyRightSubtreeNode.key, vertex.rightSon) + } } } return vertex From 2394f93bf6b02ae0b6a0a3b83f4728accc9aeec0 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 24 Mar 2024 21:50:19 +0300 Subject: [PATCH 095/227] refactor: rewrite SimpleBinarySearchTree private method removeRec() with using AbstractBinarySearchTree method compareKeys() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 41 +++++++------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 6e40a66..6dc4e6b 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -51,38 +51,23 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree? = root): SimpleBSTVertex? { - if (vertex == null) return null - val cpr = comparator - if (cpr != null) { - if (cpr.compare(key, vertex.key) < 0) vertex.leftSon = removeRec(key, vertex.leftSon) - else if (cpr.compare(key, vertex.key) > 0) vertex.rightSon = removeRec(key, vertex.rightSon) - - else if (cpr.compare(key, vertex.key) == 0) { - if (vertex.leftSon == null || vertex.rightSon == null) return if (vertex.leftSon == null) vertex.rightSon else vertex.leftSon - else if (vertex.leftSon != null && vertex.rightSon != null) { - val minKeyRightSubtreeNode = getMinKeyNodeRec(vertex.rightSon) - if (minKeyRightSubtreeNode != null) { - vertex.key = minKeyRightSubtreeNode.key - vertex.value = minKeyRightSubtreeNode.value - removeRec(minKeyRightSubtreeNode.key, vertex.rightSon) + if (vertex != null) { + when (compareKeys(key, vertex.key)) { + -1 -> vertex.leftSon = removeRec(key, vertex.leftSon) + 1 -> vertex.rightSon = removeRec(key, vertex.rightSon) + else -> { + if (vertex.leftSon == null || vertex.rightSon == null) return if (vertex.leftSon == null) vertex.rightSon else vertex.leftSon + else if (vertex.leftSon != null && vertex.rightSon != null) { + val minKeyRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) + minKeyRightSubtreeNode?.let { + vertex.key = it.key + vertex.value = it.value + removeRec(it.key, vertex.rightSon) + } } } } } - else { - val comparableKey = key as Comparable - if (comparableKey.compareTo(vertex.key) < 0) vertex.leftSon = removeRec(key, vertex.leftSon) - else if (comparableKey.compareTo(vertex.key) > 0) vertex.rightSon = removeRec(key, vertex.rightSon) - - else if (vertex.leftSon != null && vertex.rightSon != null) { - val minKeyRightSubtreeNode = getMinKeyNodeRec(vertex.rightSon) - if (minKeyRightSubtreeNode != null) { - vertex.key = minKeyRightSubtreeNode.key - vertex.value = minKeyRightSubtreeNode.value - removeRec(minKeyRightSubtreeNode.key, vertex.rightSon) - } - } - } return vertex } From 287b1a5a4119b95ab798dfd582faad6b0747462c Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Mon, 25 Mar 2024 08:41:28 +0300 Subject: [PATCH 096/227] fix: change init order in AbstractTree constructor --- lib/src/main/trees/AbstractBinarySearchTree.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index e52e0e6..d88c536 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -44,7 +44,6 @@ abstract class AbstractBinarySearchTree> { } abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) -// возможно нужен комментарий fun putAll(map: Map, replaceIfExists: Boolean = true) { for (pair in map) put(pair.key, pair.value, replaceIfExists) @@ -107,7 +106,7 @@ abstract class AbstractBinarySearchTree> { } constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) { - putAll(map, replaceIfExists) this.comparator = comparator + putAll(map, replaceIfExists) } } From 3a34901ee40d3743c5dc6ea6dd413d324031b062 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Tue, 26 Mar 2024 11:04:20 +0300 Subject: [PATCH 097/227] feat: add .gitignore --- .gitignore | 282 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d55f14 --- /dev/null +++ b/.gitignore @@ -0,0 +1,282 @@ +# Created by https://www.toptal.com/developers/gitignore/api/linux,windows,java,kotlin,gradle,intellij+all,intellij +# Edit at https://www.toptal.com/developers/gitignore?templates=linux,windows,java,kotlin,gradle,intellij+all,intellij + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +# Azure Toolkit for IntelliJ plugin +# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij +.idea/**/azureSettings.xml + +### Intellij+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# AWS User-specific + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# SonarLint plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +### Intellij+all Patch ### +# Ignore everything but code style settings and run configurations +# that are supposed to be shared within teams. + +.idea/* + +!.idea/codeStyles +!.idea/runConfigurations + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +### Kotlin ### +# Compiled class file + +# Log file + +# BlueJ files + +# Mobile Tools for Java (J2ME) + +# Package Files # + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Gradle ### +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Avoid ignore Gradle wrappper properties +!gradle-wrapper.properties + +# Cache of project +.gradletasknamecache + +# Eclipse Gradle plugin generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath + +### Gradle Patch ### +# Java heap dump +*.hprof + +# End of https://www.toptal.com/developers/gitignore/api/linux,windows,java,kotlin,gradle,intellij+all,intellij \ No newline at end of file From 3c8f1ed3fa64bb0c8c1f87a3028dcba59415d254 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Tue, 26 Mar 2024 12:18:17 +0300 Subject: [PATCH 098/227] refactor: rewritte so that value of removed vertex is returned from private SimpleBinarySerchTree method removeRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 23 +++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 6dc4e6b..5e8ae3d 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -50,25 +50,38 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree? = root): SimpleBSTVertex? { + private fun removeRec(key: K, vertex: SimpleBSTVertex? = root): Pair?, V?> { + var returnedVertexAndDeletedValue: Pair?, V?> = Pair(null, null) if (vertex != null) { when (compareKeys(key, vertex.key)) { - -1 -> vertex.leftSon = removeRec(key, vertex.leftSon) - 1 -> vertex.rightSon = removeRec(key, vertex.rightSon) + -1 -> { + returnedVertexAndDeletedValue = removeRec(key, vertex.leftSon) + vertex.leftSon = returnedVertexAndDeletedValue.first + } + 1 -> { + returnedVertexAndDeletedValue = removeRec(key, vertex.rightSon) + vertex.rightSon = returnedVertexAndDeletedValue.first + } else -> { - if (vertex.leftSon == null || vertex.rightSon == null) return if (vertex.leftSon == null) vertex.rightSon else vertex.leftSon + if (vertex.leftSon == null || vertex.rightSon == null) { + if (vertex.leftSon == null) return Pair(vertex.rightSon, vertex.value) + else return Pair(vertex.leftSon, vertex.value) + } else if (vertex.leftSon != null && vertex.rightSon != null) { + var returnValue: V? = null val minKeyRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) minKeyRightSubtreeNode?.let { + returnValue = vertex.value vertex.key = it.key vertex.value = it.value removeRec(it.key, vertex.rightSon) } + return Pair(vertex, returnValue) } } } } - return vertex + return Pair(vertex, returnedVertexAndDeletedValue.second) } constructor(comparator: Comparator?) : super(comparator) From 57088160ced91503330fe5a33c9b03745a5c8425 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Tue, 26 Mar 2024 12:21:13 +0300 Subject: [PATCH 099/227] fix: rewrite SimpleBinarySearchTree method remove() according to the return of method removeRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 5e8ae3d..3b9be62 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -44,10 +44,8 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree?, V?> = removeRec(key) + return returnedVertexAndDeletedValue.second } private fun removeRec(key: K, vertex: SimpleBSTVertex? = root): Pair?, V?> { From f166c5b8f842f2336c14d510269ab849bb941f5c Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Tue, 26 Mar 2024 12:40:57 +0300 Subject: [PATCH 100/227] refactor: rewrite SimpleBinarySearchTree private method putRec() with using AbstractBinarySearchTree method compareKeys() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 26 +++----------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 3b9be62..1873e85 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -12,31 +12,13 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree = key as Comparable - if (comparableKey.compareTo(vertex.key) == 0 && replaceIfExists) vertex.value = value - else if (comparableKey.compareTo(vertex.key) == 0 && !replaceIfExists) return - - else if (comparableKey.compareTo(vertex.key) < 0) { + when (compareKeys(key, vertex.key)) { + 0 -> if (replaceIfExists) vertex.value = value + -1 -> { if (vertex.leftSon == null) vertex.leftSon = SimpleBSTVertex(key, value) else putRec(key, value, replaceIfExists, vertex.leftSon) } - else { + 1 -> { if (vertex.rightSon == null) vertex.rightSon = SimpleBSTVertex(key, value) else putRec(key, value, replaceIfExists, vertex.rightSon) } From 29e2a4831a817391a3bacd5d55b4cd516eee7999 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 29 Mar 2024 20:43:36 +0300 Subject: [PATCH 101/227] chore: add explanatory comments --- lib/src/main/trees/RBSearchTree.kt | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index b65fffa..e9546a3 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -3,6 +3,19 @@ import main.vertexes.RBVertex class RBSearchTree : AbstractBinarySearchTree> { + //4 cases we need to look at + //1) remove red vertex with 0 children -> just remove vetrex + + //2) remove red or black vertex with 2 children -> + //find min vertex on the right subtree and swap it's key and value with + //key and value of vertex that we need to remove + //Now we can work with vertex which has 1 or 0 children + + //3) remove black vetrex with 1 child -> child can be only red + //so we just swap child's key and value with key and value that we need to remove + //and look at case 1) + + //4) remove black vertex with 0 children -> just remove vertex override fun remove(key: K): V? { val vertex: RBVertex = getVertex(key) ?: return null val value = vertex.value @@ -30,6 +43,24 @@ class RBSearchTree : AbstractBinarySearchTree> { return value } + //we need to balance tree after removal black vertex with 0 children + //in this fun we need to look at vertex's parent and brother + + //1) brother is black and brother's rightSon is red -> we paint + //brother in parent's color, parent and brother's rightSon in black + //then rotate left + + //2) brother is black and brother's leftSon is red (rightSon - black) -> + //we swap colors of brother and brother's leftSon and rotate right + //then look at case 1 + + //3) brother is black and both sons are black -> we make brother red + //then we need to launch algorithm from the parent because of it + //can be red, so we have red parent and red son or black so + //the black height of all subtree decreased + + //4) brother is red -> make brother black, parent red and + //rotate left. We move conflict on level below, then we look at the previous cases private fun balanceAfterRemove(vertex: RBVertex?){ var currentVertex = vertex while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)){ @@ -107,6 +138,8 @@ class RBSearchTree : AbstractBinarySearchTree> { currentVertex?.isRed = false } + //finds vertex by corresponding key + //if such vertex doesn't exist returns null private fun getVertex(key: K): RBVertex? { var currentVertex: RBVertex? = root @@ -124,6 +157,8 @@ class RBSearchTree : AbstractBinarySearchTree> { return currentVertex } + //finds free place and inserts newVertex, colors it in red + //if vertex with such key exists, replaces it override fun put(key: K, value: V, replaceIfExists: Boolean) { var currentVertex: RBVertex? = root var parent: RBVertex? = null @@ -157,6 +192,18 @@ class RBSearchTree : AbstractBinarySearchTree> { balanceAfterPut(currentVertex) } + //we need to balance tree in two cases + //1) when newVertex is root, so our root is red + //2) when parent of our newVertex is red(because newVertex is also red) + + //in first case we just make the root black + //in second case we need to look at the newVertex's uncle + + //if uncle is red, we make it black and newVertex's parent black and grandparent red + //launch algorithm to grandfather because now it's color changed to red + + //if uncle is black we also make newVertex's parent black, grandparent red + //and rotate it right private fun balanceAfterPut(vertex: RBVertex) { var currentVertex = vertex @@ -229,6 +276,7 @@ class RBSearchTree : AbstractBinarySearchTree> { } //suppose that vertex has a rightSon + //swap parent and rightSon, rightSon's leftSon becomes parent's rightSon private fun rotateLeft(vertex: RBVertex) { val rightVertex: RBVertex? = vertex.rightSon vertex.rightSon = rightVertex?.leftSon @@ -244,6 +292,7 @@ class RBSearchTree : AbstractBinarySearchTree> { } //suppose that vertex has a leftSon + //swap parent and leftSon, leftSon's rightSon becomes parent's leftSon private fun rotateRight(vertex: RBVertex) { val leftVertex: RBVertex? = vertex.leftSon vertex.leftSon = leftVertex?.rightSon From b20149698c89fc5d0cbf10df75cba171de2ad96b Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sat, 30 Mar 2024 14:50:17 +0300 Subject: [PATCH 102/227] refactor: add a vertex check for null and changed returns in SimpleBinarySearchTree private method removeRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 1873e85..5081691 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -31,37 +31,37 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree? = root): Pair?, V?> { - var returnedVertexAndDeletedValue: Pair?, V?> = Pair(null, null) - if (vertex != null) { - when (compareKeys(key, vertex.key)) { - -1 -> { - returnedVertexAndDeletedValue = removeRec(key, vertex.leftSon) - vertex.leftSon = returnedVertexAndDeletedValue.first - } - 1 -> { - returnedVertexAndDeletedValue = removeRec(key, vertex.rightSon) - vertex.rightSon = returnedVertexAndDeletedValue.first + if (vertex == null) return Pair(null, null) + + when (compareKeys(key, vertex.key)) { + -1 -> { + val (updateLeftSon, deletedValue) = removeRec(key, vertex.leftSon) + vertex.leftSon = updateLeftSon + return Pair(vertex, deletedValue) + } + 1 -> { + val (updateLeftSon, deletedValue) = removeRec(key, vertex.rightSon) + vertex.rightSon = updateLeftSon + return Pair(vertex, deletedValue) + } + else -> { + val deletedValue: V = vertex.value + if (vertex.leftSon == null || vertex.rightSon == null) { + if (vertex.leftSon == null) return Pair(vertex.rightSon, deletedValue) + else return Pair(vertex.leftSon, deletedValue) } - else -> { - if (vertex.leftSon == null || vertex.rightSon == null) { - if (vertex.leftSon == null) return Pair(vertex.rightSon, vertex.value) - else return Pair(vertex.leftSon, vertex.value) - } - else if (vertex.leftSon != null && vertex.rightSon != null) { - var returnValue: V? = null - val minKeyRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) - minKeyRightSubtreeNode?.let { - returnValue = vertex.value - vertex.key = it.key - vertex.value = it.value - removeRec(it.key, vertex.rightSon) - } - return Pair(vertex, returnValue) + else { + val minKeyRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) + minKeyRightSubtreeNode?.let { + vertex.key = it.key + vertex.value = it.value + val (updatedRightSon, _) = removeRec(it.key, vertex.rightSon) + vertex.rightSon = updatedRightSon } + return Pair(vertex, deletedValue) } } } - return Pair(vertex, returnedVertexAndDeletedValue.second) } constructor(comparator: Comparator?) : super(comparator) From a767151c6c3187145334f035242c8e43589e6c4c Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sat, 30 Mar 2024 15:04:43 +0300 Subject: [PATCH 103/227] refactor: add a root check for null in SimpleBinarySearchTree method put() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 5081691..ba362a3 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -4,14 +4,12 @@ import main.vertexes.SimpleBSTVertex class SimpleBinarySearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { + if (root == null) root = SimpleBSTVertex(key, value) putRec(key, value, replaceIfExists) } private fun putRec(key: K, value: V, replaceIfExists: Boolean = true, vertex: SimpleBSTVertex? = root) { - if (vertex == null) { - root = SimpleBSTVertex(key, value) - return - } + if (vertex == null) return when (compareKeys(key, vertex.key)) { 0 -> if (replaceIfExists) vertex.value = value -1 -> { From a8f2262dd8b097fed895a242e1ad905938cf2595 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 30 Mar 2024 12:55:01 +0300 Subject: [PATCH 104/227] fix (AVLTree): use compareKeys() name instead of compare() --- lib/src/main/trees/AVLSearchTree.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 0d5ec2f..c8d55db 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -21,7 +21,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { return putRec(key, value, replaceIfExists, vrtx) } val nextCallReturned : AVLVertex? - when (compare(key, vertex.key)) { + when (compareKeys(key, vertex.key)) { -1 -> { if (vertex.leftSon == null){ vertex.leftSon = AVLVertex(key, value) @@ -65,7 +65,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() else -> { - if (compare(nextCallReturned.key, vertex.key) == -1) { + if (compareKeys(nextCallReturned.key, vertex.key) == -1) { vertex.leftSon = nextCallReturned return doBalanceChoreWhenLeftSubTreeChanged() } @@ -104,7 +104,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { // if RemovalStage == b : the root of the changed subtree // if RemovalStage == c : the removed vertex // 3) a value of the removed vertex (or null if key not exists) - when (compare(key, vertex.key)) { + when (compareKeys(key, vertex.key)) { -1 -> { if (vertex.leftSon == null) return Triple(RemovalStage.A, vertex, null) nextCallReturned = removeRec(key, vertex.leftSon as AVLVertex) @@ -154,7 +154,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() else -> - when (compare(nextCallReturned.component2().key, vertex.key)) { + when (compareKeys(nextCallReturned.component2().key, vertex.key)) { -1 -> { vertex.leftSon = nextCallReturned.component2() return doBalanceChoreWhenLeftSubTreeChanged() @@ -166,7 +166,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { } } RemovalStage.C -> - when (compare(nextCallReturned.component2().key, vertex.key)) { + when (compareKeys(nextCallReturned.component2().key, vertex.key)) { -1 -> { vertex.leftSon = null return doBalanceChoreWhenLeftSubTreeChanged() From e8f3ee1bc8227e0e4324b1d1a5dd13508f53820b Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sat, 30 Mar 2024 16:22:23 +0300 Subject: [PATCH 105/227] fix: add tree size changing by changing return type to Triple?, V?, Boolean> in method removeRec() and rewriting method remove() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 38 ++++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index ba362a3..02c55bc 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -24,40 +24,39 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree?, V?> = removeRec(key) - return returnedVertexAndDeletedValue.second + val (_, deletedValue, isRemoved)= removeRec(key) + if (isRemoved) size-- + return deletedValue } - private fun removeRec(key: K, vertex: SimpleBSTVertex? = root): Pair?, V?> { - if (vertex == null) return Pair(null, null) + private fun removeRec(key: K, vertex: SimpleBSTVertex? = root): Triple?, V?, Boolean> { + if (vertex == null) return Triple(null, null, false) when (compareKeys(key, vertex.key)) { -1 -> { - val (updateLeftSon, deletedValue) = removeRec(key, vertex.leftSon) + val (updateLeftSon, deletedValue, isRemoved) = removeRec(key, vertex.leftSon) vertex.leftSon = updateLeftSon - return Pair(vertex, deletedValue) + return Triple(vertex, deletedValue, isRemoved) } 1 -> { - val (updateLeftSon, deletedValue) = removeRec(key, vertex.rightSon) + val (updateLeftSon, deletedValue, isRemoved) = removeRec(key, vertex.rightSon) vertex.rightSon = updateLeftSon - return Pair(vertex, deletedValue) + return Triple(vertex, deletedValue, isRemoved) } else -> { val deletedValue: V = vertex.value if (vertex.leftSon == null || vertex.rightSon == null) { - if (vertex.leftSon == null) return Pair(vertex.rightSon, deletedValue) - else return Pair(vertex.leftSon, deletedValue) + if (vertex.leftSon == null) return Triple(vertex.rightSon, deletedValue, true) + return Triple(vertex.leftSon, deletedValue, true) } - else { - val minKeyRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) - minKeyRightSubtreeNode?.let { - vertex.key = it.key - vertex.value = it.value - val (updatedRightSon, _) = removeRec(it.key, vertex.rightSon) - vertex.rightSon = updatedRightSon - } - return Pair(vertex, deletedValue) + val minKeyRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) + minKeyRightSubtreeNode?.let { + vertex.key = it.key + vertex.value = it.value + val (updatedRightSon, _, _) = removeRec(it.key, vertex.rightSon) + vertex.rightSon = updatedRightSon } + return Triple(vertex, deletedValue, true) } } } @@ -66,3 +65,4 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } + From dc190c8a5591ef53e54da29bfaac47b599e534f9 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sat, 30 Mar 2024 16:24:24 +0300 Subject: [PATCH 106/227] fix: add tree size changing in methods putRec() and put () --- lib/src/main/trees/SimpleBinarySearchTree.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 02c55bc..072aef6 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -4,7 +4,10 @@ import main.vertexes.SimpleBSTVertex class SimpleBinarySearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { - if (root == null) root = SimpleBSTVertex(key, value) + if (root == null) { + root = SimpleBSTVertex(key, value) + size++ + } putRec(key, value, replaceIfExists) } @@ -13,11 +16,17 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree if (replaceIfExists) vertex.value = value -1 -> { - if (vertex.leftSon == null) vertex.leftSon = SimpleBSTVertex(key, value) + if (vertex.leftSon == null) { + vertex.leftSon = SimpleBSTVertex(key, value) + size++ + } else putRec(key, value, replaceIfExists, vertex.leftSon) } 1 -> { - if (vertex.rightSon == null) vertex.rightSon = SimpleBSTVertex(key, value) + if (vertex.rightSon == null) { + vertex.rightSon = SimpleBSTVertex(key, value) + size++ + } else putRec(key, value, replaceIfExists, vertex.rightSon) } } From 6f14874594516b82c6811761d206f5daca4e67f3 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sat, 30 Mar 2024 16:28:58 +0300 Subject: [PATCH 107/227] fix: correct typos in the names of variables deletedValue and updatedRightSon in method removeRec() --- lib/src/main/trees/SimpleBinarySearchTree.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 072aef6..ef139a7 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -33,7 +33,7 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree : AbstractBinarySearchTree { - val (updateLeftSon, deletedValue, isRemoved) = removeRec(key, vertex.leftSon) - vertex.leftSon = updateLeftSon + val (updatedLeftSon, deletedValue, isRemoved) = removeRec(key, vertex.leftSon) + vertex.leftSon = updatedLeftSon return Triple(vertex, deletedValue, isRemoved) } 1 -> { - val (updateLeftSon, deletedValue, isRemoved) = removeRec(key, vertex.rightSon) - vertex.rightSon = updateLeftSon + val (updatedRightSon, deletedValue, isRemoved) = removeRec(key, vertex.rightSon) + vertex.rightSon = updatedRightSon return Triple(vertex, deletedValue, isRemoved) } else -> { @@ -74,4 +74,3 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } - From 360ac0ada7c15221432d79409d47cb39c6969781 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 30 Mar 2024 15:52:31 +0300 Subject: [PATCH 108/227] chore: add test directory; add kotlin directories in main and test --- lib/src/main/{ => kotlin}/iterator/TreeIterator.kt | 0 lib/src/main/{ => kotlin}/trees/AVLSearchTree.kt | 0 lib/src/main/{ => kotlin}/trees/AbstractBinarySearchTree.kt | 0 lib/src/main/{ => kotlin}/trees/RBSearchTree.kt | 0 lib/src/main/{ => kotlin}/trees/SimpleBinarySearchTree.kt | 0 lib/src/main/{ => kotlin}/vertexes/AVLVertex.kt | 0 lib/src/main/{ => kotlin}/vertexes/InterfaceBSTVertex.kt | 0 lib/src/main/{ => kotlin}/vertexes/RBVertex.kt | 0 lib/src/main/{ => kotlin}/vertexes/SimpleBSTVertex.kt | 0 lib/src/test/kotlin/AVLTreeTests | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename lib/src/main/{ => kotlin}/iterator/TreeIterator.kt (100%) rename lib/src/main/{ => kotlin}/trees/AVLSearchTree.kt (100%) rename lib/src/main/{ => kotlin}/trees/AbstractBinarySearchTree.kt (100%) rename lib/src/main/{ => kotlin}/trees/RBSearchTree.kt (100%) rename lib/src/main/{ => kotlin}/trees/SimpleBinarySearchTree.kt (100%) rename lib/src/main/{ => kotlin}/vertexes/AVLVertex.kt (100%) rename lib/src/main/{ => kotlin}/vertexes/InterfaceBSTVertex.kt (100%) rename lib/src/main/{ => kotlin}/vertexes/RBVertex.kt (100%) rename lib/src/main/{ => kotlin}/vertexes/SimpleBSTVertex.kt (100%) create mode 100644 lib/src/test/kotlin/AVLTreeTests diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt similarity index 100% rename from lib/src/main/iterator/TreeIterator.kt rename to lib/src/main/kotlin/iterator/TreeIterator.kt diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt similarity index 100% rename from lib/src/main/trees/AVLSearchTree.kt rename to lib/src/main/kotlin/trees/AVLSearchTree.kt diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt similarity index 100% rename from lib/src/main/trees/AbstractBinarySearchTree.kt rename to lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt similarity index 100% rename from lib/src/main/trees/RBSearchTree.kt rename to lib/src/main/kotlin/trees/RBSearchTree.kt diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt similarity index 100% rename from lib/src/main/trees/SimpleBinarySearchTree.kt rename to lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt diff --git a/lib/src/main/vertexes/AVLVertex.kt b/lib/src/main/kotlin/vertexes/AVLVertex.kt similarity index 100% rename from lib/src/main/vertexes/AVLVertex.kt rename to lib/src/main/kotlin/vertexes/AVLVertex.kt diff --git a/lib/src/main/vertexes/InterfaceBSTVertex.kt b/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt similarity index 100% rename from lib/src/main/vertexes/InterfaceBSTVertex.kt rename to lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt diff --git a/lib/src/main/vertexes/RBVertex.kt b/lib/src/main/kotlin/vertexes/RBVertex.kt similarity index 100% rename from lib/src/main/vertexes/RBVertex.kt rename to lib/src/main/kotlin/vertexes/RBVertex.kt diff --git a/lib/src/main/vertexes/SimpleBSTVertex.kt b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt similarity index 100% rename from lib/src/main/vertexes/SimpleBSTVertex.kt rename to lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt diff --git a/lib/src/test/kotlin/AVLTreeTests b/lib/src/test/kotlin/AVLTreeTests new file mode 100644 index 0000000..e69de29 From 77fa02b24e81057050bb0169ca35e29dd22ad272 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 30 Mar 2024 18:35:24 +0300 Subject: [PATCH 109/227] build: change add jacoco plugin and JacocoTestReport task --- lib/build.gradle.kts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 6e8f86e..61c261d 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -11,6 +11,9 @@ plugins { // Apply the java-library plugin for API and implementation separation. `java-library` + + // Code coverage plugin + jacoco } repositories { @@ -21,23 +24,19 @@ repositories { dependencies { // Use the Kotlin JUnit 5 integration. testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") + // + testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.2") // Use the JUnit 5 integration. testImplementation(libs.junit.jupiter.engine) testRuntimeOnly("org.junit.platform:junit-platform-launcher") - - // This dependency is exported to consumers, that is to say found on their compile classpath. - api(libs.commons.math3) - - // This dependency is used internally, and not exposed to consumers on their own compile classpath. - implementation(libs.guava) } // Apply a specific Java toolchain to ease working on different environments. java { toolchain { - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(17) } } @@ -45,3 +44,14 @@ tasks.named("test") { // Use JUnit Platform for unit tests. useJUnitPlatform() } + +tasks.named("jacocoTestReport") { + dependsOn(tasks.test) + reports { + csv.required = false + xml.required = false + html.outputLocation = layout.buildDirectory.dir("jacocoHtml") + } +} + + From de28b8cffcffd8c7161265703da6b07bd0e2a536 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 31 Mar 2024 11:47:35 +0300 Subject: [PATCH 110/227] test: add several tests for the RBTree --- lib/src/main/kotlin/trees/RBSearchTree.kt | 3 +- lib/src/test/kotlin/trees/RBSearchTreeTest.kt | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 lib/src/test/kotlin/trees/RBSearchTreeTest.kt diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index e9546a3..1ea1a98 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -185,7 +185,8 @@ class RBSearchTree : AbstractBinarySearchTree> { if (currentVertex == null){ currentVertex = RBVertex(key, value, null, null, true, parent) - if (isLeft) parent?.let { parent.leftSon = currentVertex } + if (root == null) root = currentVertex + else if (isLeft) parent?.let { parent.leftSon = currentVertex } else parent?.let { parent.rightSon = currentVertex } } diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt new file mode 100644 index 0000000..200bb28 --- /dev/null +++ b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt @@ -0,0 +1,36 @@ +package trees +import main.trees.RBSearchTree +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class RBSearchTreeTest { + private lateinit var rbTree: RBSearchTree + + @BeforeEach + fun setup(){ + rbTree = RBSearchTree() + } + + @Test + fun `put a root to the tree`(){ + rbTree.put(7, "hi") + assertEquals(rbTree.get(7), "hi") + } + + @Test + fun `put new vertex to the left`(){ + rbTree.put(7, "hi") + rbTree.put(5, "my") + assertEquals(rbTree.get(5), "my") + } + + @Test + fun `put new vertex to the right`(){ + rbTree.put(7, "hi") + rbTree.put(5, "my") + rbTree.put(9, "name") + assertEquals(rbTree.get(9), "name") + } + +} \ No newline at end of file From 036b015a5da17e0e8d107fee5c6d97070b29b5d8 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 31 Mar 2024 13:38:07 +0300 Subject: [PATCH 111/227] test: full test coverage of put --- lib/src/main/kotlin/trees/RBSearchTree.kt | 4 +- lib/src/test/kotlin/trees/RBSearchTreeTest.kt | 63 ++++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 1ea1a98..eef6fb5 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -285,8 +285,8 @@ class RBSearchTree : AbstractBinarySearchTree> { rightVertex?.parent = vertex.parent when { vertex.parent == null -> root = rightVertex - vertex == vertex.parent?.leftSon -> vertex.parent?.leftSon = rightVertex - else -> vertex.parent?.rightSon = rightVertex + vertex == vertex.parent?.rightSon -> vertex.parent?.rightSon = rightVertex + else -> vertex.parent?.leftSon = rightVertex } vertex.parent = rightVertex rightVertex?.leftSon = vertex diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt index 200bb28..9ea720e 100644 --- a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt @@ -28,9 +28,70 @@ class RBSearchTreeTest { @Test fun `put new vertex to the right`(){ rbTree.put(7, "hi") - rbTree.put(5, "my") rbTree.put(9, "name") assertEquals(rbTree.get(9), "name") } + @Test + fun `put existing vertex without replace`(){ + rbTree.put(7, "hi") + rbTree.put(7, "is", false) + assertEquals(rbTree.get(7), "hi") + } + @Test + fun `put existing vertex with replace`(){ + rbTree.put(7, "hi") + rbTree.put(7, "Slim") + assertEquals(rbTree.get(7), "Slim") + } + + @Test + fun `balance after put - uncle is rightSon and red`(){ + rbTree.put(7, "hi") + rbTree.put(5, "my") + rbTree.put(9, "name") + rbTree.put(6, "is") + assertEquals(rbTree.get(6), "is") + } + + @Test + fun `balance after put - uncle is rightSon and black + newVertex is leftSon`(){ + rbTree.put(7, "hi") + rbTree.put(5, "my") + rbTree.put(3, "name") + assertEquals(rbTree.get(3), "name") + } + + @Test + fun `balance after put - uncle is rightSon and black + newVertex is rightSon`(){ + rbTree.put(7, "hi") + rbTree.put(5, "my") + rbTree.put(6, "name") + assertEquals(rbTree.get(6), "name") + } + + @Test + fun `balance after put - uncle is leftSon and red`(){ + rbTree.put(7, "hi") + rbTree.put(5, "my") + rbTree.put(9, "name") + rbTree.put(8, "is") + assertEquals(rbTree.get(8), "is") + } + + @Test + fun `balance after put - uncle is leftSon and black + newVertex is rightSon`(){ + rbTree.put(7, "hi") + rbTree.put(9, "my") + rbTree.put(10, "name") + assertEquals(rbTree.get(10), "name") + } + + @Test + fun `balance after put - uncle is leftSon and black + newVertex is leftSon`(){ + rbTree.put(7, "hi") + rbTree.put(9, "my") + rbTree.put(8, "name") + assertEquals(rbTree.get(8), "name") + } } \ No newline at end of file From 2af5274d0fe29d9b800eb090bf47b2aa5ff047f8 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 31 Mar 2024 15:02:11 +0300 Subject: [PATCH 112/227] feat: make AVLTree open, add AVLTreeForTest class --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 9 ++-- lib/src/test/kotlin/AVLTreeForTest.kt | 62 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 lib/src/test/kotlin/AVLTreeForTest.kt diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index c8d55db..9820206 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -1,7 +1,7 @@ package main.trees import main.vertexes.AVLVertex -class AVLSearchTree : AbstractBinarySearchTree> { +open class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { if (!isEmpty()) { @@ -90,8 +90,8 @@ class AVLSearchTree : AbstractBinarySearchTree> { } return null } - - enum class RemovalStage {A, B, C} + + private enum class RemovalStage {A, B, C} // a - don't need tree changes anymore // b - probably need some tree changes, but not nulling // c - need to null due "Son" property of (if exists) the parent of removed vertex + b @@ -276,5 +276,6 @@ class AVLSearchTree : AbstractBinarySearchTree> { constructor (comparator: Comparator? = null) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, + comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } diff --git a/lib/src/test/kotlin/AVLTreeForTest.kt b/lib/src/test/kotlin/AVLTreeForTest.kt new file mode 100644 index 0000000..229193a --- /dev/null +++ b/lib/src/test/kotlin/AVLTreeForTest.kt @@ -0,0 +1,62 @@ +import main.vertexes.AVLVertex +import main.trees.AVLSearchTree +import kotlin.math.max +import kotlin.collections.mutableListOf +import kotlin.collections.mutableMapOf +class AVLTreeForTest : AVLSearchTree { + + fun getRootT() : AVLVertex? {return root} + + fun getVertexesInDFSOrder() : MutableList> { + val vertexes : MutableList> = mutableListOf() + getVertexesRec(root, vertexes) + return vertexes + } + private fun getVertexesRec(curVertex : AVLVertex?, vrtList: MutableList>) { + if (curVertex == null) return + vrtList.add(curVertex) + getVertexesRec(curVertex.leftSon, vrtList) + getVertexesRec(curVertex.rightSon, vrtList) + } + fun getHeights() : MutableMap { + val heights : MutableMap = mutableMapOf() + if (root == null) return heights + getHeightsRec(root as AVLVertex, heights) + return heights + } + private fun getHeightsRec(rootOfSubtree : AVLVertex, heights : MutableMap) : Int { + return when ((rootOfSubtree.leftSon == null) to (rootOfSubtree.rightSon == null)) { + true to true -> { + heights.put(rootOfSubtree.key, 0) + 0 + } + true to false -> { + val height = getHeightsRec(rootOfSubtree.rightSon as AVLVertex, heights) + 1 + heights.put(rootOfSubtree.key, height) + height + } + false to true -> { + val height = getHeightsRec(rootOfSubtree.leftSon as AVLVertex, heights) + 1 + heights.put(rootOfSubtree.key, height) + height + } + else -> { + val heightOfLeftSubtree = getHeightsRec(rootOfSubtree.leftSon as AVLVertex, heights) + val heightOfRightSubtree = getHeightsRec(rootOfSubtree.rightSon as AVLVertex, heights) + val height = max(heightOfLeftSubtree, heightOfRightSubtree) + 1 + heights.put(rootOfSubtree.key, height) + max(heightOfLeftSubtree, heightOfRightSubtree) + 1 + } + } + } + constructor (root: AVLVertex, size: Long, comparator: Comparator? = null) : + super(comparator) { + this.root = root + this.size = size + } + + constructor (comparator: Comparator? = null) : super(comparator) + + constructor(map: Map, replaceIfExists: Boolean = true, + comparator: Comparator? = null) : super(map, replaceIfExists, comparator) +} \ No newline at end of file From 6262d5862aaa6ec6eaff76f261f95d03db0f7f38 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 31 Mar 2024 19:13:39 +0300 Subject: [PATCH 113/227] fix: add root value change on removing in SimpleBinarySearchTree private method removeRec() --- lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index ef139a7..f8058c7 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -55,7 +55,11 @@ class SimpleBinarySearchTree : AbstractBinarySearchTree { val deletedValue: V = vertex.value if (vertex.leftSon == null || vertex.rightSon == null) { - if (vertex.leftSon == null) return Triple(vertex.rightSon, deletedValue, true) + if (vertex.leftSon == null) { + if (vertex == root) root = root?.rightSon + return Triple(vertex.rightSon, deletedValue, true) + } + if (vertex == root) root = root?.leftSon return Triple(vertex.leftSon, deletedValue, true) } val minKeyRightSubtreeNode: SimpleBSTVertex? = getMinKeyNodeRec(vertex.rightSon) From db1c9844f8d1df6ba07d201f100b317c0733c72b Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 31 Mar 2024 19:14:34 +0300 Subject: [PATCH 114/227] feat: do class SimpleBinarySearchTree open fot tests --- lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index f8058c7..d165ea8 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -1,7 +1,7 @@ package main.trees import main.vertexes.SimpleBSTVertex -class SimpleBinarySearchTree : AbstractBinarySearchTree> { +open class SimpleBinarySearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { if (root == null) { From d63c6d7f1cc87e29c556e84654533e5f86e83259 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 31 Mar 2024 19:20:41 +0300 Subject: [PATCH 115/227] feat: add new class TestSimpleBST for tests which inherits SimpleBinarySearchTree class and write method getTreeRoot() --- lib/src/test/kotlin/TestSimpleBST.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 lib/src/test/kotlin/TestSimpleBST.kt diff --git a/lib/src/test/kotlin/TestSimpleBST.kt b/lib/src/test/kotlin/TestSimpleBST.kt new file mode 100644 index 0000000..02b3dea --- /dev/null +++ b/lib/src/test/kotlin/TestSimpleBST.kt @@ -0,0 +1,10 @@ +import main.trees.SimpleBinarySearchTree +import main.vertexes.SimpleBSTVertex + +class TestSimpleBST : SimpleBinarySearchTree { + fun getTreeRoot(): SimpleBSTVertex? {return root} + + constructor(comparator: Comparator?) : super(comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) + : super(map, replaceIfExists, comparator) +} \ No newline at end of file From 197b4182aa94388cd288ad3a353d607634eb7830 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 31 Mar 2024 19:21:35 +0300 Subject: [PATCH 116/227] feat: write tests for SimpleBinarySearchTree class --- lib/src/test/kotlin/SimpleBSTreeTests.kt | 165 +++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 lib/src/test/kotlin/SimpleBSTreeTests.kt diff --git a/lib/src/test/kotlin/SimpleBSTreeTests.kt b/lib/src/test/kotlin/SimpleBSTreeTests.kt new file mode 100644 index 0000000..4271b13 --- /dev/null +++ b/lib/src/test/kotlin/SimpleBSTreeTests.kt @@ -0,0 +1,165 @@ +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class SimpleBSTTests { + + @Test + fun `get root`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + val root = tree.getTreeRoot() + assertEquals(1, root?.key) + } + + @Test + fun `put vertex after remove root test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + val deletedValue = tree.remove(1) + assertEquals("one", deletedValue) + tree.put(2, "two") + assertEquals("two", tree.getTreeRoot()?.value) + assertEquals(1, tree.size()) + } + + @Test + fun `replacing value of existing key test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "old"))) + tree.put(1, "new", true) + assertEquals("new", tree.getTreeRoot()?.value) + assertEquals(1, tree.size()) + } + + @Test + fun `non replacing value of existing key test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "old"))) + tree.put(1, "new", false) + assertEquals("old", tree.getTreeRoot()?.value) + assertEquals(1, tree.size()) + } + + @Test + fun `put key more than root key test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + tree.put(2, "right") + assertEquals("right", tree.getTreeRoot()?.rightSon?.value) + assertEquals(2, tree.size()) + } + + @Test + fun `put key less than root key test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + tree.put(0, "left") + assertEquals("left", tree.getTreeRoot()?.leftSon?.value) + assertEquals(2, tree.size()) + } + + @Test + fun `put many vertexes test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(0, "hello"))) + for (key in 1 .. 6) { + tree.put(key, "hello") + } + assertEquals(7, tree.size()) + } + + @Test + fun `put many vertexes with method putAll() test`() { + val map: Map = mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two") + ) + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + tree.putAll(map) + assertEquals(6, tree.size()) + } + + @Test + fun `put many vertexes with same key test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + for (i in 1..6) { + tree.put(1, "one") + } + assertEquals(1, tree.size()) + } + + @Test + fun `remove no sons root test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + tree.remove(1) + assertEquals(null, tree.getTreeRoot()) + assertEquals(0, tree.size()) + } + + @Test + fun `remove no sons vertex test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(0, "zero"))) + tree.remove(0) + assertEquals(null, tree.getTreeRoot()?.leftSon) + assertEquals(1, tree.size()) + } + + @Test + fun `remove one left son vertex test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(0, "zero"), Pair(-1, "negative"))) + tree.remove(0) + assertEquals(-1, tree.getTreeRoot()?.leftSon?.key) + assertEquals(2, tree.size()) + } + + @Test + fun `remove one right son vertex test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(2, "two"), Pair(3, "three"))) + tree.remove(2) + assertEquals(3, tree.getTreeRoot()?.rightSon?.key) + assertEquals(2, tree.size()) + } + + @Test + fun `remove two sons vertex test`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(2, "two"), Pair(0, "zero"))) + tree.remove(1) + assertEquals(2, tree.getTreeRoot()?.key) + assertEquals(2, tree.size()) + } + + @Test + fun `remove two sons with right subtree vertex test`() { + val tree: TestSimpleBST = TestSimpleBST( + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two") + ) + ) + tree.remove(1) + assertEquals(2, tree.getTreeRoot()?.key) + assertEquals(5, tree.size()) + } + + @Test + fun `remove many vertex test`() { + val tree: TestSimpleBST = TestSimpleBST( + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two") + ) + ) + for (key in 0..5) { + tree.remove(key) + } + assertEquals(null, tree.getTreeRoot()) + assertEquals(0, tree.size()) + } + + +} \ No newline at end of file From 16b7e562cb5217893c7044ac30be81022ba04e5f Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 31 Mar 2024 19:33:37 +0300 Subject: [PATCH 117/227] feat: add test 'remove non-existing value' in SimpleBSTree class --- lib/src/test/kotlin/SimpleBSTreeTests.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/test/kotlin/SimpleBSTreeTests.kt b/lib/src/test/kotlin/SimpleBSTreeTests.kt index 4271b13..3204aa6 100644 --- a/lib/src/test/kotlin/SimpleBSTreeTests.kt +++ b/lib/src/test/kotlin/SimpleBSTreeTests.kt @@ -161,5 +161,11 @@ class SimpleBSTTests { assertEquals(0, tree.size()) } - + @Test + fun `remove non-existing value`() { + val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + val deletedValue = tree.remove(100) + assertEquals(null, deletedValue) + assertEquals(1, tree.size()) + } } \ No newline at end of file From c578f301ee6b672a4aa8c91636e935907495d867 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 31 Mar 2024 23:55:22 +0300 Subject: [PATCH 118/227] feat : add putTest functions --- lib/src/test/kotlin/AVLTreeTest.kt | 474 +++++++++++++++++++++++++++++ 1 file changed, 474 insertions(+) create mode 100644 lib/src/test/kotlin/AVLTreeTest.kt diff --git a/lib/src/test/kotlin/AVLTreeTest.kt b/lib/src/test/kotlin/AVLTreeTest.kt new file mode 100644 index 0000000..70a6796 --- /dev/null +++ b/lib/src/test/kotlin/AVLTreeTest.kt @@ -0,0 +1,474 @@ +import AVLTreeForTest +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.condition.DisabledIf +import kotlin.collections.hashMapOf + +class AVLTreeTest { + + private fun makeEmptyTree() : AVLTreeForTest {return AVLTreeForTest()} + + //putTest + + @Test + fun `entry became root after it was added to empty tree`() { + val tree = makeEmptyTree() + tree.put(0, '0') + val root = tree.getRootT() + assert((root?.key to root?.value) == (0 to '0')) + } + + @Test + fun `size equals 1 after entry was added to empty tree`() { + val tree = makeEmptyTree() + tree.put(0, '0') + assert(tree.size() == 1L) + } + + private fun makeSize1Tree() : AVLTreeForTest { + return AVLTreeForTest(AVLVertex('b', '+'), 1L) // init tree by root and size (don't use put) + } + + @Test + fun `entry with larger key became right son after it was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('c', '+') + val root = tree.getRootT() + assert((root?.rightSon?.key to root?.rightSon?.value) == ('c' to '+')) + } + + @Test + fun `entry with lesser key became left son after it was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('a', '-') + val root = tree.getRootT() + assert((root?.leftSon?.key to root?.leftSon?.value) == ('a' to '-')) + } + + @Test + fun `root's sonsHeightDiff decreased by 1 after entery with larger key was added to size 1 tree`(){ + val tree = makeSize1Tree() + tree.put('c', '+') + val root = tree.getRootT() + assert(root?.sonsHeightDiff == -1) + } + + @Test + fun `root's sonsHeightDiff increased by 1 after entery with lesser key was added to size 1 tree`(){ + val tree = makeSize1Tree() + tree.put('a', '-') + val root = tree.getRootT() + assert(root?.sonsHeightDiff == 1) + } + + @Test + fun `size equals 2 after entry with larger key was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('c', '+') + assert(tree.size() == 2L) + } + + @Test + fun `size equals 2 after entry with lesser key was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('a', '-') + assert(tree.size() == 2L) + } + + private fun makeTreeForNeedNotBalanceingTest() : AVLTreeForTest { + return AVLTreeForTest(AVLVertex(4, 'A', AVLVertex(1, 'I'), AVLVertex(5, 'S')), 3L) + } + + private fun isTreeConsistsOf(expectedContent : Set>, tree: AVLTreeForTest ) : Boolean { + val vertexes = tree.getVertexesInDFSOrder() + val pairsFromVertexes = (Array(vertexes.size){i -> (vertexes[i].key to vertexes[i].value)}).toSet() + return pairsFromVertexes == expectedContent + } + + @Test + fun `content is correct after entery was added (needn't balancing)`() { + val tree = makeTreeForNeedNotBalanceingTest() + tree.put(0, 'O') + assert(isTreeConsistsOf(setOf(0 to 'O', 1 to 'I', 5 to 'S', 4 to 'A'), tree)) + } + + @Test + fun `size increased by 1 after added to 'size 2+' tree (needn't balancing)`() { + val tree = makeTreeForNeedNotBalanceingTest() + tree.put(0, 'O') + assert(tree.size() == 4L) + } + + private fun isTreeSStructureThat(tree : AVLTreeForTest, + order : Array, deps : List>) : Boolean { + // Tiple consists of indexes in order of (1)vertex, one's (2)leftSon and (3)RightSon + val vertexes = tree.getVertexesInDFSOrder() + if (vertexes.size != order.size) return false + for (i in order.indices) + if (order[i] != vertexes[i].key) return false + for (dep in deps){ + if (dep.component2() != null) + if (vertexes[dep.component1()].leftSon != vertexes[dep.component2() as Int]) + return false + if (dep.component3() != null) + if (vertexes[dep.component1()].rightSon != vertexes[dep.component3() as Int]) + return false + } + return true + } + + @Test + fun `structure is correct after added to 'size 2+' tree (needn't balancing)`() { + val tree = makeTreeForNeedNotBalanceingTest() + tree.put(0, 'O') + val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null)) + assert(isTreeSStructureThat(tree, arrayOf(4, 1, 0, 5), expectedDependences)) + } + + private fun isSonsHeightDiffCorrect(tree : AVLTreeForTest) : Boolean { + val vertexes = tree.getVertexesInDFSOrder() + val heights = tree.getHeights() + if (vertexes.size != heights.size) return false + for (vertex in vertexes) { + val expectedSonsHeightDiff = + when ((vertex.leftSon == null) to (vertex.rightSon == null)) { + true to true -> 0 + true to false -> -1 - (heights[(vertex.rightSon as AVLVertex).key] ?: return false) + false to true -> 1 + (heights[(vertex.leftSon as AVLVertex).key] ?: return false) + else -> { + val heightOfLeftSubtree = heights[(vertex.leftSon as AVLVertex).key] ?: return false + val heightOfRightSubtree = heights[(vertex.rightSon as AVLVertex).key] ?: return false + heightOfLeftSubtree - heightOfRightSubtree + } + } + if (expectedSonsHeightDiff != vertex.sonsHeightDiff) return false + } + return true + } + + @Test + fun `vertexes' sonsHeightDiff are correct after entery was added to 'size 2+' tree (needn't balancing)`() { + val tree = makeTreeForNeedNotBalanceingTest() + tree.put(0, 'O') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToRotateLeftPutTest() : AVLTreeForTest { + val rightSonSRightSon = AVLVertex('h', 'H', AVLVertex('f', 'F'), AVLVertex('i', 'I')) + val rightSon = AVLVertex('e', 'E', AVLVertex('d','D'), rightSonSRightSon, -1) + val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) + return AVLTreeForTest(root, 8L) + } + + @Test + fun `content is correct after entery was added (have to rotate left)`() { + val tree = makeTreeForHaveToRotateLeftPutTest() + tree.put('j', 'J') + val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expextedContent, tree)) + } + + + @Test + fun `size increased by 1 after added (have to rotate left)`() { + val tree = makeTreeForHaveToRotateLeftPutTest() + tree.put('j', 'J') + assert(tree.size() == 9L) + } + + @Test + fun `structure is correct after added (have to rotate left)`() { + val tree = makeTreeForHaveToRotateLeftPutTest() + tree.put('j', 'J') + val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), + Triple(4, 5, 6), Triple(7, null, 8)) + val expextedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j' ) + assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after added (have to rotate left)`() { + val tree = makeTreeForHaveToRotateLeftPutTest() + tree.put('j', 'J') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToRotateRightPutTest() : AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) + val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('e','E'), 1) + val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I', null, AVLVertex('j', 'J'), -1), 1) + return AVLTreeForTest(root, 8L) + } + + @Test + fun `content is correct after entery was added (have to rotate right)`() { + val tree = makeTreeForHaveToRotateRightPutTest() + tree.put('a', 'A') + val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expextedContent, tree)) + } + + @Test + fun `size increased by 1 after added (have to rotate right)`() { + val tree = makeTreeForHaveToRotateRightPutTest() + tree.put('a', 'A') + assert(tree.size() == 9L) + } + + @Test + fun `structure is correct after added (have to rotate right)`() { + val tree = makeTreeForHaveToRotateRightPutTest() + tree.put('a', 'A') + val expectedDependences = listOf(Triple(0, 1, 7), Triple(1, 2, 4), Triple(2, 3, null), + Triple(4, 5, 6), Triple(7, null, 8)) + val expextedOrder = arrayOf('h', 'c', 'b', 'a', 'f', 'd', 'e', 'i', 'j') + assert(isTreeSStructureThat(tree, expextedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after added (have to rotate right)`() { + val tree = makeTreeForHaveToRotateRightPutTest() + tree.put('a', 'A') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToChangeRootByRotateLeftPutTest() : AVLTreeForTest { + val rightSon = AVLVertex('h', 'H', AVLVertex('f', 'F'), AVLVertex('i', 'I')) + val root = AVLVertex('e', 'E', AVLVertex('d','D'), rightSon, -1) + return AVLTreeForTest(root, 5L) + } + + @Test + fun `content is correct after entery was added (rotateLeft changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() + tree.put('j', 'J') + val expextedContent = setOf('d' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expextedContent, tree)) + } + + @Test + fun `size increased by 1 after added (rotateLeft changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() + tree.put('j', 'J') + assert(tree.size() == 6L) + } + + @Test + fun `structure is correct after added (rotateLeft changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() + tree.put('j', 'J') + val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, null, 5)) + val expextedOrder = arrayOf('h', 'e', 'd', 'f', 'i', 'j') + assert(isTreeSStructureThat(tree, expextedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after added (rotateLeft changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() + tree.put('j', 'J') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToChangeRootByRotateRightPutTest() : AVLTreeForTest { + val leftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) + val root = AVLVertex('f', 'F', leftSon, AVLVertex('e','E'), 1) + return AVLTreeForTest(root, 5L) + } + + @Test + fun `tree consists of initially content and entery after entery was added (rotateRight changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() + tree.put('a', 'A') + val expextedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'f' to 'F') + assert(isTreeConsistsOf(expextedContent, tree)) + } + + @Test + fun `size increased by 1 after added (rotateRight changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() + tree.put('a', 'A') + assert(tree.size() == 6L) + } + + @Test + fun `tree's structure is correct after added (rotateRight changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() + tree.put('a', 'A') + val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 5)) + val expextedOrder = arrayOf('c', 'b', 'a', 'f', 'd', 'e') + assert(isTreeSStructureThat(tree, expextedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after added (rotateRight changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() + tree.put('a', 'A') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToBigRotateLeftPutTest() : AVLTreeForTest { + val rightSonSRightSon = AVLVertex('i', 'I', AVLVertex('g', 'G'), AVLVertex('j', 'J')) + val rightSon = AVLVertex('e', 'E', AVLVertex('d','D'), rightSonSRightSon, -1) + val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) + return AVLTreeForTest(root, 8L) + } + + // (1) - add grandson's right son, (2) add grandson's left son + @Test + fun `content is correct after entery was added (have to big rotate left)(1)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('f', 'F') + val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + 'd' to 'D', 'e' to 'E', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expextedContent, tree)) + } + + @Test + fun `content is correct after entery was added (have to big rotate left)(2)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('h', 'H') + val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expextedContent, tree)) + } + + @Test + fun `size increased by 1 after added (have to big rotate left)(1)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('f', 'F') + assert(tree.size() == 9L) + } + + @Test + fun `size increased by 1 after added (have to big rotate left)(2)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('h', 'H') + assert(tree.size() == 9L) + } + + @Test + fun `structure is correct after added (have to big rotate left)(1)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('f', 'F') + val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), + Triple(4, 5, 6), Triple(7, null, 8)) + val expextedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'f', 'i', 'j') + assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + } + @Test + fun `structure is correct after added (have to big rotate left)(2)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('h', 'H') + val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 6), + Triple(4, 5, null), Triple(6, 7, 8)) + val expextedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'i', 'h', 'j') + assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + } + @Test + fun `vertexes' sonsHeightDiff are correct after added (have to big rotate left)(1)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('f', 'F') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after added (have to big rotate left)(2)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('h', 'H') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToBigRotateRightPutTest() : AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', 'B', AVLVertex('a', 'A'), AVLVertex('d', 'D')) + val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('g','G'), 1) + val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I',null, AVLVertex('j', 'J'), -1), 1) + return AVLTreeForTest(root, 8L) + } + + // (1) - add grandson's left son, (2) add grandson's right son + @Test + fun `content is correct after entery was added (have to big rotate right)(1)`() { + val tree = makeTreeForHaveToBigRotateRightPutTest() + tree.put('c', 'C') + val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + 'd' to 'D', 'h' to 'H', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expextedContent, tree)) + } + + @Test + fun `content is correct after entery was added (have to big rotate right)(2)`() { + val tree = makeTreeForHaveToBigRotateRightPutTest() + tree.put('e', 'E') + val expextedContent = setOf('a' to 'A','b' to 'B', 'f' to 'F', + 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expextedContent, tree)) + } + + @Test + fun `size increased by 1 after added (have to big rotate right)(1)`() { + val tree = makeTreeForHaveToBigRotateRightPutTest() + tree.put('c', 'C') + assert(tree.size() == 9L) + } + + @Test + fun `size increased by 1 after added (have to big rotate right)(2)`() { + val tree = makeTreeForHaveToBigRotateRightPutTest() + tree.put('e', 'E') + assert(tree.size() == 9L) + } + + + @Test + fun `structure is correct after added (have to big rotate right)(1)`() { + val tree = makeTreeForHaveToBigRotateRightPutTest() + tree.put('c', 'C') + val expectedDependences = listOf(Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 5), + Triple(5, null, 6), Triple(2, 3, 4)) + val expextedOrder = arrayOf('h', 'd', 'b', 'a', 'c', 'f', 'g', 'i', 'j') + assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + } + + @Test + fun `structure is correct after added (have to big rotate right)(2)`() { + val tree = makeTreeForHaveToBigRotateRightPutTest() + tree.put('e', 'E') + val expectedDependences = listOf(Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 4), + Triple(2, 3, null), Triple(4, 5, 6)) + val expextedOrder = arrayOf('h', 'd', 'b', 'a', 'f', 'e', 'g', 'i', 'j') + assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after added (have to big rotate right)(1)`() { + val tree = makeTreeForHaveToBigRotateRightPutTest() + tree.put('c', 'C') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after added (have to big rotate right)(2)`() { + val tree = makeTreeForHaveToBigRotateLeftPutTest() + tree.put('e', 'E') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `tree has no changes after entry with existed key and param replaceIfExists = false was added`() { + val tree = makeSize1Tree() + tree.put('b', '-', false) + assert(tree.size() == 1L) + assert(tree.getRootT()?.value == '+') + } + + @Test + fun `content is correct after init by map`() { + val tree = AVLTreeForTest(hashMapOf('a' to 'A', 'b' to 'B')) + val expextedContent = setOf('a' to 'A', 'b' to 'B') + assert(isTreeConsistsOf(expextedContent, tree)) + } +} + From bdc6b5858c81331cfa155b1279d1b275af4361f7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 1 Apr 2024 02:12:11 +0300 Subject: [PATCH 119/227] fix (AVLTree) : remove wrongs in work with RemovaleStage values --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 9820206..5c021aa 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -90,7 +90,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> } return null } - + private enum class RemovalStage {A, B, C} // a - don't need tree changes anymore // b - probably need some tree changes, but not nulling @@ -121,13 +121,13 @@ open class AVLSearchTree : AbstractBinarySearchTree> } true to false -> { size-- - Triple(RemovalStage.C, vertex.rightSon as AVLVertex, vertex.value) + Triple(RemovalStage.B, vertex.rightSon as AVLVertex, vertex.value) } false to true -> { size-- - Triple(RemovalStage.C, vertex.leftSon as AVLVertex, vertex.value) + Triple(RemovalStage.B, vertex.leftSon as AVLVertex, vertex.value) } - else -> Triple(RemovalStage.C, + else -> Triple(RemovalStage.B, prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) } } From 6896c5818e8d7eebfc119dcbdfc934a23cf83d2f Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 02:37:30 +0300 Subject: [PATCH 120/227] feat: add README.md --- README.md | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..04d2d78 --- /dev/null +++ b/README.md @@ -0,0 +1,140 @@ +
+

+

badge +badge +badge

+ +# BinTreeKit +___ + + +## Table of Contents +- [About Project](#about-project) +- [Usage](#usage) +- [Project Structure](#project-structure) +- [Developers and Contacts](#developers-and-contacts) +- [License](#license) + + +## About Project +`BinTreeKit` is a library that provides implementations for three types of trees: `SimpleBinarySearchTree`, `AVLSearchTree` and `RBSearchTree`. The library is designed to simplify the process of managing hierarchical data, allowing Kotlin developers to focus on building robust and scalable applications. + + +## Usage +### 1. **Importing Classes**: +```kotlin +import main.trees.SimpleBinarySearchTree +import main.trees.AVLSearchTree +import main.trees.RBSearchTree +``` +### 2. **Instantiate Trees**: +```kotlin +// create a Simple Binary Search Tree +val bstTree = SimpleBinarySearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) + +// create an AVL Search Tree +val avlTree = AVLSearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) + +// create a Red-Black Search Tree +val rbTree = RBSearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) +``` +### 3. **Use Tree Methods**: +```kotlin +// put key-value pairs with different values of replaceIfExists perematers +bstTree.putAll(mapOf(Pair(2, "hamster"), Pair(3, "bird")), true) +rbTree.put(4, "horse", false) + +// remove key-value pair from tree and return value +println(rbTree.remove(4)) // output: horse +bstTree.remove(1) + +// pairwise iteration +for (pair in avlTree) { + print(pair) +} // output: (1, "cat")(2, "dog") +``` + + +[//]: # (## Project Structure) + + +## Developers and Contacts +- [vicitori](https://github.com/vicitori) - Victoria Lutsyuk (Simple Binary Search Tree) +- [Szczucki](https://github.com/Szczucki) - Nikita Shchutskii (AVL Search Tree) +- [TerrMen](https://github.com/TerrMen) - Kostya Oreshin (RB Search Tree) + +Project Link: [trees-9](https://github.com/spbu-coding-2023/trees-9.git) + + +## License +This project uses the **APACHE LICENSE, VERSION 2.0**. See the [LICENSE](LICENSE.md) for more info. + + +[//]: # (## How to Use ) + +[//]: # (___) + +[//]: # (To use the Tree Library in your Kotlin project, follow these steps:) + +[//]: # (1. **Add Dependency**: Add the Tree Library as a dependency in your `build.gradle.kts` file:) + +[//]: # ( ```kotlin) + +[//]: # ( dependencies {) + +[//]: # ( implementation("com.example:tree-library:1.0.0")) + +[//]: # ( }) + +[//]: # (2. **Import Classes**: Import the necessary classes from the library into your Kotlin files:) + +[//]: # ( ```kotlin) + +[//]: # ( import main.trees.*) + +[//]: # ( import main.vertexes.InterfaceBSTVertex) + +[//]: # ( import main.iterator.TreeIterator) + +[//]: # (3. **Instantiate Trees**: Create instances of the tree structures provided by the library, such as Simple Binary Search Tree, AVL Tree, or Red-Black Tree.) + +[//]: # ( ```kotlin) + +[//]: # ( // Create a Simple Binary Search Tree) + +[//]: # ( val bst = SimpleBinarySearchTree()) + +[//]: # (4. **Use Tree Methods**: Utilize the methods provided by the tree classes to insert, remove, search, and traverse tree elements according to your application requirements.) + +[//]: # ( ```kotlin) + +[//]: # ( // Insert key-value pairs) + +[//]: # ( bst.put(5, "Five")) + +[//]: # ( bst.put(3, "Three")) + +[//]: # ( bst.put(7, "Seven")) + +[//]: # ( ) +[//]: # ( // Retrieve values) + +[//]: # ( println(bst.get(3)) // Output: Three) + +[//]: # ( ) +[//]: # ( // Remove a key-value pair) + +[//]: # ( bst.remove(3)) + +[//]: # ( ) +[//]: # ( // Iterate over tree elements) + +[//]: # ( for ((key, value) in bst) {) + +[//]: # ( println("Key: $key, Value: $value")) + +[//]: # ( }) \ No newline at end of file From 5cd9a378cde0659e451eaf8c327956719bc3a172 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 02:44:57 +0300 Subject: [PATCH 121/227] fix: deleted logo.png and Project Structure in Table of Contents at README.md --- README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 04d2d78..f9a0179 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,18 @@ -
-

badge badge badge

# BinTreeKit -___ ## Table of Contents - [About Project](#about-project) - [Usage](#usage) -- [Project Structure](#project-structure) - [Developers and Contacts](#developers-and-contacts) - [License](#license) +[//]: # (- [Project Structure](#project-structure)) + ## About Project `BinTreeKit` is a library that provides implementations for three types of trees: `SimpleBinarySearchTree`, `AVLSearchTree` and `RBSearchTree`. The library is designed to simplify the process of managing hierarchical data, allowing Kotlin developers to focus on building robust and scalable applications. From 33bbb7a8fbb6b1582f3ece959eb20dc65d642f81 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 1 Apr 2024 03:10:54 +0300 Subject: [PATCH 122/227] test: add tests for remove, coverage is about 93% --- lib/src/main/kotlin/trees/RBSearchTree.kt | 55 +++-- lib/src/test/kotlin/trees/RBSearchTreeTest.kt | 202 +++++++++++++++++- 2 files changed, 228 insertions(+), 29 deletions(-) diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index eef6fb5..fde180f 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -19,28 +19,43 @@ class RBSearchTree : AbstractBinarySearchTree> { override fun remove(key: K): V? { val vertex: RBVertex = getVertex(key) ?: return null val value = vertex.value - var isVertexRed = vertex.isRed - var child: RBVertex? = null - if (countChildren(vertex) < 2){ - child = getChild(vertex) - replaceVertexBy(vertex, child) - } + if (needToBalance(vertex)) balanceAfterRemove(vertex) + + return value + } - else{ - val vertexForSwap = getMinKeyNodeRec(vertex.rightSon) - vertexForSwap?.let{ - vertex.key = it.key - vertex.value = it.value - isVertexRed = it.isRed - child = getChild(it) - replaceVertexBy(it, child) + private fun needToBalance(vertex: RBVertex): Boolean{ + when (countChildren(vertex)){ + 0 -> { + if (vertex.isRed){ + replaceVertexBy(vertex, null) + return false + } + return true } - } - if (!isVertexRed) balanceAfterRemove(child) + 1 -> { + replaceVertexBy(vertex, getChild(vertex)) + return false + } - return value + 2 -> { + val vertexForSwap = getMinKeyNodeRec(vertex.rightSon) + vertexForSwap?.let{ + val key = vertex.key + vertex.key = it.key + it.key = key + + val value = vertex.value + vertex.value = it.value + it.value = value + + needToBalance(vertexForSwap) + } + } + } + return false } //we need to balance tree after removal black vertex with 0 children @@ -79,6 +94,7 @@ class RBSearchTree : AbstractBinarySearchTree> { if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && (brother?.rightSon?.isRed == false || brother?.rightSon == null)){ brother?.isRed = true + if (currentVertex == vertex) currentVertex?.parent?.leftSon = null currentVertex = currentVertex?.parent } @@ -96,6 +112,7 @@ class RBSearchTree : AbstractBinarySearchTree> { brother?.rightSon?.isRed = false val vertexForRotate = currentVertex?.parent vertexForRotate?.let { rotateLeft(vertexForRotate) } + if (currentVertex == vertex) currentVertex?.parent?.leftSon = null currentVertex = root } } @@ -114,6 +131,7 @@ class RBSearchTree : AbstractBinarySearchTree> { if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && (brother?.rightSon?.isRed == false || brother?.rightSon == null)){ brother?.isRed = true + if (currentVertex == vertex) currentVertex?.parent?.rightSon = null currentVertex = currentVertex?.parent } @@ -131,6 +149,7 @@ class RBSearchTree : AbstractBinarySearchTree> { brother?.rightSon?.isRed = false val vertexForRotate = currentVertex?.parent vertexForRotate?.let { rotateRight(vertexForRotate) } + if (currentVertex == vertex) currentVertex?.parent?.rightSon = null currentVertex = root } } @@ -140,7 +159,7 @@ class RBSearchTree : AbstractBinarySearchTree> { //finds vertex by corresponding key //if such vertex doesn't exist returns null - private fun getVertex(key: K): RBVertex? { + fun getVertex(key: K): RBVertex? { var currentVertex: RBVertex? = root while (currentVertex?.key != key){ diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt index 9ea720e..71f9040 100644 --- a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt @@ -1,47 +1,56 @@ package trees import main.trees.RBSearchTree +import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import kotlin.test.assertEquals class RBSearchTreeTest { private lateinit var rbTree: RBSearchTree + private lateinit var expectedResult: List> + private var result: MutableList> = mutableListOf() @BeforeEach fun setup(){ rbTree = RBSearchTree() } + @AfterEach + fun end(){ + for (el in rbTree) result.add(el) + assertEquals(expectedResult, result) + } + @Test fun `put a root to the tree`(){ rbTree.put(7, "hi") - assertEquals(rbTree.get(7), "hi") + expectedResult = listOf(Pair(7, "hi")) } @Test fun `put new vertex to the left`(){ rbTree.put(7, "hi") rbTree.put(5, "my") - assertEquals(rbTree.get(5), "my") + expectedResult = listOf(Pair(7, "hi"), Pair(5, "my")) } @Test fun `put new vertex to the right`(){ rbTree.put(7, "hi") rbTree.put(9, "name") - assertEquals(rbTree.get(9), "name") + expectedResult = listOf(Pair(7, "hi"), Pair(9, "name")) } @Test fun `put existing vertex without replace`(){ rbTree.put(7, "hi") rbTree.put(7, "is", false) - assertEquals(rbTree.get(7), "hi") + expectedResult = listOf(Pair(7, "hi")) } @Test fun `put existing vertex with replace`(){ rbTree.put(7, "hi") rbTree.put(7, "Slim") - assertEquals(rbTree.get(7), "Slim") + expectedResult = listOf(Pair(7, "Slim")) } @Test @@ -50,7 +59,7 @@ class RBSearchTreeTest { rbTree.put(5, "my") rbTree.put(9, "name") rbTree.put(6, "is") - assertEquals(rbTree.get(6), "is") + expectedResult = listOf(Pair(7, "hi"), Pair(9, "name"), Pair(5, "my"), Pair(6, "is")) } @Test @@ -58,7 +67,7 @@ class RBSearchTreeTest { rbTree.put(7, "hi") rbTree.put(5, "my") rbTree.put(3, "name") - assertEquals(rbTree.get(3), "name") + expectedResult = listOf(Pair(5, "my"), Pair(7, "hi"), Pair(3, "name")) } @Test @@ -66,7 +75,7 @@ class RBSearchTreeTest { rbTree.put(7, "hi") rbTree.put(5, "my") rbTree.put(6, "name") - assertEquals(rbTree.get(6), "name") + expectedResult = listOf(Pair(6, "name"), Pair(7, "hi"), Pair(5, "my")) } @Test @@ -75,7 +84,7 @@ class RBSearchTreeTest { rbTree.put(5, "my") rbTree.put(9, "name") rbTree.put(8, "is") - assertEquals(rbTree.get(8), "is") + expectedResult = listOf(Pair(7, "hi"), Pair(9, "name"), Pair(8, "is"), Pair(5, "my")) } @Test @@ -83,7 +92,7 @@ class RBSearchTreeTest { rbTree.put(7, "hi") rbTree.put(9, "my") rbTree.put(10, "name") - assertEquals(rbTree.get(10), "name") + expectedResult = listOf(Pair(9, "my"), Pair(10, "name"), Pair(7, "hi")) } @Test @@ -91,7 +100,178 @@ class RBSearchTreeTest { rbTree.put(7, "hi") rbTree.put(9, "my") rbTree.put(8, "name") - assertEquals(rbTree.get(8), "name") + expectedResult = listOf(Pair(8, "name"), Pair(9, "my"), Pair(7, "hi")) + } + + @Test + fun `remove non-existent vertex`(){ + rbTree.put(7, "hi") + rbTree.remove(9) + expectedResult = listOf(Pair(7, "hi")) + } + + @Test + fun `delete red vertex with 0 children`(){ + rbTree.put(7, "hi") + rbTree.put(9, "my") + rbTree.remove(9) + expectedResult = listOf(Pair(7, "hi")) + } + + @Test + fun `delete black vertex with 1 rightSon`(){ + rbTree.put(7, "hi") + rbTree.put(9, "my") + rbTree.remove(7) + expectedResult = listOf(Pair(9, "my")) + } + + @Test + fun `delete black vertex with 1 leftSon`(){ + rbTree.put(7, "hi") + rbTree.put(5, "my") + rbTree.remove(7) + expectedResult = listOf(Pair(5, "my")) + } + + @Test + fun `delete black vertex with 2 children`(){ + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.remove(7) + expectedResult = listOf(Pair(10, "name"), Pair(4, "my")) + } + + @Test + fun `delete red vertex with 2 children`(){ + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(3, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "chka") + rbTree.put(11, "Slim") + rbTree.put(13, "Shady") + rbTree.remove(10) + expectedResult = listOf(Pair(7, "hi"), Pair(11, "Slim"), Pair(12, "chka"), Pair(13, "Shady"), Pair(9, "chka"), + Pair(4, "my"), Pair(5, "chka"), Pair(3, "is")) + } + + @Test + fun `balance after remove - brother is right and black, brother's rightSon - red`(){ + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(3, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "chka") + rbTree.put(11, "Slim") + rbTree.put(13, "Shady") + rbTree.remove(9) + expectedResult = listOf(Pair(7, "hi"), Pair(12, "chka"), Pair(13, "Shady"), Pair(10, "name"), Pair(11, "Slim"), + Pair(4, "my"), Pair(5, "chka"), Pair(3, "is")) + } + + @Test + fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`(){ + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(3, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "Slim") + rbTree.put(11, "Shady") + rbTree.remove(9) + expectedResult = listOf(Pair(7, "hi"), Pair(11, "Shady"), Pair(12, "Slim"), Pair(10, "name"), Pair(4, "my"), + Pair(5, "chka"), Pair(3, "is")) + } + + @Test + fun `balance after remove - brother is right and black, both sons - black`(){ + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(9, "is") + rbTree.put(12, "Slim") + rbTree.put(11, "Shady") + rbTree.remove(11) + + //now vertexes with keys 9 and 12 are black + rbTree.remove(9) + + expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) + } + +// @Test +// fun `balance after remove - brother is red`(){ +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(3, "is") +// rbTree.put(9, "is") +// rbTree.put(12, "is") +// rbTree.put(11, "is") +// println(rbTree.getVertex(7)?.isRed) +// println(rbTree.getVertex(4)?.isRed) +// println(rbTree.getVertex(10)?.isRed) +// println(rbTree.getVertex(3)?.isRed) +// println(rbTree.getVertex(9)?.isRed) +// println(rbTree.getVertex(12)?.isRed) +// println(rbTree.getVertex(11)?.isRed) +// +// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Shady"), Pair(4, "my"), Pair(5, "chka"), +// Pair(3, "is")) +// } + + @Test + fun `balance after remove - brother is left and black, brother's rightSon - red`(){ + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "chka") + rbTree.put(1, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(5) + expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "chka"), Pair(9, "chka"), Pair(2, "is"), + Pair(4, "my"), Pair(3, "Shady"), Pair(1, "Slim")) + } + + @Test + fun `balance after remove - brother is left and black, brother's leftSon - red (rightSon - black)`(){ + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(5) + expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(9, "chka"), Pair(3, "Shady"), + Pair(4, "my"), Pair(2, "is")) + } + + @Test + fun `balance after remove - brother is left and black, both sons - black`(){ + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(3) + + //now vertexes with keys 2 and 5 are black + rbTree.remove(5) + + expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) } } \ No newline at end of file From dd45d9566950641f82411b3eb0c4531807736d44 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 05:59:10 +0300 Subject: [PATCH 123/227] dosc: add dosc to InterfaceBSTVertex --- lib/src/main/vertexes/InterfaceBSTVertex.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/src/main/vertexes/InterfaceBSTVertex.kt b/lib/src/main/vertexes/InterfaceBSTVertex.kt index 2a657b1..41b7e85 100644 --- a/lib/src/main/vertexes/InterfaceBSTVertex.kt +++ b/lib/src/main/vertexes/InterfaceBSTVertex.kt @@ -1,5 +1,15 @@ package main.vertexes +/** + * Represents a generic vertex in a Binary Search Tree (BST). + * @param K Type of keys. + * @param V Type of values. + * @param N Type of the child vertices. + * @property key The key associated with this vertex. + * @property value The value associated with this vertex. + * @property leftSon The left child vertex of this vertex, of type N. + * @property rightSon The right child vertex of this vertex, of type N. + */ interface InterfaceBSTVertex { var key: K var value: V From 764490309f8b9fb32afa2c2c34e6b395de6735bf Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 06:00:17 +0300 Subject: [PATCH 124/227] dosc: add dosc to AVLVertex --- lib/src/main/vertexes/AVLVertex.kt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/src/main/vertexes/AVLVertex.kt b/lib/src/main/vertexes/AVLVertex.kt index 291bc9a..7a19f4a 100644 --- a/lib/src/main/vertexes/AVLVertex.kt +++ b/lib/src/main/vertexes/AVLVertex.kt @@ -1,5 +1,16 @@ package main.vertexes +/** + * Represents a vertex in an AVL tree. + * @param K Type of keys. + * @param V Type of values. + * @property key The key associated with this vertex. + * @property value The value associated with this vertex. + * @property leftSon The left child vertex of this vertex, of type [AVLVertex]. + * @property rightSon The right child vertex of this vertex, of type [AVLVertex]. + * @property sonsHeightDiff The difference in height between the left and right subtrees. + */ + class AVLVertex( override var key: K, override var value: V @@ -7,8 +18,20 @@ class AVLVertex( override var leftSon: AVLVertex? = null override var rightSon: AVLVertex? = null + + /** + * The difference in height between the left and right subtrees. + */ var sonsHeightDiff: Int = 0 + /** + * Constructs a vertex with the specified key and value. + * @param key The key associated with this vertex. + * @param value The value associated with this vertex. + * @param leftSon The left child vertex of this vertex. + * @param rightSon The right child vertex of this vertex. + * @param sonsHeightDiff The difference in height between the left and right subtrees. + */ constructor( key: K, value: V, From 2ba91c0d367d79b9bcd6049de40ab808705fd88a Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 06:01:24 +0300 Subject: [PATCH 125/227] dosc: add dosc to RBVertex --- lib/src/main/vertexes/RBVertex.kt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/src/main/vertexes/RBVertex.kt b/lib/src/main/vertexes/RBVertex.kt index 2f1d9b0..9200e1a 100644 --- a/lib/src/main/vertexes/RBVertex.kt +++ b/lib/src/main/vertexes/RBVertex.kt @@ -1,5 +1,16 @@ package main.vertexes +/** + * Represents a vertex in a Red-Black Tree. + * @param K Type of keys. + * @param V Type of values. + * @property key The key associated with this vertex. + * @property value The value associated with this vertex. + * @property isRed A boolean indicating whether this vertex is red. + * @property parent The parent vertex of this vertex. + * @property leftSon The left child vertex of this vertex. + * @property rightSon The right child vertex of this vertex. + */ class RBVertex( override var key: K, override var value: V @@ -10,6 +21,15 @@ class RBVertex( override var leftSon: RBVertex? = null override var rightSon: RBVertex? = null + /** + * Creates a new RBVertex with the specified parameters. + * @param key The key associated with this vertex. + * @param value The value associated with this vertex. + * @param leftSon The left child vertex of this vertex. + * @param rightSon The right child vertex of this vertex. + * @param isRed A boolean indicating whether this vertex is red. + * @param parent The parent vertex of this vertex. + */ constructor( key: K, value: V, From 92585b3415963829bd4182b567c6725365627cf8 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 06:01:51 +0300 Subject: [PATCH 126/227] dosc: add dosc to SimpleBSTVertex --- lib/src/main/vertexes/SimpleBSTVertex.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/src/main/vertexes/SimpleBSTVertex.kt b/lib/src/main/vertexes/SimpleBSTVertex.kt index 2e76767..46027d3 100644 --- a/lib/src/main/vertexes/SimpleBSTVertex.kt +++ b/lib/src/main/vertexes/SimpleBSTVertex.kt @@ -1,5 +1,14 @@ package main.vertexes +/** + * Represents a simple vertex in a Binary Search Tree. + * @param K Type of keys. + * @param V Type of values. + * @property key The key associated with this vertex. + * @property value The value associated with this vertex. + * @property leftSon The left child vertex of this vertex, of type SimpleBSTVertex. + * @property rightSon The right child vertex of this vertex, of type SimpleBSTVertex. + */ class SimpleBSTVertex( override var key: K, override var value: V @@ -8,6 +17,13 @@ class SimpleBSTVertex( override var leftSon: SimpleBSTVertex? = null override var rightSon: SimpleBSTVertex? = null + /** + * Constructs a simple vertex with the specified key and value. + * @param key The key associated with this vertex. + * @param value The value associated with this vertex. + * @param leftSon The left child vertex of this vertex. + * @param rightSon The right child vertex of this vertex. + */ constructor( key: K, value: V, From 1bdc476a6852dc06ccfb171027bb8b6a409d1362 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 06:03:35 +0300 Subject: [PATCH 127/227] dosc: add dosc to AbstractBinarySearchTree --- .../main/trees/AbstractBinarySearchTree.kt | 111 +++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index d88c536..8b6785b 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -2,60 +2,143 @@ package main.trees import main.vertexes.InterfaceBSTVertex import main.iterator.TreeIterator +/** + * An abstract class representing a binary search tree. + * @param K The type of keys. + * @param V The type of values. + * @param N The type of vertices implementing the [InterfaceBSTVertex] interface. + * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. + * @property size The number of elements in the tree. + * @property root The root vertex of the tree. + */ abstract class AbstractBinarySearchTree> { + /** Comparator used for comparing keys. */ protected var comparator: Comparator? = null + + /** The number of elements in the tree. */ protected var size : Long = 0L + + /** The root vertex of the tree. */ protected var root : N? = null + /** + * Returns an iterator over the elements in this tree in proper sequence. + * @return an iterator over the elements in this tree in proper sequence + */ operator fun iterator(): Iterator> { return TreeIterator(root) } + /** + * Returns the number of key-value pairs in this tree. + * @return the number of key-value pairs in this tree + */ fun size(): Long {return size} + /** + * Returns true if this tree contains no key-value pairs. + * @return true if this tree contains no key-value pairs + */ fun isEmpty(): Boolean {return size == 0L} - + + /** + * Returns the value associated with the specified key in this tree. + * If the key is not found, returns null. + * @param key the key whose associated value is to be returned + * @return the value associated with the specified key, or null if the key is not found + */ fun get(key: K): V? {return getRec(key)} + /** + * Returns a Pair containing the specified key-value mapping, if found. + * If the key is not found, returns null. + * @param key the key whose associated value is to be returned + * @return a Pair containing the specified key-value mapping, or null if the key is not found + */ fun getPair(key: K): Pair? { val value = get(key) return if (value == null) null else Pair(key, value) } + /** + * Returns the minimum value in the tree, or null if the tree is empty. + * @return the minimum value in the tree, or null if the tree is empty + */ fun getMin(): V? { val minKeyNode = getMinKeyNodeRec() return if (minKeyNode == null) null else minKeyNode.value } + /** + * Returns the maximum value in the tree, or null if the tree is empty. + * @return the maximum value in the tree, or null if the tree is empty + */ fun getMax(): V?{ val maxKeyNode = getMaxKeyNodeRec() return if (maxKeyNode == null) null else maxKeyNode.value } + /** + * Returns a Pair containing the minimum key-value mapping in the tree, or null if the tree is empty. + * @return a Pair containing the minimum key-value mapping in the tree, or null if the tree is empty + */ fun getMinKeyPair(): Pair? { val minKeyNode = getMinKeyNodeRec() return if (minKeyNode == null) null else Pair(minKeyNode.key, minKeyNode.value) } + /** + * Returns a Pair containing the maximum key-value mapping in the tree, or null if the tree is empty. + * @return a Pair containing the maximum key-value mapping in the tree, or null if the tree is empty + */ fun getMaxKeyPair(): Pair? { val maxKeyNode = getMaxKeyNodeRec() return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) } + /** + * Associates the specified value with the specified key in this tree. + * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. + * @param key the key with which the specified value is to be associated + * @param value the value to be associated with the specified key + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + */ abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) + /** + * Put all of the pairs from the specified map to this tree. + * If parameter replaceIfExists is true and a key already exists, the value is replaced; otherwise, the value is ignored. + * @param map the map whose mappings are to be added to this tree + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + */ fun putAll(map: Map, replaceIfExists: Boolean = true) { for (pair in map) put(pair.key, pair.value, replaceIfExists) } + /** + * Removes the mapping for a key from this tree if it is present. + * @param key the key whose mapping is to be removed from the tree + * @return the previous value associated with key, or null if there was no mapping for key + */ abstract fun remove(key: K): V? + /** + * Removes the mapping for a key from this tree if it is present, and returns it as a Pair. + * @param key the key whose mapping is to be removed from the tree + * @return a Pair containing the removed key-value mapping, or null if the key was not found + */ fun removeAndReturnPair(key: K): Pair? { val value = remove(key) return if (value == null) null else Pair(key, value) } + /** + * Recursively searches for the value associated with the specified key. + * @param key the key to search for + * @param vertex the current vertex being examined + * @return the value associated with the specified key, or null if not found + */ private fun getRec(key: K, vertex: N? = root): V? { if (vertex == null) return null return when (compareKeys(key, vertex.key)) { @@ -65,6 +148,11 @@ abstract class AbstractBinarySearchTree> { } } + /** + * Recursively finds the vertex with the minimum key in the tree. + * @param vertex the current vertex being examined + * @return the vertex with the minimum key in the tree, or null if the tree is empty + */ protected fun getMinKeyNodeRec(vertex: N? = root) : N? { if (vertex == null) return null else { @@ -73,6 +161,11 @@ abstract class AbstractBinarySearchTree> { } } + /** + * Recursively finds the vertex with the maximum key in the tree. + * @param vertex the current vertex being examined + * @return the vertex with the maximum key in the tree, or null if the tree is empty + */ protected fun getMaxKeyNodeRec(vertex: N? = root) : N? { if (vertex == null) return null else { @@ -81,6 +174,12 @@ abstract class AbstractBinarySearchTree> { } } + /** + * Compares two keys. + * @param firstKey the first key to compare + * @param secondKey the second key to compare + * @return -1 if the first key is less than the second key, 0 if they are equal, or 1 if the first key is greater than the second key + */ protected fun compareKeys(firstKey: K, secondKey: K): Int{ val cpr = comparator return if (cpr != null) { @@ -101,10 +200,20 @@ abstract class AbstractBinarySearchTree> { } } + /** + * Constructs a new binary search tree with the specified comparator. + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor(comparator: Comparator? = null) { this.comparator = comparator } + /** + * Constructs a new binary search tree and initializes it with the mappings from the specified map. + * @param map the map whose mappings are to be added to this tree + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) { this.comparator = comparator putAll(map, replaceIfExists) From 47ef5ce82fe048f1914d1896b737ab37d72c0768 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 06:05:09 +0300 Subject: [PATCH 128/227] dosc: add dosc to SimpleBinarySearchTree --- lib/src/main/trees/SimpleBinarySearchTree.kt | 51 ++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 71259a0..21fb621 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -1,13 +1,64 @@ package main.trees import main.vertexes.SimpleBSTVertex +/** + * This class represents a simple implementation of a binary search tree. + * It extends AbstractBinarySearchTree and uses SimpleBSTVertex as vertices. + * @param K The type of keys in the tree. + * @param V The type of values in the tree. + * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. + * @property size The number of elements in the tree. + * @property root The root vertex of the tree. + */ class SimpleBinarySearchTree : AbstractBinarySearchTree> { + /** + * Associates the specified value with the specified key in this tree. + * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. + * @param key the key with which the specified value is to be associated + * @param value the value to be associated with the specified key + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + */ override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} + /** + * Recursively inserts a key-value pair into the tree. + * @param key The key to insert. + * @param value The value associated with the key. + * @param replaceIfExists If true, replaces the existing value for the key. + * @param vertex The current vertex in the recursion. + */ + + /** + * Removes the key-value pair associated with the specified key from the tree. + * @param key The key to remove. + * @return The value associated with the removed key, or null if the key is not found. + */ override fun remove(key: K): V? {TODO()} + /** + * Recursively removes the key-value pair associated with the specified key from the tree. + * This method traverses the tree recursively to find the node with the given key and removes it. + * If the key is found and the corresponding node has both left and right children, + * the method replaces the node's key and value with those of the minimum key node in its right subtree, + * and then removes the minimum key node from the right subtree. + * If the key is not found, it returns a pair containing the vertex and null value. + * @param key The key to remove. + * @param vertex The current vertex being examined in the recursion. + * @return A pair containing the updated vertex and the value associated with the removed key, or null if the key is not found. + */ + + /** + * Constructs a new binary search tree with the specified comparator. + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor(comparator: Comparator?) : super(comparator) + /** + * Constructs a new binary search tree and initializes it with the mappings from the specified map. + * @param map the map whose mappings are to be added to this tree + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } From 91a13ef5487d9f48a80c1e089ac7cf88300df654 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 06:07:16 +0300 Subject: [PATCH 129/227] dosc: add dosc to AVLSearchTree --- lib/src/main/trees/AVLSearchTree.kt | 134 +++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 12 deletions(-) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index c8d55db..49b7f77 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -1,8 +1,25 @@ package main.trees import main.vertexes.AVLVertex +/** + * An implementation of a binary search tree that automatically balances itself using AVL rotations. + * It extends AbstractBinarySearchTree and uses AVLVertex as vertices. + * This class extends AbstractBinarySearchTree and provides methods to put, remove for key-value pairs. + * @param K the type of keys in the tree + * @param V the type of values associated with the keys + * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. + * @property size The number of elements in the tree. + * @property root The root vertex of the tree. + */ class AVLSearchTree : AbstractBinarySearchTree> { + /** + * Associates the specified value with the specified key in this tree. + * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. + * @param key the key with which the specified value is to be associated + * @param value the value to be associated with the specified key + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + */ override fun put(key: K, value: V, replaceIfExists: Boolean) { if (!isEmpty()) { when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { @@ -15,6 +32,14 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ } + /** + * Associates the specified value with the specified key in this tree. + * If replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. + * @param key the key with which the specified value is to be associated + * @param value the value to be associated with the specified key + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * @return the root vertex of the tree after the operation + */ private fun putRec(key: K, value: V, replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { fun putRecShort(vrtx : AVLVertex) : AVLVertex? { @@ -74,7 +99,12 @@ class AVLSearchTree : AbstractBinarySearchTree> { } } } - + + /** + * Removes the mapping for a key from this tree if it is present. + * @param key the key whose mapping is to be removed from the tree + * @return the previous value associated with key, or null if there was no mapping for key + */ override fun remove(key: K): V? { if (!isEmpty()) { val removeRecReturned = removeRec(key, root as AVLVertex) @@ -91,19 +121,55 @@ class AVLSearchTree : AbstractBinarySearchTree> { return null } - enum class RemovalStage {A, B, C} - // a - don't need tree changes anymore - // b - probably need some tree changes, but not nulling - // c - need to null due "Son" property of (if exists) the parent of removed vertex + b + /** + * An enumeration representing different stages of removal during the removal process. + */ + enum class RemovalStage { + /** + * Don't need tree changes anymore + */ + A, + + /** + * Probably need some tree changes, but not nulling + */ + B, + + /** + * Need to null due "Son" property of (if exists) the parent of removed vertex + b + */ + C + } + /** + * Recursively removes a key-value pair from the subtree rooted at the given vertex. + * @param key the key to remove + * @param vertex the root of the subtree to remove from + * @return Triple that consists of: + * + * 1) removal stage; + * + * 2) if RemovalStage == a : just a vertex (don't need it later); + * + * if RemovalStage == b : the root of the changed subtree; + * + * if RemovalStage == c : the removed vertex; + * + * 3) a value of the removed vertex (or null if key not exists). */ private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { + + /** + * Triple consists of: + * + * 1) removal stage; + * + * 2) if RemovalStage == a : just a vertex (don't need it later); + * if RemovalStage == b : the root of the changed subtree; + * if RemovalStage == c : the removed vertex; + * + * 3) a value of the removed vertex (or null if key not exists). + */ val nextCallReturned : Triple ?, V?> - // Triple consists of: - // 1) removal stage - // 2) if RemovalStage == a : just a vertex (don't need it later) - // if RemovalStage == b : the root of the changed subtree - // if RemovalStage == c : the removed vertex - // 3) a value of the removed vertex (or null if key not exists) when (compareKeys(key, vertex.key)) { -1 -> { if (vertex.leftSon == null) return Triple(RemovalStage.A, vertex, null) @@ -180,6 +246,11 @@ class AVLSearchTree : AbstractBinarySearchTree> { } } + /** + * Prepares the largest lower vertex to replace the specified vertex. + * @param vertex the vertex to be replaced + * @return the substitute vertex prepared to replace the specified vertex + */ private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex? { val substitute = getMaxKeyNodeRec(vertex.leftSon) if (substitute == null) return null @@ -190,6 +261,11 @@ class AVLSearchTree : AbstractBinarySearchTree> { return substitute } + /** + * Balances the tree starting from the specified vertex. + * @param curVertex the current vertex to start balancing from + * @return the root vertex of the tree after balancing + */ private fun balance(curVertex: AVLVertex) : AVLVertex { var (rightSon, leftSon) = List?>(2){null} fun setTwoSonHeightDiffs(values : Pair) { @@ -250,31 +326,65 @@ class AVLSearchTree : AbstractBinarySearchTree> { } } + /** + * Performs a single left rotation around the specified vertices. + * @param curVertex the current vertex to rotate around + * @param rightSon the right son vertex + * @return the new root vertex after rotation + */ private fun rotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex return rightSon } + /** + * Performs a single right rotation around the specified vertices. + * @param curVertex the current vertex to rotate around + * @param leftSon the left son vertex + * @return the new root vertex after rotation + */ private fun rotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { curVertex.leftSon = leftSon.rightSon leftSon.rightSon = curVertex return leftSon } - + + /** + * Performs a big left rotation around the specified vertices. + * @param curVertex the current vertex to rotate around + * @param rightSon the right son vertex + * @return the new root vertex after rotation + */ private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) curVertex.rightSon = curRightSon return rotateLeft(curVertex, curRightSon) } + /** + * Performs a big right rotation around the specified vertices. + * @param curVertex the current vertex to rotate around + * @param leftSon the left son vertex + * @return the new root vertex after rotation + */ private fun bigRotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) curVertex.leftSon = curLeftSon return rotateRight(curVertex, curLeftSon) } + /** + * Constructs a new binary search tree with the specified comparator. + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor (comparator: Comparator? = null) : super(comparator) + /** + * Constructs a new binary search tree and initializes it with the mappings from the specified map. + * @param map the map whose mappings are to be added to this tree + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } From fe0576a84f830ffbfc44e2079a4c6bf884b47fc8 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 06:10:42 +0300 Subject: [PATCH 130/227] dosc: add dosc to RBSearchTree --- lib/src/main/trees/RBSearchTree.kt | 169 ++++++++++++++++++++--------- 1 file changed, 118 insertions(+), 51 deletions(-) diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index e9546a3..6c0d196 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -1,21 +1,45 @@ package main.trees import main.vertexes.RBVertex +/** + * Red-Black Tree implementation. It extends AbstractBinarySearchTree and uses RBVertex as vertices. + * Red-Black Tree is a balanced binary search tree, where each vertex is colored either red or black. + * This implementation ensures the following properties: + * + * - Every vertex is either red or black. + * - The root is black. + * - Every leaf (NIL) is black. + * - If a vertex is red, then both its children are black. + * - Every simple path from a vertex to a descendant leaf (NIL) has the same number of black vertexes. + * @param K the type of keys in the tree + * @param V the type of values associated with the keys + * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. + * @property size The number of elements in the tree. + * @property root The root vertex of the tree. + */ class RBSearchTree : AbstractBinarySearchTree> { - //4 cases we need to look at - //1) remove red vertex with 0 children -> just remove vetrex - - //2) remove red or black vertex with 2 children -> - //find min vertex on the right subtree and swap it's key and value with - //key and value of vertex that we need to remove - //Now we can work with vertex which has 1 or 0 children - - //3) remove black vetrex with 1 child -> child can be only red - //so we just swap child's key and value with key and value that we need to remove - //and look at case 1) - - //4) remove black vertex with 0 children -> just remove vertex + /** + * This method removes the vertex with the given key from the tree and returns its associated value, + * maintaining the properties of the red-black tree. + * + * 4 cases we need to look at: + * + * 1) remove red vertex with 0 children -> just remove vetrex + * + * 2) remove red or black vertex with 2 children -> + * find min vertex on the right subtree and swap it's key and value with + * key and value of vertex that we need to remove. + * Now we can work with vertex which has 1 or 0 children + * + * 3) remove black vetrex with 1 child -> child can be only red + * so we just swap child's key and value with key and value that we need to remove + * and look at case 1) + * + * 4) remove black vertex with 0 children -> just remove vertex + * @param key the key of the vertex to be removed + * @return the value associated with the removed vertex, or null if the key is not found + */ override fun remove(key: K): V? { val vertex: RBVertex = getVertex(key) ?: return null val value = vertex.value @@ -43,24 +67,26 @@ class RBSearchTree : AbstractBinarySearchTree> { return value } - //we need to balance tree after removal black vertex with 0 children - //in this fun we need to look at vertex's parent and brother - - //1) brother is black and brother's rightSon is red -> we paint - //brother in parent's color, parent and brother's rightSon in black - //then rotate left - - //2) brother is black and brother's leftSon is red (rightSon - black) -> - //we swap colors of brother and brother's leftSon and rotate right - //then look at case 1 - - //3) brother is black and both sons are black -> we make brother red - //then we need to launch algorithm from the parent because of it - //can be red, so we have red parent and red son or black so - //the black height of all subtree decreased - - //4) brother is red -> make brother black, parent red and - //rotate left. We move conflict on level below, then we look at the previous cases + /** + * We need to balance tree after removal black vertex with 0 children. + * In this fun we need to look at vertex's parent and brother: + * 1) brother is black and brother's rightSon is red -> we paint + * brother in parent's color, parent and brother's rightSon in black + * then rotate left + * + * 2) brother is black and brother's leftSon is red (rightSon - black) -> + * we swap colors of brother and brother's leftSon and rotate right + * then look at case 1 + * + * 3) brother is black and both sons are black -> we make brother red + * then we need to launch algorithm from the parent because of it + * can be red, so we have red parent and red son or black so + * the black height of all subtree decreased + * + * 4) brother is red -> make brother black, parent red and + * rotate left. We move conflict on level below, then we look at the previous cases + * @param vertex The child vertex of the removed vertex or null if the removed vertex had no children. + */ private fun balanceAfterRemove(vertex: RBVertex?){ var currentVertex = vertex while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)){ @@ -138,8 +164,11 @@ class RBSearchTree : AbstractBinarySearchTree> { currentVertex?.isRed = false } - //finds vertex by corresponding key - //if such vertex doesn't exist returns null + /** + * Finds a vertex by corresponding key. If such vertex doesn't exist returns null. + * @param key The key to search for. + * @return The vertex with the corresponding key, or null if such vertex doesn't exist. + */ private fun getVertex(key: K): RBVertex? { var currentVertex: RBVertex? = root @@ -157,8 +186,13 @@ class RBSearchTree : AbstractBinarySearchTree> { return currentVertex } - //finds free place and inserts newVertex, colors it in red - //if vertex with such key exists, replaces it + /** + * Finds free place and inserts newVertex, colors it in red. + * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. + * @param key the key with which the specified value is to be associated + * @param value the value to be associated with the specified key + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + */ override fun put(key: K, value: V, replaceIfExists: Boolean) { var currentVertex: RBVertex? = root var parent: RBVertex? = null @@ -192,18 +226,20 @@ class RBSearchTree : AbstractBinarySearchTree> { balanceAfterPut(currentVertex) } - //we need to balance tree in two cases - //1) when newVertex is root, so our root is red - //2) when parent of our newVertex is red(because newVertex is also red) - - //in first case we just make the root black - //in second case we need to look at the newVertex's uncle - - //if uncle is red, we make it black and newVertex's parent black and grandparent red - //launch algorithm to grandfather because now it's color changed to red - - //if uncle is black we also make newVertex's parent black, grandparent red - //and rotate it right + /** + * Balances the tree after inserting a new vertex. + * We need to balance tree in two cases: + * 1) when newVertex is root, so our root is red + * 2) when parent of our newVertex is red(because newVertex is also red) + * + * in first case we just make the root black + * in second case we need to look at the newVertex's uncle + * if uncle is red, we make it black and newVertex's parent black and grandparent red + * launch algorithm to grandfather because now it's color changed to red + * if uncle is black we also make newVertex's parent black, grandparent red + * and rotate it right + * @param vertex The newly inserted vertex. + */ private fun balanceAfterPut(vertex: RBVertex) { var currentVertex = vertex @@ -259,6 +295,11 @@ class RBSearchTree : AbstractBinarySearchTree> { root?.isRed = false } + /** + * Counts the number of children of the given vertex. + * @param vertex The vertex whose children count is to be determined. + * @return The number of children of the given vertex. + */ private fun countChildren(vertex: RBVertex): Int { var numOfChild = 0 if (vertex.leftSon != null) ++numOfChild @@ -266,8 +307,18 @@ class RBSearchTree : AbstractBinarySearchTree> { return numOfChild } + /** + * Retrieves the child vertex of the given vertex. + * @param vertex The vertex whose child is to be retrieved. + * @return The child vertex of the given vertex. + */ private fun getChild(vertex: RBVertex) = if (vertex.leftSon != null) vertex.leftSon else vertex.rightSon + /** + * Replaces the old vertex with the new vertex in the tree structure. + * @param oldVertex The old vertex to be replaced. + * @param newVertex The new vertex that replaces the old vertex. + */ private fun replaceVertexBy(oldVertex: RBVertex, newVertex: RBVertex?){ if (root == oldVertex) root = newVertex else if (oldVertex == oldVertex.parent?.leftSon) oldVertex.parent?.leftSon = newVertex @@ -275,8 +326,11 @@ class RBSearchTree : AbstractBinarySearchTree> { newVertex?.parent = oldVertex.parent } - //suppose that vertex has a rightSon - //swap parent and rightSon, rightSon's leftSon becomes parent's rightSon + /** + * Performs a left rotation on the given vertex. + * Suppose that vertex has a rightSon. Swap parent and rightSon, rightSon's leftSon becomes parent's rightSon. + * @param vertex The vertex on which the left rotation is to be performed. + */ private fun rotateLeft(vertex: RBVertex) { val rightVertex: RBVertex? = vertex.rightSon vertex.rightSon = rightVertex?.leftSon @@ -291,8 +345,11 @@ class RBSearchTree : AbstractBinarySearchTree> { rightVertex?.leftSon = vertex } - //suppose that vertex has a leftSon - //swap parent and leftSon, leftSon's rightSon becomes parent's leftSon + /** + * Performs a right rotation on the given vertex. + * Suppose that vertex has a leftSon. Swap parent and leftSon, leftSon's rightSon becomes parent's leftSon. + * @param vertex The vertex on which the right rotation is to be performed. + */ private fun rotateRight(vertex: RBVertex) { val leftVertex: RBVertex? = vertex.leftSon vertex.leftSon = leftVertex?.rightSon @@ -307,7 +364,17 @@ class RBSearchTree : AbstractBinarySearchTree> { leftVertex?.rightSon = vertex } + /** + * Constructs a new binary search tree with the specified comparator. + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor(comparator: Comparator? = null) : super(comparator) + /** + * Constructs a new binary search tree and initializes it with the mappings from the specified map. + * @param map the map whose mappings are to be added to this tree + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } From 8014d7ab5354d1f82d2f983a178231b7d6318049 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 06:12:01 +0300 Subject: [PATCH 131/227] dosc: add dosc to TreeIterator --- lib/src/main/iterator/TreeIterator.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/src/main/iterator/TreeIterator.kt b/lib/src/main/iterator/TreeIterator.kt index bad1c15..91a8c29 100644 --- a/lib/src/main/iterator/TreeIterator.kt +++ b/lib/src/main/iterator/TreeIterator.kt @@ -2,19 +2,38 @@ package main.iterator import main.vertexes.InterfaceBSTVertex import java.util.LinkedList +/** + * Iterator iterates over the vertices of the tree, visiting each vertex in the order of a depth-first traversal. + * Iterator interface implementation. + * @param K the type of keys in the tree + * @param V the type of values associated with the keys + * @param N the type of tree vertices implementing InterfaceBSTVertex + */ internal class TreeIterator>( vertex: N? ): Iterator> { + // Stack to store vertices for traversal private val stack = LinkedList() init { + // Initialize the iterator with the given vertex by adding it to the stack vertex?.let { stack.add(it) } } + /** + * Returns true if the iterator has more elements. + * This method checks if there are more vertices to traverse in the tree. + * @return true if the iterator has more elements, otherwise false + */ override fun hasNext(): Boolean { return stack.isNotEmpty() } + /** + * Returns the next element in the iteration. + * This method returns the next vertex in the depth-first traversal of the tree. + * @return the next element in the iteration as a Pair containing the key and value of the vertex + */ override fun next(): Pair { val nextVertex: N = stack.removeLast() nextVertex.leftSon?.let { stack.add(it) } From b300cf44fa429d117ff22b67b8d4d0c7c5238ae9 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 07:36:50 +0300 Subject: [PATCH 132/227] feat: add project structure and contributing in README.md --- README.md | 129 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index f9a0179..e11f170 100644 --- a/README.md +++ b/README.md @@ -2,30 +2,31 @@ badge badge

-# BinTreeKit +## BinTreeKit -## Table of Contents +### Table of Contents - [About Project](#about-project) - [Usage](#usage) +- [Project Structure](#project-structure) - [Developers and Contacts](#developers-and-contacts) +- [Contributing](#contributing) - [License](#license) -[//]: # (- [Project Structure](#project-structure)) - -## About Project +### About Project `BinTreeKit` is a library that provides implementations for three types of trees: `SimpleBinarySearchTree`, `AVLSearchTree` and `RBSearchTree`. The library is designed to simplify the process of managing hierarchical data, allowing Kotlin developers to focus on building robust and scalable applications. -## Usage -### 1. **Importing Classes**: +### Usage +1. Importing Classes: ```kotlin import main.trees.SimpleBinarySearchTree import main.trees.AVLSearchTree import main.trees.RBSearchTree ``` -### 2. **Instantiate Trees**: + +2. Instantiate Trees: ```kotlin // create a Simple Binary Search Tree val bstTree = SimpleBinarySearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) @@ -36,7 +37,8 @@ val avlTree = AVLSearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) // create a Red-Black Search Tree val rbTree = RBSearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) ``` -### 3. **Use Tree Methods**: + +3. Use Tree Methods: ```kotlin // put key-value pairs with different values of replaceIfExists perematers bstTree.putAll(mapOf(Pair(2, "hamster"), Pair(3, "bird")), true) @@ -53,82 +55,107 @@ for (pair in avlTree) { ``` -[//]: # (## Project Structure) +### Project Structure -## Developers and Contacts -- [vicitori](https://github.com/vicitori) - Victoria Lutsyuk (Simple Binary Search Tree) -- [Szczucki](https://github.com/Szczucki) - Nikita Shchutskii (AVL Search Tree) -- [TerrMen](https://github.com/TerrMen) - Kostya Oreshin (RB Search Tree) +#### Constructors +- `constructor(comparator: Comparator? = null)` - constructs a new AbstractBinarySearchTree instance with the given comparator. -Project Link: [trees-9](https://github.com/spbu-coding-2023/trees-9.git) +- `constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null)` - constructs a new AbstractBinarySearchTree instance initialized with the contents of the given map. -## License -This project uses the **APACHE LICENSE, VERSION 2.0**. See the [LICENSE](LICENSE.md) for more info. + The `comparator` to be used optional for ordering keys in the tree. -[//]: # (## How to Use ) -[//]: # (___) +#### Methods -[//]: # (To use the Tree Library in your Kotlin project, follow these steps:) +- put -[//]: # (1. **Add Dependency**: Add the Tree Library as a dependency in your `build.gradle.kts` file:) + - `put(key: K, value: V, replaceIfExists : Boolean = true)` - inserts the specified key-value pair into the tree. -[//]: # ( ```kotlin) + - `putAll(map: Map, replaceIfExists: Boolean = true)` - inserts all key-value pairs from the given map into the tree. -[//]: # ( dependencies {) + replaceIfExists is an optional (default is true) Boolean flag indicating whether to replace the value if the key already exists in the tree. -[//]: # ( implementation("com.example:tree-library:1.0.0")) -[//]: # ( }) +- remove -[//]: # (2. **Import Classes**: Import the necessary classes from the library into your Kotlin files:) + - `remove(key: K): V?` - removes the key-value pair with the specified key from the tree and returns value associated with the removed key, or `null` if the key was not found in the tree. -[//]: # ( ```kotlin) -[//]: # ( import main.trees.*) +- get -[//]: # ( import main.vertexes.InterfaceBSTVertex) + - `get(key: K): V?` - retrieves the value associated with the specified key from the tree and returns value associated with the specified key, or `null` if the key was not found in the tree. -[//]: # ( import main.iterator.TreeIterator) + - `getPair(key: K): Pair?` - retrieves the key-value pair associated with the specified key from the tree and returns the key-value pair associated with the specified key, or `null` if the key was not found in the tree. -[//]: # (3. **Instantiate Trees**: Create instances of the tree structures provided by the library, such as Simple Binary Search Tree, AVL Tree, or Red-Black Tree.) + - `getMin(): V?` - retrieves the value associated with the minimum key in the tree and returns the value associated with the minimum key, or `null` if the tree is empty. -[//]: # ( ```kotlin) + - `getMax(): V?` - retrieves the value associated with the maximum key in the tree and returns the value associated with the maximum key, or `null` if the tree is empty. -[//]: # ( // Create a Simple Binary Search Tree) + - `getMinKeyPair(): Pair?` - retrieves the key-value pair associated with the minimum key in the tree and returns the key-value pair associated with the minimum key, or `null` if the tree is empty. -[//]: # ( val bst = SimpleBinarySearchTree()) + - `getMaxKeyPair(): Pair?` - retrieves the key-value pair associated with the maximum key in the tree and returns the key-value pair associated with the maximum key, or `null` if the tree is empty. -[//]: # (4. **Use Tree Methods**: Utilize the methods provided by the tree classes to insert, remove, search, and traverse tree elements according to your application requirements.) -[//]: # ( ```kotlin) +- others -[//]: # ( // Insert key-value pairs) + - `size(): Long` - returns the number of key-value pairs in the tree. -[//]: # ( bst.put(5, "Five")) + - `isEmpty(): Boolean` checks whether the tree is empty and returns `true` if the tree is empty, `false` otherwise. -[//]: # ( bst.put(3, "Three")) -[//]: # ( bst.put(7, "Seven")) +#### Tree Properties -[//]: # ( ) -[//]: # ( // Retrieve values) +- `size: Long` - the number of key-value pairs currently stored in the tree. -[//]: # ( println(bst.get(3)) // Output: Three) -[//]: # ( ) -[//]: # ( // Remove a key-value pair) +- `isEmpty: Boolean` - indicates whether the tree is empty. -[//]: # ( bst.remove(3)) -[//]: # ( ) -[//]: # ( // Iterate over tree elements) +#### Iterator +###### Constructors +- `constructor(vertex: N?)` - constructs a new TreeIterator instance with the specified starting vertex. -[//]: # ( for ((key, value) in bst) {) + vertex is the starting vertex of the iterator. -[//]: # ( println("Key: $key, Value: $value")) +###### Methods -[//]: # ( }) \ No newline at end of file +- `hasNext(): Boolean` - checks if there are more elements in the iteration and returns `true` if there are more elements, `false` otherwise. + + +- `next(): Pair` - retrieves the next key-value pair in the iteration and returns the next key-value pair in the iteration. + + +### Developers +- [vicitori](https://github.com/vicitori) - Victoria Lutsyuk (Simple Binary Search Tree) +- [Szczucki](https://github.com/Szczucki) - Nikita Shchutskii (AVL Search Tree) +- [TerrMen](https://github.com/TerrMen) - Kostya Oreshin (RB Search Tree) + + +### Contributing + +**Quick start** + +1. Create new branch branching off `develop`, name it as feature you want to implement +```bash +git checkout develop +git switch -c my_feature +``` + +2. Commit the changes and write messages according to [commits convention](https://www.conventionalcommits.org/en/v1.0.0/) +```bash +git commit -m "feat: implement new feature" +``` + +3. Push changes to a remote repository +```bash +git push origin my_feature +``` + +4. Open pull request to `develop` + + +### License +This project uses the **APACHE LICENSE, VERSION 2.0**. See the [LICENSE](LICENSE.md) for more info. From c0c8792685ffbf6a76709048716f1b80b8d45a93 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 07:52:10 +0300 Subject: [PATCH 133/227] refactor: change text size and rename title 'Project Structure' to 'Library Features' in README.md --- README.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e11f170..48f976c 100644 --- a/README.md +++ b/README.md @@ -2,31 +2,37 @@ badge badge

-## BinTreeKit +# BinTreeKit -### Table of Contents +## Table of Contents - [About Project](#about-project) - [Usage](#usage) -- [Project Structure](#project-structure) -- [Developers and Contacts](#developers-and-contacts) +- [Library Features](#library-features) + - [Constructors](#constructors) + - [Methods](#methods) + - [Tree Properties](#tree-properties) + - [Iterator](#iterator) + - [Constructors](#constructors-1) + - [Methods](#methods-1) +- [Developers](#developers) - [Contributing](#contributing) - [License](#license) -### About Project +## About Project `BinTreeKit` is a library that provides implementations for three types of trees: `SimpleBinarySearchTree`, `AVLSearchTree` and `RBSearchTree`. The library is designed to simplify the process of managing hierarchical data, allowing Kotlin developers to focus on building robust and scalable applications. -### Usage -1. Importing Classes: +## Usage +1. **Importing Classes:** ```kotlin import main.trees.SimpleBinarySearchTree import main.trees.AVLSearchTree import main.trees.RBSearchTree ``` -2. Instantiate Trees: +2. **Instantiate Trees:** ```kotlin // create a Simple Binary Search Tree val bstTree = SimpleBinarySearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) @@ -38,7 +44,7 @@ val avlTree = AVLSearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) val rbTree = RBSearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) ``` -3. Use Tree Methods: +3. **Use Tree Methods:** ```kotlin // put key-value pairs with different values of replaceIfExists perematers bstTree.putAll(mapOf(Pair(2, "hamster"), Pair(3, "bird")), true) @@ -55,7 +61,7 @@ for (pair in avlTree) { ``` -### Project Structure +## Library Features #### Constructors @@ -128,13 +134,13 @@ for (pair in avlTree) { - `next(): Pair` - retrieves the next key-value pair in the iteration and returns the next key-value pair in the iteration. -### Developers +## Developers - [vicitori](https://github.com/vicitori) - Victoria Lutsyuk (Simple Binary Search Tree) - [Szczucki](https://github.com/Szczucki) - Nikita Shchutskii (AVL Search Tree) - [TerrMen](https://github.com/TerrMen) - Kostya Oreshin (RB Search Tree) -### Contributing +## Contributing **Quick start** @@ -157,5 +163,5 @@ git push origin my_feature 4. Open pull request to `develop` -### License +## License This project uses the **APACHE LICENSE, VERSION 2.0**. See the [LICENSE](LICENSE.md) for more info. From 1ed29b35258947fb94452b3a4fcd024dbb824dc0 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 10:04:58 +0300 Subject: [PATCH 134/227] fix: do class TreeIterator open and do stack protected --- lib/src/main/kotlin/iterator/TreeIterator.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/main/kotlin/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt index bad1c15..8324535 100644 --- a/lib/src/main/kotlin/iterator/TreeIterator.kt +++ b/lib/src/main/kotlin/iterator/TreeIterator.kt @@ -2,10 +2,10 @@ package main.iterator import main.vertexes.InterfaceBSTVertex import java.util.LinkedList -internal class TreeIterator>( +open class TreeIterator>( vertex: N? ): Iterator> { - private val stack = LinkedList() + protected val stack = LinkedList() init { vertex?.let { stack.add(it) } From 376bec6e182723c3d203cb615b55f657914886e3 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 10:06:01 +0300 Subject: [PATCH 135/227] feat: write class TestIterator for test --- lib/src/test/kotlin/TestIterator.kt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 lib/src/test/kotlin/TestIterator.kt diff --git a/lib/src/test/kotlin/TestIterator.kt b/lib/src/test/kotlin/TestIterator.kt new file mode 100644 index 0000000..18727a6 --- /dev/null +++ b/lib/src/test/kotlin/TestIterator.kt @@ -0,0 +1,7 @@ +import main.vertexes.InterfaceBSTVertex +import main.iterator.TreeIterator +import java.util.LinkedList + +internal class TestIterator>(vertex: N?) : TreeIterator(vertex) { + fun getTreeStack(): LinkedList {return stack} +} \ No newline at end of file From 5808e12baaefdd8319a8ee0c578b79c47dc86d28 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 1 Apr 2024 05:21:54 +0300 Subject: [PATCH 136/227] fix (AVLTree, putRec()) : add removalStage D --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 5c021aa..e20410d 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -85,23 +85,25 @@ open class AVLSearchTree : AbstractBinarySearchTree> root = removeRecReturned.component2() } RemovalStage.C -> root = null + RemovalStage.D -> root = removeRecReturned.component2() } return removeRecReturned.component3() } return null } - private enum class RemovalStage {A, B, C} - // a - don't need tree changes anymore - // b - probably need some tree changes, but not nulling - // c - need to null due "Son" property of (if exists) the parent of removed vertex + b + private enum class RemovalStage {A, B, C, D} + // A - don't need tree changes anymore + // B - probably need some tree changes, but not nulling + // C - need to null due "Son" property of (if exists) the parent of removed vertex + b + // D - need only to change due "Son" property of (if exists) the parent private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { val nextCallReturned : Triple ?, V?> // Triple consists of: // 1) removal stage // 2) if RemovalStage == a : just a vertex (don't need it later) - // if RemovalStage == b : the root of the changed subtree + // if RemovalStage == b or d : the root of the changed subtree // if RemovalStage == c : the removed vertex // 3) a value of the removed vertex (or null if key not exists) when (compareKeys(key, vertex.key)) { @@ -127,7 +129,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> size-- Triple(RemovalStage.B, vertex.leftSon as AVLVertex, vertex.value) } - else -> Triple(RemovalStage.B, + else -> Triple(RemovalStage.D, prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) } } @@ -175,14 +177,19 @@ open class AVLSearchTree : AbstractBinarySearchTree> vertex.rightSon = null return doBalanceChoreWhenRightSubTreeChanged() } - } + } + RemovalStage.D -> { + if (compareKeys(nextCallReturned.component2().key, vertex.key) == -1) + vertex.leftSon = nextCallReturned.component2() + else vertex.rightSon = nextCallReturned.component2() + return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) + } } } private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex? { - val substitute = getMaxKeyNodeRec(vertex.leftSon) - if (substitute == null) return null + val substitute = getMaxKeyNodeRec(vertex.leftSon) as AVLVertex remove(substitute.key) substitute.leftSon = vertex.leftSon substitute.rightSon = vertex.rightSon From 4ef6c910952d64b2e075c68751f3b158c48bfd16 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 1 Apr 2024 08:42:16 +0300 Subject: [PATCH 137/227] feat : add removeTest --- lib/src/test/kotlin/AVLTreeTest.kt | 905 +++++++++++++++++++++++++++-- lib/src/test/kotlin/AVLTreeTests | 0 2 files changed, 853 insertions(+), 52 deletions(-) delete mode 100644 lib/src/test/kotlin/AVLTreeTests diff --git a/lib/src/test/kotlin/AVLTreeTest.kt b/lib/src/test/kotlin/AVLTreeTest.kt index 70a6796..6b116e9 100644 --- a/lib/src/test/kotlin/AVLTreeTest.kt +++ b/lib/src/test/kotlin/AVLTreeTest.kt @@ -47,7 +47,7 @@ class AVLTreeTest { } @Test - fun `root's sonsHeightDiff decreased by 1 after entery with larger key was added to size 1 tree`(){ + fun `root's sonsHeightDiff decreased by 1 after entry with larger key was added to size 1 tree`(){ val tree = makeSize1Tree() tree.put('c', '+') val root = tree.getRootT() @@ -55,7 +55,7 @@ class AVLTreeTest { } @Test - fun `root's sonsHeightDiff increased by 1 after entery with lesser key was added to size 1 tree`(){ + fun `root's sonsHeightDiff increased by 1 after entry with lesser key was added to size 1 tree`(){ val tree = makeSize1Tree() tree.put('a', '-') val root = tree.getRootT() @@ -76,7 +76,7 @@ class AVLTreeTest { assert(tree.size() == 2L) } - private fun makeTreeForNeedNotBalanceingTest() : AVLTreeForTest { + private fun makeTreeForNeedNotBalanceingPutTest() : AVLTreeForTest { return AVLTreeForTest(AVLVertex(4, 'A', AVLVertex(1, 'I'), AVLVertex(5, 'S')), 3L) } @@ -87,15 +87,15 @@ class AVLTreeTest { } @Test - fun `content is correct after entery was added (needn't balancing)`() { - val tree = makeTreeForNeedNotBalanceingTest() + fun `content is correct after entry was added (needn't balancing)`() { + val tree = makeTreeForNeedNotBalanceingPutTest() tree.put(0, 'O') assert(isTreeConsistsOf(setOf(0 to 'O', 1 to 'I', 5 to 'S', 4 to 'A'), tree)) } @Test fun `size increased by 1 after added to 'size 2+' tree (needn't balancing)`() { - val tree = makeTreeForNeedNotBalanceingTest() + val tree = makeTreeForNeedNotBalanceingPutTest() tree.put(0, 'O') assert(tree.size() == 4L) } @@ -120,7 +120,7 @@ class AVLTreeTest { @Test fun `structure is correct after added to 'size 2+' tree (needn't balancing)`() { - val tree = makeTreeForNeedNotBalanceingTest() + val tree = makeTreeForNeedNotBalanceingPutTest() tree.put(0, 'O') val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null)) assert(isTreeSStructureThat(tree, arrayOf(4, 1, 0, 5), expectedDependences)) @@ -148,8 +148,8 @@ class AVLTreeTest { } @Test - fun `vertexes' sonsHeightDiff are correct after entery was added to 'size 2+' tree (needn't balancing)`() { - val tree = makeTreeForNeedNotBalanceingTest() + fun `vertexes' sonsHeightDiff are correct after entry was added to 'size 2+' tree (needn't balancing)`() { + val tree = makeTreeForNeedNotBalanceingPutTest() tree.put(0, 'O') assert(isSonsHeightDiffCorrect(tree)) } @@ -162,12 +162,12 @@ class AVLTreeTest { } @Test - fun `content is correct after entery was added (have to rotate left)`() { + fun `content is correct after entry was added (have to rotate left)`() { val tree = makeTreeForHaveToRotateLeftPutTest() tree.put('j', 'J') - val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') - assert(isTreeConsistsOf(expextedContent, tree)) + assert(isTreeConsistsOf(expectedContent, tree)) } @@ -184,8 +184,8 @@ class AVLTreeTest { tree.put('j', 'J') val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), Triple(4, 5, 6), Triple(7, null, 8)) - val expextedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j' ) - assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + val expectedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j' ) + assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) } @Test @@ -203,12 +203,12 @@ class AVLTreeTest { } @Test - fun `content is correct after entery was added (have to rotate right)`() { + fun `content is correct after entry was added (have to rotate right)`() { val tree = makeTreeForHaveToRotateRightPutTest() tree.put('a', 'A') - val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') - assert(isTreeConsistsOf(expextedContent, tree)) + assert(isTreeConsistsOf(expectedContent, tree)) } @Test @@ -224,8 +224,8 @@ class AVLTreeTest { tree.put('a', 'A') val expectedDependences = listOf(Triple(0, 1, 7), Triple(1, 2, 4), Triple(2, 3, null), Triple(4, 5, 6), Triple(7, null, 8)) - val expextedOrder = arrayOf('h', 'c', 'b', 'a', 'f', 'd', 'e', 'i', 'j') - assert(isTreeSStructureThat(tree, expextedOrder, expectedDependences)) + val expectedOrder = arrayOf('h', 'c', 'b', 'a', 'f', 'd', 'e', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @Test @@ -242,11 +242,11 @@ class AVLTreeTest { } @Test - fun `content is correct after entery was added (rotateLeft changes root)`() { + fun `content is correct after entry was added (rotateLeft changes root)`() { val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() tree.put('j', 'J') - val expextedContent = setOf('d' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') - assert(isTreeConsistsOf(expextedContent, tree)) + val expectedContent = setOf('d' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expectedContent, tree)) } @Test @@ -261,8 +261,8 @@ class AVLTreeTest { val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() tree.put('j', 'J') val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, null, 5)) - val expextedOrder = arrayOf('h', 'e', 'd', 'f', 'i', 'j') - assert(isTreeSStructureThat(tree, expextedOrder, expectedDependences)) + val expectedOrder = arrayOf('h', 'e', 'd', 'f', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @Test @@ -279,11 +279,11 @@ class AVLTreeTest { } @Test - fun `tree consists of initially content and entery after entery was added (rotateRight changes root)`() { + fun `content is correct after entry was added (rotateRight changes root)`() { val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() tree.put('a', 'A') - val expextedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'f' to 'F') - assert(isTreeConsistsOf(expextedContent, tree)) + val expectedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'f' to 'F') + assert(isTreeConsistsOf(expectedContent, tree)) } @Test @@ -294,12 +294,12 @@ class AVLTreeTest { } @Test - fun `tree's structure is correct after added (rotateRight changes root)`() { + fun `structure is correct after added (rotateRight changes root)`() { val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() tree.put('a', 'A') val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 5)) - val expextedOrder = arrayOf('c', 'b', 'a', 'f', 'd', 'e') - assert(isTreeSStructureThat(tree, expextedOrder, expectedDependences)) + val expectedOrder = arrayOf('c', 'b', 'a', 'f', 'd', 'e') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @Test @@ -318,21 +318,21 @@ class AVLTreeTest { // (1) - add grandson's right son, (2) add grandson's left son @Test - fun `content is correct after entery was added (have to big rotate left)(1)`() { + fun `content is correct after entry was added (have to big rotate left)(1)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('f', 'F') - val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J') - assert(isTreeConsistsOf(expextedContent, tree)) + assert(isTreeConsistsOf(expectedContent, tree)) } @Test - fun `content is correct after entery was added (have to big rotate left)(2)`() { + fun `content is correct after entry was added (have to big rotate left)(2)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('h', 'H') - val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J') - assert(isTreeConsistsOf(expextedContent, tree)) + assert(isTreeConsistsOf(expectedContent, tree)) } @Test @@ -355,8 +355,8 @@ class AVLTreeTest { tree.put('f', 'F') val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), Triple(4, 5, 6), Triple(7, null, 8)) - val expextedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'f', 'i', 'j') - assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'f', 'i', 'j') + assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) } @Test fun `structure is correct after added (have to big rotate left)(2)`() { @@ -364,8 +364,8 @@ class AVLTreeTest { tree.put('h', 'H') val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 6), Triple(4, 5, null), Triple(6, 7, 8)) - val expextedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'i', 'h', 'j') - assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'i', 'h', 'j') + assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) } @Test fun `vertexes' sonsHeightDiff are correct after added (have to big rotate left)(1)`() { @@ -390,21 +390,21 @@ class AVLTreeTest { // (1) - add grandson's left son, (2) add grandson's right son @Test - fun `content is correct after entery was added (have to big rotate right)(1)`() { + fun `content is correct after entry was added (have to big rotate right)(1)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('c', 'C') - val expextedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', + val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', 'd' to 'D', 'h' to 'H', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J') - assert(isTreeConsistsOf(expextedContent, tree)) + assert(isTreeConsistsOf(expectedContent, tree)) } @Test - fun `content is correct after entery was added (have to big rotate right)(2)`() { + fun `content is correct after entry was added (have to big rotate right)(2)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('e', 'E') - val expextedContent = setOf('a' to 'A','b' to 'B', 'f' to 'F', + val expectedContent = setOf('a' to 'A','b' to 'B', 'f' to 'F', 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J') - assert(isTreeConsistsOf(expextedContent, tree)) + assert(isTreeConsistsOf(expectedContent, tree)) } @Test @@ -428,8 +428,8 @@ class AVLTreeTest { tree.put('c', 'C') val expectedDependences = listOf(Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 5), Triple(5, null, 6), Triple(2, 3, 4)) - val expextedOrder = arrayOf('h', 'd', 'b', 'a', 'c', 'f', 'g', 'i', 'j') - assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'c', 'f', 'g', 'i', 'j') + assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) } @Test @@ -438,8 +438,8 @@ class AVLTreeTest { tree.put('e', 'E') val expectedDependences = listOf(Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 4), Triple(2, 3, null), Triple(4, 5, 6)) - val expextedOrder = arrayOf('h', 'd', 'b', 'a', 'f', 'e', 'g', 'i', 'j') - assert(isTreeSStructureThat(tree,expextedOrder, expectedDependences)) + val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'f', 'e', 'g', 'i', 'j') + assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) } @Test @@ -467,8 +467,809 @@ class AVLTreeTest { @Test fun `content is correct after init by map`() { val tree = AVLTreeForTest(hashMapOf('a' to 'A', 'b' to 'B')) - val expextedContent = setOf('a' to 'A', 'b' to 'B') - assert(isTreeConsistsOf(expextedContent, tree)) + val expectedContent = setOf('a' to 'A', 'b' to 'B') + assert(isTreeConsistsOf(expectedContent, tree)) + } + + // remove test + + @Test + fun `delete from emptyTree returns null`(){ + val tree = makeEmptyTree() + assert(tree.remove(0) == null) + } + + @Test + fun `tree is empty after deleted root of 'size 1' tree `() { + val tree = makeSize1Tree() + tree.remove('b') + assert(tree.getVertexesInDFSOrder().isEmpty()) + } + + @Test + fun `size equals 0 after deleted root of 'size 1' tree`() { + val tree = makeSize1Tree() + tree.remove('b') + assert(tree.size() == 0L) + } + + @Test + fun `remove fun return null if entry's key isn't exists`() { + val tree = makeSize1Tree() + assert(tree.remove('a') == null) + } + + @Test + fun `tree has no changes after tried to delete by non existed larger key`() { + val tree = makeSize1Tree() + tree.remove('c') + assert(tree.size() == 1L) + assert(tree.getRootT()?.value == '+') + } + + @Test + fun `tree has no changes after tried to delete by non existed lesser key`() { + val tree = makeSize1Tree() + tree.remove('a') + assert(tree.size() == 1L) + assert(tree.getRootT()?.value == '+') + } + + + private fun makeTreeForRemoveLeafWithoutBalanceingTest() : AVLTreeForTest { + return AVLTreeForTest(AVLVertex('r', "r", AVLVertex('n', "n"), AVLVertex('z', "z")), 3L) + } + + @Test + fun `right leaf deleted after remove with one's key was called (needn't balanceing)`() { + val tree = makeTreeForRemoveLeafWithoutBalanceingTest() + tree.remove('z') + val root = tree.getRootT() + if (root != null) assert(root.rightSon == null) + else assert(false) + } + + @Test + fun `left leaf deleted after remove with one's key was called (needn't balanceing)`() { + val tree = makeTreeForRemoveLeafWithoutBalanceingTest() + tree.remove('n') + val root = tree.getRootT() + if (root != null) assert(root.leftSon == null) + else assert(false) + } + + @Test + fun `remove by right leaf's key return due value (needn't balanceing)`() { + val tree = makeTreeForRemoveLeafWithoutBalanceingTest() + assert(tree.remove('z') == "z") + } + + @Test + fun `remove by left leaf's key return due value (needn't balanceing)`() { + val tree = makeTreeForRemoveLeafWithoutBalanceingTest() + assert(tree.remove('n') == "n") + } + + @Test + fun `vertex's sonsHeightDiff increased by 1 after deleted one's right leaf (needn't balanceing)`(){ + val tree = makeTreeForRemoveLeafWithoutBalanceingTest() + tree.remove('z') + val root = tree.getRootT() + assert(root?.sonsHeightDiff == 1) + } + + @Test + fun `vertex's sonsHeightDiff decreased by 1 after deleted one's left son (needn't balanceing)`(){ + val tree = makeTreeForRemoveLeafWithoutBalanceingTest() + tree.remove('n') + val root = tree.getRootT() + assert(root?.sonsHeightDiff == -1) + } + + @Test + fun `size decreased by 1 after deleted right leaf (needn't balanceing)`() { + val tree = makeTreeForRemoveLeafWithoutBalanceingTest() + tree.remove('z') + assert(tree.size() == 2L) + } + + @Test + fun `size decreased by 1 after deleted left leaf (needn't balanceing)`() { + val tree = makeTreeForRemoveLeafWithoutBalanceingTest() + tree.remove('n') + assert(tree.size() == 2L) + } + private fun makeTreeForRemoveLeftSonWithOnlyLeftSonTest() : AVLTreeForTest { + val leftSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) + val root = AVLVertex('s', 5, leftSon, AVLVertex('z', 2), 1) + return AVLTreeForTest(root, 4L) + } + + @Test + fun `remove left son with only left son returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + assert(tree.remove('q') == 9) + } + + @Test + fun `content is correct after removed left son with only left son (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isTreeConsistsOf(setOf('o' to 0, 's' to 5, 'z' to 2), tree)) + } + + @Test + fun `size decreased by 1 after removed left son with only left son (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() + tree.remove('q') + assert(tree.size() == 3L) + } + + @Test + fun `structure is correct after removed left son with only leftt son (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isTreeSStructureThat(tree ,arrayOf('s', 'o', 'z'), listOf(Triple(0, 1, 2 )))) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed LSon with only LSon (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveLeftSonWithOnlyRightSonTest() : AVLTreeForTest { + val leftSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) + val root = AVLVertex('s', 5, leftSon, AVLVertex('z', 2), 1) + return AVLTreeForTest(root, 4L) + } + + @Test + fun `remove left son with only right son returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + assert(tree.remove('q') == 9) + } + + @Test + fun `content is correct after removed left son with only right son (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + tree.remove('q') + assert(isTreeConsistsOf(setOf('r' to 7, 's' to 5, 'z' to 2), tree)) + } + + @Test + fun `size decreased by 1 after removed left son with only right son (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + tree.remove('q') + assert(tree.size() == 3L) + } + + @Test + fun `structure is correct after removed left son with only right son (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + tree.remove('q') + assert(isTreeSStructureThat(tree ,arrayOf('s', 'r', 'z'), listOf(Triple(0, 1, 2 )))) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed LSon with only RSon (needn't balanceing)`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + tree.remove('q') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveRightSonWithOnlyLeftSonTest() : AVLTreeForTest { + val rightSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) + val root = AVLVertex('i', 1, AVLVertex('b', 6), rightSon, -1) + return AVLTreeForTest(root, 4L) + } + + @Test + fun `remove right son with only left son returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + assert(tree.remove('q') == 9) + } + + @Test + fun `content is correct after removed right son with only left son (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isTreeConsistsOf(setOf('o' to 0, 'b' to 6, 'i' to 1), tree)) + } + + @Test + fun `size decreased by 1 after removed right son with only left son (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + tree.remove('q') + assert(tree.size() == 3L) + } + + @Test + fun `structure is correct after removed right son with only left son (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isTreeSStructureThat(tree ,arrayOf('i', 'b', 'o'), listOf(Triple(0, 1, 2 )))) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed RSon with only LSon (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveRightSonWithOnlyRightSonTest() : AVLTreeForTest { + val rightSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) + val root = AVLVertex('i', 1, AVLVertex('b', 6), rightSon, -1) + return AVLTreeForTest(root, 4L) + } + + @Test + fun `remove right son with only right son returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + assert(tree.remove('q') == 9) + } + + @Test + fun `content is correct after removed right son with only right son (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + tree.remove('q') + assert(isTreeConsistsOf(setOf('r' to 7, 'b' to 6, 'i' to 1), tree)) + } + + @Test + fun `size decreased by 1 after removed right son with only right son (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + tree.remove('q') + assert(tree.size() == 3L) + } + + @Test + fun `structure is correct after removed right son with only right son (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + tree.remove('q') + assert(isTreeSStructureThat(tree ,arrayOf('i', 'b', 'r'), listOf(Triple(0, 1, 2 )))) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed RSon with only RSon (needn't balanceing)`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + tree.remove('q') + assert(isSonsHeightDiffCorrect(tree)) + } + private fun makeTreeForRemoveRootWithOnlyLeftSon() : AVLTreeForTest{ + return AVLTreeForTest(AVLVertex("be", "es", (AVLVertex("and", "et")), null, 1), 2L) + } + @Test + fun `remove root with only left son returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithOnlyLeftSon() + assert(tree.remove("be") == "es") } + + @Test + fun `content is correct after removed root with only left son (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithOnlyLeftSon() + tree.remove("be") + assert(isTreeConsistsOf(setOf("and" to "et"), tree)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed root with only LSon (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithOnlyLeftSon() + tree.remove("and") + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveRootWithOnlyRightSon() : AVLTreeForTest{ + return AVLTreeForTest(AVLVertex("and", "et", null, (AVLVertex("be", "es")), -1), 2L) + } + @Test + fun `remove root with only right son returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithOnlyRightSon() + assert(tree.remove("and") == "et") + } + + @Test + fun `content is correct after removed root with only right son (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithOnlyRightSon() + tree.remove("and") + assert(isTreeConsistsOf(setOf("be" to "es"), tree)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed root with only RSon (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithOnlyRightSon() + tree.remove("and") + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveSonWithBothSons() : AVLTreeForTest { + val eVrt = AVLVertex('e', 'E', AVLVertex('c', 'C'), null, 1) + val bVrt = AVLVertex('b', 'B', AVLVertex('a', 'A'), eVrt, -1) + val leftSon = AVLVertex('f', 'F', bVrt, AVLVertex('i', 'I', null, AVLVertex('k', 'K'), -1), 1) + val qVrt = AVLVertex('q', 'Q', null, AVLVertex('s', 'S'), -1) + val wVrt = AVLVertex('w', 'W', null, AVLVertex('z', 'Z'), -1) + val root = AVLVertex('n', 'N', leftSon, AVLVertex('u', 'U', qVrt, wVrt, 0), 1) + return AVLTreeForTest(root, 13L) + } + + @Test + fun `remove left son with both sons returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + assert(tree.remove('f') == 'F') + } + + @Test + fun `content is correct after removed left son with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('f') + val expectedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'e' to 'E','i' to 'I', + 'z' to 'Z', 'k' to 'K', 'n' to 'N', 'u' to 'U', 'q' to 'Q', 's' to 'S', 'w' to 'W') + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed left son with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('f') + assert(tree.size() == 12L) + } + + @Test + fun `structure is correct after removed left son with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('f') + val expectedDependences = listOf(Triple(0, 1, 7), Triple(1, 2, 5), Triple(2, 3, 4), + Triple (5, null, 6), Triple(7, 8, 10), Triple(10, null, 11)) + val expectedOrder = arrayOf('n', 'e', 'b', 'a', 'c', 'i', 'k', 'u', 'q', 's', 'w','z') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed LSon with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('f') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `remove right son with both sons returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + assert(tree.remove('u') == 'U') + } + + @Test + fun `content is correct after removed right son with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('u') + val expectedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'e' to 'E', 'i' to 'I', + 'z' to 'Z', 'k' to 'K', 'n' to 'N', 'f' to 'F', 'q' to 'Q', 's' to 'S', 'w' to 'W') + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed right son with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('u') + assert(tree.size() == 12L) + } + + @Test + fun `structure is correct after removed right son with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('u') + val expectedDependences = listOf(Triple(0, 1, 8), Triple(1, 2, 6), Triple(2, 3, 4), + Triple (6, null, 7), Triple(4, 5, null), Triple(8, 9, 10), Triple(10, null, 11)) + val expectedOrder = arrayOf('n', 'f', 'b', 'a', 'e', 'c', 'i', 'k', 's', 'q', 'w', 'z') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed RSon with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('u') + assert(isSonsHeightDiffCorrect(tree)) + } + private fun makeTreeForRemoveRootWithBothSonsTest() : AVLTreeForTest { + val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), AVLVertex('e', 5), 0) + val rightSon = AVLVertex('i', 9, null, AVLVertex('k', 11), -1) + val root = AVLVertex('f', 6, leftSon, rightSon, 0) + return AVLTreeForTest(root, 6L) + } + + @Test + fun `remove root with both sons returns due value (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + assert(tree.remove('f') == 6) + } + + @Test + fun `content is correct after removed root with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + tree.remove('f') + val expectedContent = setOf('a' to 1, 'b' to 2, 'e' to 5, 'i' to 9, 'k' to 11) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed root with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + tree.remove('f') + assert(tree.size() == 5L) + } + + @Test + fun `structure is correct after removed root with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + tree.remove('f') + val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, null, 4)) + val expectedOrder = arrayOf('e', 'b', 'a', 'i', 'k') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed root with both sons (needn't balanceing)`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + tree.remove('f') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveWithLeftRotate1Test() : AVLTreeForTest { + val rightSonSRightSon = AVLVertex('o', false, null, AVLVertex('p', true), -1) + val rightSon = AVLVertex('m', true, AVLVertex('l', true), rightSonSRightSon, -1) + val root = AVLVertex('k', true, AVLVertex('i', false, AVLVertex('a', false), null, 1), rightSon, -1) + return AVLTreeForTest(root, 7L) + } + + private fun makeTreeForRemoveWithLeftRotate2Test() : AVLTreeForTest { + val rightSonSRightSon = AVLVertex('o', false, AVLVertex('n', true), AVLVertex('p', true), 0) + val rightSon = AVLVertex('m', true, AVLVertex('l', true), rightSonSRightSon, -1) + val root = AVLVertex('k', true, AVLVertex('i', false, AVLVertex('a', false), null, 1), rightSon, -1) + return AVLTreeForTest(root, 8L) + } + // new subroot initially had sonSHeightDiff == -1 in (1) and 0 in (2) + @Test + fun `returns due value after removed and rotated left(1)`() { + val tree = makeTreeForRemoveWithLeftRotate1Test() + assert(tree.remove('l') == true) + } + + @Test + fun `returns due value after removed and rotated left(2)`() { + val tree = makeTreeForRemoveWithLeftRotate2Test() + assert(tree.remove('l') == true) + } + + @Test + fun `content is correct after removed and rotated left (1)`() { + val tree = makeTreeForRemoveWithLeftRotate1Test() + tree.remove('l') + val expectedContent = setOf('k' to true, 'i' to false, 'm' to true, + 'o' to false, 'p' to true, 'a' to false) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `content is correct after removed and rotated left (2)`() { + val tree = makeTreeForRemoveWithLeftRotate2Test() + tree.remove('l') + val expectedContent = setOf('k' to true, 'i' to false, 'm' to true, + 'o' to false, 'p' to true, 'n' to true, 'a' to false) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed and rotated left (1)`() { + val tree = makeTreeForRemoveWithLeftRotate1Test() + tree.remove('l') + assert(tree.size() == 6L) + } + + @Test + fun `size decreased by 1 after removed and rotated left (2)`() { + val tree = makeTreeForRemoveWithLeftRotate2Test() + tree.remove('l') + assert(tree.size() == 7L) + } + + @Test + fun `structure is correct after removed and rotated left (1)`() { + val tree = makeTreeForRemoveWithLeftRotate1Test() + tree.remove('l') + val expectedDependences = listOf(Triple(0, 1, 3), Triple(3, 4, 5), Triple(1, 2, null)) + val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'p') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `structure is correct after removed and rotated left (2)`() { + val tree = makeTreeForRemoveWithLeftRotate2Test() + tree.remove('l') + val expectedDependences = listOf(Triple(0, 1, 3), Triple(3, 4, 6), + Triple(4, null, 5), Triple(1, 2, null)) + val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'n', 'p') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed and rotated left (1)`() { + val tree = makeTreeForRemoveWithLeftRotate1Test() + tree.remove('l') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed and rotated left (2)`() { + val tree = makeTreeForRemoveWithLeftRotate2Test() + tree.remove('l') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveWithRightRotate1Test() : AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), null, 1) + val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) + val root = AVLVertex('k', true, leftSon, AVLVertex('m', true, null, AVLVertex('o', false), -1), 1) + return AVLTreeForTest(root, 7L) + } + + + private fun makeTreeForRemoveWithRightRotate2Test() : AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), AVLVertex('c', true), 0) + val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) + val root = AVLVertex('k', true, leftSon, AVLVertex('m', true, null, AVLVertex('o', false), -1), 1) + return AVLTreeForTest(root, 8L) + } + + // new subroot initially had sonSHeightDiff == 1 in (1) and 0 in (2) + @Test + fun `returns due value after removed and rotated right(1)`() { + val tree = makeTreeForRemoveWithRightRotate1Test() + assert(tree.remove('e') == false) + } + + @Test + fun `returns due value after removed and rotated right(2)`() { + val tree = makeTreeForRemoveWithRightRotate2Test() + assert(tree.remove('e') == false) + } + + @Test + fun `content is correct after removed and rotated right (1)`() { + val tree = makeTreeForRemoveWithRightRotate1Test() + tree.remove('e') + val expectedContent = setOf('k' to true, 'b' to true, 'm' to true, + 'o' to false, 'd' to true, 'a' to false) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `content is correct after removed and rotated right (2)`() { + val tree = makeTreeForRemoveWithRightRotate2Test() + tree.remove('e') + val expectedContent = setOf('k' to true, 'b' to true, 'm' to true, + 'o' to false, 'd' to true, 'a' to false, 'c' to true) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed and rotated right (1)`() { + val tree = makeTreeForRemoveWithRightRotate1Test() + tree.remove('e') + assert(tree.size() == 6L) + } + + @Test + fun `size decreased by 1 after removed and rotated right (2)`() { + val tree = makeTreeForRemoveWithRightRotate2Test() + tree.remove('e') + assert(tree.size() == 7L) + } + + @Test + fun `structure is correct after removed and rotated right (1)`() { + val tree = makeTreeForRemoveWithRightRotate1Test() + tree.remove('e') + val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, null, 5)) + val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'm', 'o') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `structure is correct after removed and rotated right (2)`() { + val tree = makeTreeForRemoveWithRightRotate2Test() + tree.remove('e') + val expectedDependences = listOf(Triple(0, 1, 5), Triple(1, 2, 3), + Triple(5, null, 6), Triple(3, 4, null)) + val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'c', 'm', 'o') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed and rotated right (1)`() { + val tree = makeTreeForRemoveWithRightRotate1Test() + tree.remove('e') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed and rotated right (2)`() { + val tree = makeTreeForRemoveWithRightRotate2Test() + tree.remove('e') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRotateLeftChangesRootRemoveTest() : AVLTreeForTest { + val root = AVLVertex(1, 1, AVLVertex(0, 0), AVLVertex(3, 3, AVLVertex(2, 2), AVLVertex(5, 5)), -1) + return AVLTreeForTest(root, 5L) + } + + @Test + fun `returns due value after removed and rotated right(rotateLeft changed root)`() { + val tree = makeTreeForRotateLeftChangesRootRemoveTest() + assert(tree.remove(0) == 0) + } + + @Test + fun `content is correct after removed (rotateLeft changed root)`() { + val tree = makeTreeForRotateLeftChangesRootRemoveTest() + tree.remove(0) + val expectedContent = setOf(1 to 1, 2 to 2, 3 to 3, 5 to 5) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed (rotateLeft changed root)`() { + val tree = makeTreeForRotateLeftChangesRootRemoveTest() + tree.remove(0) + assert(tree.size() == 4L) + } + + @Test + fun `structure is correct after removed (rotateLeft changed root)`() { + val tree = makeTreeForRotateLeftChangesRootRemoveTest() + tree.remove(0) + val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, null, 2)) + val expectedOrder = arrayOf(3, 1, 2, 5) + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed (rotateLeft changed root)`() { + val tree = makeTreeForRotateLeftChangesRootRemoveTest() + tree.remove(0) + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRotateRightChangesRootRemoveTest() : AVLTreeForTest { + val root = AVLVertex(-1, 1, AVLVertex(-3, 3, AVLVertex(-5, 5), AVLVertex(-2, 2)), AVLVertex(0, 0), 1) + return AVLTreeForTest(root, 5L) + } + + @Test + fun `returns due value after removed and rotated right(rotateRight changed root)`() { + val tree = makeTreeForRotateRightChangesRootRemoveTest() + assert(tree.remove(0) == 0) + } + + @Test + fun `content is correct after removed (rotateRight changed root)`() { + val tree = makeTreeForRotateRightChangesRootRemoveTest() + tree.remove(0) + val expectedContent = setOf(-1 to 1, -2 to 2, -3 to 3, -5 to 5) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed (rotateRight changed root)`() { + val tree = makeTreeForRotateRightChangesRootRemoveTest() + tree.remove(0) + assert(tree.size() == 4L) + } + + @Test + fun `structure is correct after removed (rotateRight changed root)`() { + val tree = makeTreeForRotateRightChangesRootRemoveTest() + tree.remove(0) + val expectedDependences = listOf(Triple(0, 1, 2), Triple(2, 3, null)) + val expectedOrder = arrayOf(-3, -5, -1, -2) + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed (rotateRight changed root)`() { + val tree = makeTreeForRotateRightChangesRootRemoveTest() + tree.remove(0) + assert(isSonsHeightDiffCorrect(tree)) + } + private fun makeTreeForBigRotateLeftChangesRootRemoveTest() : AVLTreeForTest { + val rightSonSLeftSon = AVLVertex('d', 'D', AVLVertex('c', 'C'), AVLVertex('e', 'E')) + val rightSon = AVLVertex('f', 'F', rightSonSLeftSon, AVLVertex('g', 'G'), 1) + val root = AVLVertex('b', 'B', AVLVertex('a', 'A', AVLVertex(' ', ' '), null, 1), rightSon, -1) + return AVLTreeForTest(root, 8L) + } + + @Test + fun `remove returns due value(bigRotateLeft changed root)`() { + val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() + assert(tree.remove(' ') == ' ') + } + + @Test + fun `content is correct after removed (bigRotateLeft changed root)`() { + val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() + tree.remove(' ') + val expectedContent = setOf('d' to 'D', 'c' to 'C', 'e' to 'E','f' to 'F', + 'g' to 'G', 'b' to 'B', 'a' to 'A') + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed (bigRotateLeft changed root)`() { + val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() + tree.remove(' ') + assert(tree.size() == 7L) + } + + @Test + fun `structure is correct after removed (bigRotateLeft changed root)`() { + val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() + tree.remove(' ') + val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, 5, 6)) + val expectedOrder = arrayOf('d', 'b', 'a', 'c', 'f', 'e', 'g') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed (bigRotateLeft changed root)`() { + val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() + tree.remove(' ') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForBigRotateRightChangesRootRemoveTest() : AVLTreeForTest { + val leftSonSRightSon = AVLVertex('e', 5, AVLVertex('c', 3), AVLVertex('d', 4)) + val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), leftSonSRightSon, -1) + val root = AVLVertex('f', 8, leftSon, AVLVertex('i', 9, null, AVLVertex('k', 10), -1), 1) + return AVLTreeForTest(root, 8L) + } + + @Test + fun `remove returns due value(bigRotateRight changed root)`() { + val tree = makeTreeForBigRotateRightChangesRootRemoveTest() + assert(tree.remove('k') == 10) + } + + @Test + fun `content is correct after removed (bigRotateRight changed root)`() { + val tree = makeTreeForBigRotateRightChangesRootRemoveTest() + tree.remove('k') + val expectedContent = setOf('a' to 1, 'b' to 2, 'c' to 3, 'd' to 4, 'e' to 5, + 'i' to 9, 'f' to 8) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after removed (bigRotateRight changed root)`() { + val tree = makeTreeForBigRotateRightChangesRootRemoveTest() + tree.remove('k') + assert(tree.size() == 7L) + } + + @Test + fun `structure is correct after removed (bigRotateRight changed root)`() { + val tree = makeTreeForBigRotateRightChangesRootRemoveTest() + tree.remove('k') + val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, 5, 6)) + val expectedOrder = arrayOf('e', 'b', 'a', 'c', 'f', 'd', 'i') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after removed (bigRotateRight changed root)`() { + val tree = makeTreeForBigRotateRightChangesRootRemoveTest() + tree.remove('k') + assert(isSonsHeightDiffCorrect(tree)) + } } diff --git a/lib/src/test/kotlin/AVLTreeTests b/lib/src/test/kotlin/AVLTreeTests deleted file mode 100644 index e69de29..0000000 From 503e2eeffe20b496f36e622726fa3b007ae14924 Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Mon, 1 Apr 2024 11:22:40 +0300 Subject: [PATCH 138/227] refactor: auto codsetyle changes --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 96 +++++++++++----------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index e20410d..eb40f87 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -16,11 +16,11 @@ open class AVLSearchTree : AbstractBinarySearchTree> } private fun putRec(key: K, value: V, - replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { + replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { fun putRecShort(vrtx : AVLVertex) : AVLVertex? { return putRec(key, value, replaceIfExists, vrtx) - } - val nextCallReturned : AVLVertex? + } + val nextCallReturned : AVLVertex? when (compareKeys(key, vertex.key)) { -1 -> { if (vertex.leftSon == null){ @@ -53,7 +53,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> if (nextCallReturned.sonsHeightDiff == 0) return null if (vertex.sonsHeightDiff + 1 == 2) return balance(vertex) vertex.sonsHeightDiff++ - return vertex + return vertex } fun doBalanceChoreWhenRightSubTreeChanged() : AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null @@ -63,18 +63,18 @@ open class AVLSearchTree : AbstractBinarySearchTree> } when (nextCallReturned){ vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() - vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() + vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() else -> { if (compareKeys(nextCallReturned.key, vertex.key) == -1) { - vertex.leftSon = nextCallReturned - return doBalanceChoreWhenLeftSubTreeChanged() + vertex.leftSon = nextCallReturned + return doBalanceChoreWhenLeftSubTreeChanged() } - vertex.rightSon = nextCallReturned - return doBalanceChoreWhenRightSubTreeChanged() + vertex.rightSon = nextCallReturned + return doBalanceChoreWhenRightSubTreeChanged() } } } - + override fun remove(key: K): V? { if (!isEmpty()) { val removeRecReturned = removeRec(key, root as AVLVertex) @@ -96,7 +96,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> // A - don't need tree changes anymore // B - probably need some tree changes, but not nulling // C - need to null due "Son" property of (if exists) the parent of removed vertex + b - // D - need only to change due "Son" property of (if exists) the parent + // D - need only to change due "Son" property of (if exists) the parent private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { val nextCallReturned : Triple ?, V?> @@ -124,31 +124,31 @@ open class AVLSearchTree : AbstractBinarySearchTree> true to false -> { size-- Triple(RemovalStage.B, vertex.rightSon as AVLVertex, vertex.value) - } - false to true -> { + } + false to true -> { size-- Triple(RemovalStage.B, vertex.leftSon as AVLVertex, vertex.value) } else -> Triple(RemovalStage.D, - prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) + prepareLargestLowerToReplaceVertex(vertex), vertex.value) } - } + } } fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff - 1 == -2) + if (vertex.sonsHeightDiff - 1 == -2) return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) vertex.sonsHeightDiff-- - return Triple(RemovalStage.B, vertex, nextCallReturned.third) + return Triple(RemovalStage.B, vertex, nextCallReturned.third) } fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff + 1 == 2) + if (vertex.sonsHeightDiff + 1 == 2) return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) vertex.sonsHeightDiff++ - return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) + return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) } when (nextCallReturned.component1()) { RemovalStage.A -> return nextCallReturned @@ -178,17 +178,17 @@ open class AVLSearchTree : AbstractBinarySearchTree> return doBalanceChoreWhenRightSubTreeChanged() } } - RemovalStage.D -> { + RemovalStage.D -> { if (compareKeys(nextCallReturned.component2().key, vertex.key) == -1) vertex.leftSon = nextCallReturned.component2() else vertex.rightSon = nextCallReturned.component2() return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) } - + } } - private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex? { + private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex { val substitute = getMaxKeyNodeRec(vertex.leftSon) as AVLVertex remove(substitute.key) substitute.leftSon = vertex.leftSon @@ -207,7 +207,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> } (leftSon as AVLVertex).sonsHeightDiff = values.component2() } - + if(curVertex.sonsHeightDiff == -1) { rightSon = curVertex.rightSon as AVLVertex return if (rightSon.sonsHeightDiff == 1) { @@ -228,33 +228,33 @@ open class AVLSearchTree : AbstractBinarySearchTree> setTwoSonHeightDiffs( if (rightSon.sonsHeightDiff == 0) -1 to 1 else 0 to 0 - ) + ) subtreeRoot } } - leftSon = curVertex.leftSon as AVLVertex - return if (leftSon.sonsHeightDiff == -1) { - val leftSonSRightSon = leftSon.rightSon as AVLVertex - val subtreeRoot = bigRotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( - when (leftSonSRightSon.sonsHeightDiff) { - -1 -> 0 to 1 - 1 -> -1 to 0 - else -> 0 to 0 - } - ) - leftSonSRightSon.sonsHeightDiff = 0 - subtreeRoot - } - else { - val subtreeRoot = rotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( - if (leftSon.sonsHeightDiff == 0) 1 to -1 - else 0 to 0 - ) - subtreeRoot - } + leftSon = curVertex.leftSon as AVLVertex + return if (leftSon.sonsHeightDiff == -1) { + val leftSonSRightSon = leftSon.rightSon as AVLVertex + val subtreeRoot = bigRotateRight(curVertex, leftSon) + setTwoSonHeightDiffs( + when (leftSonSRightSon.sonsHeightDiff) { + -1 -> 0 to 1 + 1 -> -1 to 0 + else -> 0 to 0 + } + ) + leftSonSRightSon.sonsHeightDiff = 0 + subtreeRoot + } + else { + val subtreeRoot = rotateRight(curVertex, leftSon) + setTwoSonHeightDiffs( + if (leftSon.sonsHeightDiff == 0) 1 to -1 + else 0 to 0 + ) + subtreeRoot + } } private fun rotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { @@ -268,7 +268,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> leftSon.rightSon = curVertex return leftSon } - + private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) curVertex.rightSon = curRightSon @@ -284,5 +284,5 @@ open class AVLSearchTree : AbstractBinarySearchTree> constructor (comparator: Comparator? = null) : super(comparator) constructor(map: Map, replaceIfExists: Boolean = true, - comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } From bef4b1c44c93eb36f4d0ec3c1b03480ffa46d658 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 1 Apr 2024 13:10:35 +0300 Subject: [PATCH 139/227] test: add 100% test coverage --- lib/src/main/kotlin/trees/RBSearchTree.kt | 98 +++++------ lib/src/test/kotlin/trees/RBSearchTreeTest.kt | 160 ++++++++++++------ 2 files changed, 153 insertions(+), 105 deletions(-) diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index fde180f..d1cb2cb 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -1,17 +1,18 @@ package main.trees + import main.vertexes.RBVertex -class RBSearchTree : AbstractBinarySearchTree> { +class RBSearchTree : AbstractBinarySearchTree> { //4 cases we need to look at - //1) remove red vertex with 0 children -> just remove vetrex + //1) remove red vertex with 0 children -> just remove vertex //2) remove red or black vertex with 2 children -> //find min vertex on the right subtree and swap it's key and value with //key and value of vertex that we need to remove //Now we can work with vertex which has 1 or 0 children - //3) remove black vetrex with 1 child -> child can be only red + //3) remove black vertex with 1 child -> child can be only red //so we just swap child's key and value with key and value that we need to remove //and look at case 1) @@ -22,13 +23,14 @@ class RBSearchTree : AbstractBinarySearchTree> { if (needToBalance(vertex)) balanceAfterRemove(vertex) + --size return value } - private fun needToBalance(vertex: RBVertex): Boolean{ - when (countChildren(vertex)){ + private fun needToBalance(vertex: RBVertex): Boolean { + when (countChildren(vertex)) { 0 -> { - if (vertex.isRed){ + if (vertex.isRed) { replaceVertexBy(vertex, null) return false } @@ -42,7 +44,7 @@ class RBSearchTree : AbstractBinarySearchTree> { 2 -> { val vertexForSwap = getMinKeyNodeRec(vertex.rightSon) - vertexForSwap?.let{ + vertexForSwap?.let { val key = vertex.key vertex.key = it.key it.key = key @@ -76,14 +78,14 @@ class RBSearchTree : AbstractBinarySearchTree> { //4) brother is red -> make brother black, parent red and //rotate left. We move conflict on level below, then we look at the previous cases - private fun balanceAfterRemove(vertex: RBVertex?){ + private fun balanceAfterRemove(vertex: RBVertex?) { var currentVertex = vertex - while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)){ + while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { var brother: RBVertex? - if (currentVertex == currentVertex?.parent?.leftSon){ + if (currentVertex == currentVertex?.parent?.leftSon) { brother = currentVertex?.parent?.rightSon - if (brother?.isRed == true){ + if (brother?.isRed == true) { brother.isRed = false currentVertex?.parent?.isRed = true val vertexForRotate = currentVertex?.parent @@ -92,14 +94,13 @@ class RBSearchTree : AbstractBinarySearchTree> { } if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null)){ + (brother?.rightSon?.isRed == false || brother?.rightSon == null) + ) { brother?.isRed = true - if (currentVertex == vertex) currentVertex?.parent?.leftSon = null currentVertex = currentVertex?.parent - } - - else{ - if (brother.rightSon?.isRed == false || brother.rightSon == null){ + if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null + } else { + if (brother.rightSon?.isRed == false || brother.rightSon == null) { brother.leftSon?.isRed = false brother.isRed = true rotateRight(brother) @@ -115,12 +116,10 @@ class RBSearchTree : AbstractBinarySearchTree> { if (currentVertex == vertex) currentVertex?.parent?.leftSon = null currentVertex = root } - } - - else{ + } else { brother = currentVertex?.parent?.leftSon - if (brother?.isRed == true){ + if (brother?.isRed == true) { brother.isRed = false currentVertex?.parent?.isRed = true val vertexForRotate = currentVertex?.parent @@ -129,14 +128,13 @@ class RBSearchTree : AbstractBinarySearchTree> { } if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null)){ + (brother?.rightSon?.isRed == false || brother?.rightSon == null) + ) { brother?.isRed = true - if (currentVertex == vertex) currentVertex?.parent?.rightSon = null currentVertex = currentVertex?.parent - } - - else{ - if (brother.leftSon?.isRed == false || brother.leftSon == null){ + if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null + } else { + if (brother.leftSon?.isRed == false || brother.leftSon == null) { brother.rightSon?.isRed = false brother.isRed = true rotateLeft(brother) @@ -146,7 +144,7 @@ class RBSearchTree : AbstractBinarySearchTree> { val parentColor = currentVertex?.parent?.isRed parentColor?.let { brother?.isRed = parentColor } currentVertex?.parent?.isRed = false - brother?.rightSon?.isRed = false + brother?.leftSon?.isRed = false val vertexForRotate = currentVertex?.parent vertexForRotate?.let { rotateRight(vertexForRotate) } if (currentVertex == vertex) currentVertex?.parent?.rightSon = null @@ -159,15 +157,16 @@ class RBSearchTree : AbstractBinarySearchTree> { //finds vertex by corresponding key //if such vertex doesn't exist returns null - fun getVertex(key: K): RBVertex? { + private fun getVertex(key: K): RBVertex? { var currentVertex: RBVertex? = root - while (currentVertex?.key != key){ + while (currentVertex?.key != key) { if (currentVertex == null) return null - when (compareKeys(key, currentVertex.key)){ + when (compareKeys(key, currentVertex.key)) { -1 -> { currentVertex = currentVertex.leftSon } + 1 -> { currentVertex = currentVertex.rightSon } @@ -184,16 +183,18 @@ class RBSearchTree : AbstractBinarySearchTree> { var isLeft: Boolean = false while (currentVertex != null) { - when (compareKeys(key, currentVertex.key)){ + when (compareKeys(key, currentVertex.key)) { -1 -> { parent = currentVertex currentVertex = currentVertex.leftSon isLeft = true } + 0 -> { if (replaceIfExists) currentVertex.value = value break } + 1 -> { parent = currentVertex currentVertex = currentVertex.rightSon @@ -202,7 +203,7 @@ class RBSearchTree : AbstractBinarySearchTree> { } } - if (currentVertex == null){ + if (currentVertex == null) { currentVertex = RBVertex(key, value, null, null, true, parent) if (root == null) root = currentVertex else if (isLeft) parent?.let { parent.leftSon = currentVertex } @@ -210,6 +211,7 @@ class RBSearchTree : AbstractBinarySearchTree> { } balanceAfterPut(currentVertex) + ++size } //we need to balance tree in two cases @@ -227,20 +229,18 @@ class RBSearchTree : AbstractBinarySearchTree> { private fun balanceAfterPut(vertex: RBVertex) { var currentVertex = vertex - while (currentVertex.parent?.isRed == true){ + while (currentVertex.parent?.isRed == true) { val grandparent = currentVertex.parent?.parent - if (currentVertex.parent == grandparent?.leftSon){ + if (currentVertex.parent == grandparent?.leftSon) { val uncle = grandparent?.rightSon - if (uncle?.isRed == true){ + if (uncle?.isRed == true) { currentVertex.parent?.isRed = false uncle.isRed = false grandparent.isRed = true currentVertex = grandparent - } - - else { + } else { if (currentVertex == currentVertex.parent?.rightSon) { currentVertex = currentVertex.parent ?: currentVertex rotateLeft(currentVertex) @@ -251,19 +251,15 @@ class RBSearchTree : AbstractBinarySearchTree> { val vertexForRightRotate = currentVertex.parent?.parent vertexForRightRotate?.let { rotateRight(vertexForRightRotate) } } - } - - else { + } else { val uncle = grandparent?.leftSon - if (uncle?.isRed == true){ + if (uncle?.isRed == true) { currentVertex.parent?.isRed = false uncle.isRed = false grandparent.isRed = true currentVertex = grandparent - } - - else { + } else { if (currentVertex == currentVertex.parent?.leftSon) { currentVertex = currentVertex.parent ?: currentVertex rotateRight(currentVertex) @@ -288,7 +284,7 @@ class RBSearchTree : AbstractBinarySearchTree> { private fun getChild(vertex: RBVertex) = if (vertex.leftSon != null) vertex.leftSon else vertex.rightSon - private fun replaceVertexBy(oldVertex: RBVertex, newVertex: RBVertex?){ + private fun replaceVertexBy(oldVertex: RBVertex, newVertex: RBVertex?) { if (root == oldVertex) root = newVertex else if (oldVertex == oldVertex.parent?.leftSon) oldVertex.parent?.leftSon = newVertex else oldVertex.parent?.rightSon = newVertex @@ -316,7 +312,7 @@ class RBSearchTree : AbstractBinarySearchTree> { private fun rotateRight(vertex: RBVertex) { val leftVertex: RBVertex? = vertex.leftSon vertex.leftSon = leftVertex?.rightSon - leftVertex?.rightSon.let { leftVertex?.rightSon?.parent = vertex} + leftVertex?.rightSon.let { leftVertex?.rightSon?.parent = vertex } leftVertex?.parent = vertex.parent when { vertex.parent == null -> root = leftVertex @@ -329,5 +325,9 @@ class RBSearchTree : AbstractBinarySearchTree> { constructor(comparator: Comparator? = null) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) } diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt index 71f9040..0b2fafd 100644 --- a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt @@ -1,4 +1,5 @@ package trees + import main.trees.RBSearchTree import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach @@ -11,50 +12,52 @@ class RBSearchTreeTest { private var result: MutableList> = mutableListOf() @BeforeEach - fun setup(){ + fun setup() { rbTree = RBSearchTree() } @AfterEach - fun end(){ + fun end() { for (el in rbTree) result.add(el) assertEquals(expectedResult, result) } @Test - fun `put a root to the tree`(){ + fun `put a root to the tree`() { rbTree.put(7, "hi") expectedResult = listOf(Pair(7, "hi")) } @Test - fun `put new vertex to the left`(){ + fun `put new vertex to the left`() { rbTree.put(7, "hi") rbTree.put(5, "my") expectedResult = listOf(Pair(7, "hi"), Pair(5, "my")) } @Test - fun `put new vertex to the right`(){ + fun `put new vertex to the right`() { rbTree.put(7, "hi") rbTree.put(9, "name") expectedResult = listOf(Pair(7, "hi"), Pair(9, "name")) } + @Test - fun `put existing vertex without replace`(){ + fun `put existing vertex without replace`() { rbTree.put(7, "hi") rbTree.put(7, "is", false) expectedResult = listOf(Pair(7, "hi")) } + @Test - fun `put existing vertex with replace`(){ + fun `put existing vertex with replace`() { rbTree.put(7, "hi") rbTree.put(7, "Slim") expectedResult = listOf(Pair(7, "Slim")) } @Test - fun `balance after put - uncle is rightSon and red`(){ + fun `balance after put - uncle is rightSon and red`() { rbTree.put(7, "hi") rbTree.put(5, "my") rbTree.put(9, "name") @@ -63,7 +66,7 @@ class RBSearchTreeTest { } @Test - fun `balance after put - uncle is rightSon and black + newVertex is leftSon`(){ + fun `balance after put - uncle is rightSon and black + newVertex is leftSon`() { rbTree.put(7, "hi") rbTree.put(5, "my") rbTree.put(3, "name") @@ -71,7 +74,7 @@ class RBSearchTreeTest { } @Test - fun `balance after put - uncle is rightSon and black + newVertex is rightSon`(){ + fun `balance after put - uncle is rightSon and black + newVertex is rightSon`() { rbTree.put(7, "hi") rbTree.put(5, "my") rbTree.put(6, "name") @@ -79,7 +82,7 @@ class RBSearchTreeTest { } @Test - fun `balance after put - uncle is leftSon and red`(){ + fun `balance after put - uncle is leftSon and red`() { rbTree.put(7, "hi") rbTree.put(5, "my") rbTree.put(9, "name") @@ -88,7 +91,7 @@ class RBSearchTreeTest { } @Test - fun `balance after put - uncle is leftSon and black + newVertex is rightSon`(){ + fun `balance after put - uncle is leftSon and black + newVertex is rightSon`() { rbTree.put(7, "hi") rbTree.put(9, "my") rbTree.put(10, "name") @@ -96,7 +99,7 @@ class RBSearchTreeTest { } @Test - fun `balance after put - uncle is leftSon and black + newVertex is leftSon`(){ + fun `balance after put - uncle is leftSon and black + newVertex is leftSon`() { rbTree.put(7, "hi") rbTree.put(9, "my") rbTree.put(8, "name") @@ -104,14 +107,14 @@ class RBSearchTreeTest { } @Test - fun `remove non-existent vertex`(){ + fun `remove non-existent vertex`() { rbTree.put(7, "hi") rbTree.remove(9) expectedResult = listOf(Pair(7, "hi")) } @Test - fun `delete red vertex with 0 children`(){ + fun `delete red vertex with 0 children`() { rbTree.put(7, "hi") rbTree.put(9, "my") rbTree.remove(9) @@ -119,7 +122,7 @@ class RBSearchTreeTest { } @Test - fun `delete black vertex with 1 rightSon`(){ + fun `delete black vertex with 1 rightSon`() { rbTree.put(7, "hi") rbTree.put(9, "my") rbTree.remove(7) @@ -127,7 +130,7 @@ class RBSearchTreeTest { } @Test - fun `delete black vertex with 1 leftSon`(){ + fun `delete black vertex with 1 leftSon`() { rbTree.put(7, "hi") rbTree.put(5, "my") rbTree.remove(7) @@ -135,7 +138,7 @@ class RBSearchTreeTest { } @Test - fun `delete black vertex with 2 children`(){ + fun `delete black vertex with 2 children`() { rbTree.put(7, "hi") rbTree.put(4, "my") rbTree.put(10, "name") @@ -144,7 +147,7 @@ class RBSearchTreeTest { } @Test - fun `delete red vertex with 2 children`(){ + fun `delete red vertex with 2 children`() { rbTree.put(7, "hi") rbTree.put(4, "my") rbTree.put(10, "name") @@ -155,12 +158,14 @@ class RBSearchTreeTest { rbTree.put(11, "Slim") rbTree.put(13, "Shady") rbTree.remove(10) - expectedResult = listOf(Pair(7, "hi"), Pair(11, "Slim"), Pair(12, "chka"), Pair(13, "Shady"), Pair(9, "chka"), - Pair(4, "my"), Pair(5, "chka"), Pair(3, "is")) + expectedResult = listOf( + Pair(7, "hi"), Pair(11, "Slim"), Pair(12, "chka"), Pair(13, "Shady"), Pair(9, "chka"), + Pair(4, "my"), Pair(5, "chka"), Pair(3, "is") + ) } @Test - fun `balance after remove - brother is right and black, brother's rightSon - red`(){ + fun `balance after remove - brother is right and black, brother's rightSon - red`() { rbTree.put(7, "hi") rbTree.put(4, "my") rbTree.put(10, "name") @@ -171,12 +176,14 @@ class RBSearchTreeTest { rbTree.put(11, "Slim") rbTree.put(13, "Shady") rbTree.remove(9) - expectedResult = listOf(Pair(7, "hi"), Pair(12, "chka"), Pair(13, "Shady"), Pair(10, "name"), Pair(11, "Slim"), - Pair(4, "my"), Pair(5, "chka"), Pair(3, "is")) + expectedResult = listOf( + Pair(7, "hi"), Pair(12, "chka"), Pair(13, "Shady"), Pair(10, "name"), Pair(11, "Slim"), + Pair(4, "my"), Pair(5, "chka"), Pair(3, "is") + ) } @Test - fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`(){ + fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { rbTree.put(7, "hi") rbTree.put(4, "my") rbTree.put(10, "name") @@ -186,12 +193,14 @@ class RBSearchTreeTest { rbTree.put(12, "Slim") rbTree.put(11, "Shady") rbTree.remove(9) - expectedResult = listOf(Pair(7, "hi"), Pair(11, "Shady"), Pair(12, "Slim"), Pair(10, "name"), Pair(4, "my"), - Pair(5, "chka"), Pair(3, "is")) + expectedResult = listOf( + Pair(7, "hi"), Pair(11, "Shady"), Pair(12, "Slim"), Pair(10, "name"), Pair(4, "my"), + Pair(5, "chka"), Pair(3, "is") + ) } @Test - fun `balance after remove - brother is right and black, both sons - black`(){ + fun `balance after remove - brother is right and black, both sons - black`() { rbTree.put(7, "hi") rbTree.put(4, "my") rbTree.put(10, "name") @@ -206,29 +215,33 @@ class RBSearchTreeTest { expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) } -// @Test -// fun `balance after remove - brother is red`(){ -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(3, "is") -// rbTree.put(9, "is") -// rbTree.put(12, "is") -// rbTree.put(11, "is") -// println(rbTree.getVertex(7)?.isRed) -// println(rbTree.getVertex(4)?.isRed) -// println(rbTree.getVertex(10)?.isRed) -// println(rbTree.getVertex(3)?.isRed) -// println(rbTree.getVertex(9)?.isRed) -// println(rbTree.getVertex(12)?.isRed) -// println(rbTree.getVertex(11)?.isRed) -// -// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Shady"), Pair(4, "my"), Pair(5, "chka"), -// Pair(3, "is")) -// } + @Test + fun `balance after remove - right brother is red`() { + rbTree.put(60, "sixty") + rbTree.put(33, "thirty-three") + rbTree.put(84, "eighty-four") + rbTree.put(15, "fifteen") + rbTree.put(51, "fifty-one") + rbTree.put(65, "sixty-five") + rbTree.put(96, "ninety-six") + rbTree.put(34, "thirty-four") + rbTree.put(52, "Alblack") + rbTree.put(94, "ninety-four") + rbTree.put(97, "ninety-seven") + rbTree.put(95, "ninety-five") + + //now vertex with key 96 is red, with key 65 - black + rbTree.remove(65) + + expectedResult = listOf( + Pair(60, "sixty"), Pair(96, "ninety-six"), Pair(97, "ninety-seven"), + Pair(94, "ninety-four"), Pair(95, "ninety-five"), Pair(84, "eighty-four"), Pair(33, "thirty-three"), + Pair(51, "fifty-one"), Pair(52, "Alblack"), Pair(34, "thirty-four"), Pair(15, "fifteen") + ) + } @Test - fun `balance after remove - brother is left and black, brother's rightSon - red`(){ + fun `balance after remove - brother is left and black, brother's rightSon - red`() { rbTree.put(7, "hi") rbTree.put(4, "my") rbTree.put(10, "name") @@ -239,12 +252,14 @@ class RBSearchTreeTest { rbTree.put(1, "Slim") rbTree.put(3, "Shady") rbTree.remove(5) - expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "chka"), Pair(9, "chka"), Pair(2, "is"), - Pair(4, "my"), Pair(3, "Shady"), Pair(1, "Slim")) + expectedResult = listOf( + Pair(7, "hi"), Pair(10, "name"), Pair(12, "chka"), Pair(9, "chka"), Pair(2, "is"), + Pair(4, "my"), Pair(3, "Shady"), Pair(1, "Slim") + ) } @Test - fun `balance after remove - brother is left and black, brother's leftSon - red (rightSon - black)`(){ + fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { rbTree.put(7, "hi") rbTree.put(4, "my") rbTree.put(10, "name") @@ -254,12 +269,14 @@ class RBSearchTreeTest { rbTree.put(12, "Slim") rbTree.put(3, "Shady") rbTree.remove(5) - expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(9, "chka"), Pair(3, "Shady"), - Pair(4, "my"), Pair(2, "is")) + expectedResult = listOf( + Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(9, "chka"), Pair(3, "Shady"), + Pair(4, "my"), Pair(2, "is") + ) } @Test - fun `balance after remove - brother is left and black, both sons - black`(){ + fun `balance after remove - brother is left and black, both sons - black`() { rbTree.put(7, "hi") rbTree.put(4, "my") rbTree.put(10, "name") @@ -274,4 +291,35 @@ class RBSearchTreeTest { expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) } -} \ No newline at end of file + @Test + fun `balance after remove - left brother is red`() { + rbTree.put(60, "sixty") + rbTree.put(33, "thirty-three") + rbTree.put(84, "eighty-four") + rbTree.put(15, "fifteen") + rbTree.put(51, "fifty-one") + rbTree.put(65, "sixty-five") + rbTree.put(96, "ninety-six") + rbTree.put(5, "five") + rbTree.put(27, "twenty-seven") + rbTree.put(61, "sixty-one") + rbTree.put(69, "sixty-nine") + rbTree.put(17, "seventeen") + + //now vertex with key 15 is red, with key 51 - black + rbTree.remove(51) + + expectedResult = listOf( + Pair(60, "sixty"), Pair(84, "eighty-four"), Pair(96, "ninety-six"), + Pair(65, "sixty-five"), Pair(69, "sixty-nine"), Pair(61, "sixty-one"), Pair(15, "fifteen"), + Pair(27, "twenty-seven"), Pair(33, "thirty-three"), Pair(17, "seventeen"), Pair(5, "five") + ) + } + + @Test + fun `test secondary constructor`() { + val testMap = mapOf(3 to "three", 1 to "one", 2 to "two") + rbTree = RBSearchTree(testMap) + expectedResult = listOf(Pair(2, "two"), Pair(3, "three"), Pair(1, "one")) + } +} From d847a750bc91b8bbceda351d94fd99b3ec8b3068 Mon Sep 17 00:00:00 2001 From: Kostya Oreshin <84198636+TerrMen@users.noreply.github.com> Date: Mon, 1 Apr 2024 14:09:12 +0300 Subject: [PATCH 140/227] chore: delete ci.yml --- .github/workflows/ci.yml | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 4d7a9db..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Build -on: workflow_dispatch -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Set up Java JDK - uses: actions/setup-java@v4 - with: - java-version: 21 - cache: gradle - - name: Set up Gradle - uses: gradle/actions/setup-gradle@v4 - - name: Build with Gradle - run: .gradlew build \ No newline at end of file From 5b908514ef4472433c16a56dc3cdcf3bfa4786ed Mon Sep 17 00:00:00 2001 From: Kostya Oreshin <84198636+TerrMen@users.noreply.github.com> Date: Mon, 1 Apr 2024 14:10:24 +0300 Subject: [PATCH 141/227] feat: add ci.yml --- .github/workflows/ci.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d2b8557 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,19 @@ +name: Build +on: workflow_dispatch +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Java JDK + uses: actions/setup-java@v4 + with: + java-version: 21 + cache: gradle + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + - name: Build with Gradle + run: ./gradlew build + - name: Run tests + run: ./gradlew test From 329ca922fc289cd0ed16c238438251fa40bea123 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 1 Apr 2024 17:46:29 +0300 Subject: [PATCH 142/227] test: add test coverage for AbstractTree methods --- lib/src/main/kotlin/trees/RBSearchTree.kt | 8 +- lib/src/test/kotlin/AVLTreeTests | 0 .../trees/RBSearchTreeAbstractMethodsTest.kt | 171 ++++++++++++++++++ lib/src/test/kotlin/trees/RBSearchTreeTest.kt | 1 + 4 files changed, 177 insertions(+), 3 deletions(-) delete mode 100644 lib/src/test/kotlin/AVLTreeTests create mode 100644 lib/src/test/kotlin/trees/RBSearchTreeAbstractMethodsTest.kt diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index d1cb2cb..156f67d 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -19,11 +19,12 @@ class RBSearchTree : AbstractBinarySearchTree> { //4) remove black vertex with 0 children -> just remove vertex override fun remove(key: K): V? { val vertex: RBVertex = getVertex(key) ?: return null + --size val value = vertex.value - if (needToBalance(vertex)) balanceAfterRemove(vertex) + if (vertex == root && size == 0L) root = null + else if (needToBalance(vertex)) balanceAfterRemove(vertex) - --size return value } @@ -181,6 +182,7 @@ class RBSearchTree : AbstractBinarySearchTree> { var currentVertex: RBVertex? = root var parent: RBVertex? = null var isLeft: Boolean = false + ++size while (currentVertex != null) { when (compareKeys(key, currentVertex.key)) { @@ -192,6 +194,7 @@ class RBSearchTree : AbstractBinarySearchTree> { 0 -> { if (replaceIfExists) currentVertex.value = value + --size break } @@ -211,7 +214,6 @@ class RBSearchTree : AbstractBinarySearchTree> { } balanceAfterPut(currentVertex) - ++size } //we need to balance tree in two cases diff --git a/lib/src/test/kotlin/AVLTreeTests b/lib/src/test/kotlin/AVLTreeTests deleted file mode 100644 index e69de29..0000000 diff --git a/lib/src/test/kotlin/trees/RBSearchTreeAbstractMethodsTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeAbstractMethodsTest.kt new file mode 100644 index 0000000..143707e --- /dev/null +++ b/lib/src/test/kotlin/trees/RBSearchTreeAbstractMethodsTest.kt @@ -0,0 +1,171 @@ +package trees + +import main.trees.RBSearchTree +import main.vertexes.RBVertex +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class RBSearchTreeAbstractMethodsTest { + private lateinit var rbTree: RBSearchTree + + @BeforeEach + fun setup() { + rbTree = RBSearchTree() + } + + @Test + fun `test size after put`(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + val previousSize = rbTree.size() + val expectedResult = previousSize + 1 + rbTree.put(11, segment.random()) + assertEquals(expectedResult, rbTree.size()) + } + + @Test + fun `test size after remove`(){ + val segment = 1..10 + val listOfKeys: MutableList = mutableListOf() + for (i in 0 until segment.random()){ + val key = segment.random() + listOfKeys.add(key) + rbTree.put(key, segment.random()) + } + val previousSize = rbTree.size() + val expectedResult = previousSize - 1 + rbTree.remove(listOfKeys.random()) + assertEquals(expectedResult, rbTree.size()) + } + + @Test + fun `size can't be negative`(){ + val segment = 1..10 + val listOfKeys: MutableList = mutableListOf() + for (i in 0 until segment.random()){ + val key = segment.random() + listOfKeys.add(key) + rbTree.put(key, segment.random()) + } + listOfKeys.forEach { rbTree.remove(it) } + rbTree.remove(segment.random()) + assertEquals(0, rbTree.size()) + } + + @Test + fun `check for empty`(){ + val segment = 1..10 + val listOfKeys: MutableList = mutableListOf() + for (i in 0 until segment.random()){ + val key = segment.random() + listOfKeys.add(key) + rbTree.put(key, segment.random()) + } + listOfKeys.forEach { rbTree.remove(it) } + assertEquals(true, rbTree.isEmpty()) + } + + @Test + fun `get`(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + rbTree.put(7, 44536643) + assertEquals(44536643, rbTree.get(7)) + } + + @Test + fun `get but such vertex doesn't exist`(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + assertEquals(null, rbTree.get(11)) + } + + @Test + fun getPair(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + rbTree.put(7, 44536643) + assertEquals(Pair(7, 44536643), rbTree.getPair(7)) + } + + @Test + fun `getPair but such vertex doesn't exist`(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + assertEquals(null, rbTree.getPair(11)) + } + + @Test + fun getMin(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + rbTree.put(1, 44536643) + assertEquals(44536643, rbTree.getMin()) + } + + @Test + fun `getMin but tree is empty`(){ + assertEquals(null, rbTree.getMin()) + } + + @Test + fun getMax(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + rbTree.put(10, 44536643) + assertEquals(44536643, rbTree.getMax()) + } + + @Test + fun `getMax but tree is empty`(){ + assertEquals(null, rbTree.getMax()) + } + + @Test + fun getMinKeyPair(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + rbTree.put(1, 44536643) + assertEquals(Pair(1, 44536643), rbTree.getMinKeyPair()) + } + + @Test + fun `getMinKeyPair but tree is empty`(){ + assertEquals(null, rbTree.getMinKeyPair()) + } + + @Test + fun getMaxKeyPair(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + rbTree.put(10, 44536643) + assertEquals(Pair(10, 44536643), rbTree.getMaxKeyPair()) + } + + @Test + fun `getMaxKeyPair but tree is empty`(){ + assertEquals(null, rbTree.getMaxKeyPair()) + } + +// @Test +// fun putAll(){ +// TODO() +// } + + @Test + fun removeAndReturnPair(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + rbTree.put(7, 44536643) + assertEquals(Pair(7, 44536643), rbTree.removeAndReturnPair(7)) + assertEquals(null, rbTree.get(7)) + } + + @Test + fun `removeAndReturnPair but vertex doesn't exist`(){ + val segment = 1..10 + for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) + assertEquals(null, rbTree.removeAndReturnPair(11)) + } +} \ No newline at end of file diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt index 0b2fafd..cd4ebea 100644 --- a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt @@ -322,4 +322,5 @@ class RBSearchTreeTest { rbTree = RBSearchTree(testMap) expectedResult = listOf(Pair(2, "two"), Pair(3, "three"), Pair(1, "one")) } + } From 2cbb182d968483b7e821252cd0e6097a117287d4 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 20:11:29 +0300 Subject: [PATCH 143/227] feat: write tests for TreeIterator class --- lib/src/test/kotlin/TreeIteratorTests.kt | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 lib/src/test/kotlin/TreeIteratorTests.kt diff --git a/lib/src/test/kotlin/TreeIteratorTests.kt b/lib/src/test/kotlin/TreeIteratorTests.kt new file mode 100644 index 0000000..174d0d5 --- /dev/null +++ b/lib/src/test/kotlin/TreeIteratorTests.kt @@ -0,0 +1,47 @@ +import main.trees.AVLSearchTree +import main.vertexes.SimpleBSTVertex +import org.junit.jupiter.api.Assertions.assertEquals +import kotlin.test.Test + +class IteratorTests { + + @Test + fun `add in stack`() { + val vertex = SimpleBSTVertex(1, "one") + val iterator = TestIterator(vertex) + assertEquals(1, iterator.getTreeStack().removeLast().key) + } + + @Test + fun `hasNext if stack is not empty`() { + val vertex = SimpleBSTVertex(1, "one") + val iterator = TestIterator(vertex) + assertEquals(true, iterator.hasNext()) + } + + @Test + fun `check if method next() works correctly`() { + val vertex = SimpleBSTVertex(1, "one") + val iterator = TestIterator(vertex) + val deletedVertex = iterator.next() + assertEquals(Pair(1, "one"), deletedVertex) + } + + @Test + fun `hasNext if stack is empty`() { + val vertex = SimpleBSTVertex(1, "one") + val iterator = TestIterator(vertex) + iterator.next() + assertEquals(false, iterator.hasNext()) + } + + @Test + fun `check if method iterator() works correctly`() { + val tree = AVLSearchTree(mapOf(Pair(3, "three"), Pair(1, "one"), Pair(2, "two"), Pair(150, "one-five-zero"))) + val list: MutableList> = mutableListOf() + for (pair in tree) { + list.add(pair) + } + assertEquals(mutableListOf(Pair(2, "two"), Pair(3, "three"), Pair(150, "one-five-zero"), Pair(1, "one")), list) + } +} \ No newline at end of file From 4fe22c61b6e1d727c4959ecb05de2d03f9c7c333 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 20:19:02 +0300 Subject: [PATCH 144/227] fix: remove 'get root' test --- lib/src/test/kotlin/SimpleBSTreeTests.kt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/src/test/kotlin/SimpleBSTreeTests.kt b/lib/src/test/kotlin/SimpleBSTreeTests.kt index 3204aa6..975984a 100644 --- a/lib/src/test/kotlin/SimpleBSTreeTests.kt +++ b/lib/src/test/kotlin/SimpleBSTreeTests.kt @@ -3,13 +3,6 @@ import kotlin.test.assertEquals class SimpleBSTTests { - @Test - fun `get root`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) - val root = tree.getTreeRoot() - assertEquals(1, root?.key) - } - @Test fun `put vertex after remove root test`() { val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) From d0360e3ebd089f79b5182de2064fd5dd14fcab9a Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 20:55:19 +0300 Subject: [PATCH 145/227] fix: add default comparator value null in constructor --- lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index d165ea8..324e28a 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -74,7 +74,7 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree?) : super(comparator) + constructor(comparator: Comparator? = null) : super(comparator) constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } From d9ebfdbbf1bbdf844ef26a8f0e5a6a894d6873a9 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 21:00:31 +0300 Subject: [PATCH 146/227] fix: add default comparator value null in constructor --- lib/src/test/kotlin/TestSimpleBST.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/test/kotlin/TestSimpleBST.kt b/lib/src/test/kotlin/TestSimpleBST.kt index 02b3dea..0ae7b58 100644 --- a/lib/src/test/kotlin/TestSimpleBST.kt +++ b/lib/src/test/kotlin/TestSimpleBST.kt @@ -4,7 +4,7 @@ import main.vertexes.SimpleBSTVertex class TestSimpleBST : SimpleBinarySearchTree { fun getTreeRoot(): SimpleBSTVertex? {return root} - constructor(comparator: Comparator?) : super(comparator) + constructor(comparator: Comparator? = null) : super(comparator) constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } \ No newline at end of file From 4bb84e00e7381ba6d15ad03f5d27f5c3d1767ae5 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 1 Apr 2024 21:17:36 +0300 Subject: [PATCH 147/227] ci: add new cases for checks --- .github/workflows/ci.yml | 18 +++++++++++++++--- lib/src/test/kotlin/AVLTreeTests | 0 2 files changed, 15 insertions(+), 3 deletions(-) delete mode 100644 lib/src/test/kotlin/AVLTreeTests diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d2b8557..25f9bf2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,16 @@ name: Build -on: workflow_dispatch + +on: + pull_request: + branches: + - main + - develop + push: + branches: + - main + - develop + workflow_dispatch: + jobs: build: runs-on: ubuntu-latest @@ -9,10 +20,11 @@ jobs: - name: Set up Java JDK uses: actions/setup-java@v4 with: - java-version: 21 + java-version: 17 cache: gradle + distribution: "temurin" - name: Set up Gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v3 - name: Build with Gradle run: ./gradlew build - name: Run tests diff --git a/lib/src/test/kotlin/AVLTreeTests b/lib/src/test/kotlin/AVLTreeTests deleted file mode 100644 index e69de29..0000000 From bb05faba8eb9af1f3156c03608e2b2ffdcfd2450 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 1 Apr 2024 21:18:15 +0300 Subject: [PATCH 148/227] refactor: add setup before each test, coverage 100% --- lib/src/test/kotlin/SimpleBSTreeTests.kt | 111 ++++++++++++----------- 1 file changed, 58 insertions(+), 53 deletions(-) diff --git a/lib/src/test/kotlin/SimpleBSTreeTests.kt b/lib/src/test/kotlin/SimpleBSTreeTests.kt index 975984a..8557e2d 100644 --- a/lib/src/test/kotlin/SimpleBSTreeTests.kt +++ b/lib/src/test/kotlin/SimpleBSTreeTests.kt @@ -1,29 +1,32 @@ +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import kotlin.test.assertEquals class SimpleBSTTests { - - @Test - fun `put vertex after remove root test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) - val deletedValue = tree.remove(1) - assertEquals("one", deletedValue) - tree.put(2, "two") - assertEquals("two", tree.getTreeRoot()?.value) - assertEquals(1, tree.size()) + private lateinit var tree: TestSimpleBST + @BeforeEach + fun setup() { + tree = TestSimpleBST() } @Test - fun `replacing value of existing key test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "old"))) + fun `replacing value of existing key`() { + tree.put(1, "old") tree.put(1, "new", true) assertEquals("new", tree.getTreeRoot()?.value) assertEquals(1, tree.size()) } @Test - fun `non replacing value of existing key test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "old"))) + fun `create tree from a map`() { + val tree = TestSimpleBST(mapOf(Pair(1, "cat"), Pair(2, "dog"))) + assertEquals("cat", tree.getTreeRoot()?.value) + assertEquals(2, tree.size()) + } + + @Test + fun `non replacing value of existing key`() { + tree.put(1, "old") tree.put(1, "new", false) assertEquals("old", tree.getTreeRoot()?.value) assertEquals(1, tree.size()) @@ -31,7 +34,7 @@ class SimpleBSTTests { @Test fun `put key more than root key test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + tree.put(1, "one") tree.put(2, "right") assertEquals("right", tree.getTreeRoot()?.rightSon?.value) assertEquals(2, tree.size()) @@ -39,7 +42,7 @@ class SimpleBSTTests { @Test fun `put key less than root key test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + tree.put(1, "one") tree.put(0, "left") assertEquals("left", tree.getTreeRoot()?.leftSon?.value) assertEquals(2, tree.size()) @@ -47,7 +50,7 @@ class SimpleBSTTests { @Test fun `put many vertexes test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(0, "hello"))) + tree.put(0, "hello") for (key in 1 .. 6) { tree.put(key, "hello") } @@ -56,22 +59,18 @@ class SimpleBSTTests { @Test fun `put many vertexes with method putAll() test`() { - val map: Map = mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") - ) - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) - tree.putAll(map) + tree.putAll(mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two"))) assertEquals(6, tree.size()) } @Test fun `put many vertexes with same key test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) for (i in 1..6) { tree.put(1, "one") } @@ -80,7 +79,7 @@ class SimpleBSTTests { @Test fun `remove no sons root test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + tree.put(1, "one") tree.remove(1) assertEquals(null, tree.getTreeRoot()) assertEquals(0, tree.size()) @@ -88,7 +87,7 @@ class SimpleBSTTests { @Test fun `remove no sons vertex test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(0, "zero"))) + tree.putAll(mapOf(Pair(1, "one"), Pair(0, "zero"))) tree.remove(0) assertEquals(null, tree.getTreeRoot()?.leftSon) assertEquals(1, tree.size()) @@ -96,7 +95,7 @@ class SimpleBSTTests { @Test fun `remove one left son vertex test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(0, "zero"), Pair(-1, "negative"))) + tree.putAll(mapOf(Pair(1, "one"), Pair(0, "zero"), Pair(-1, "negative"))) tree.remove(0) assertEquals(-1, tree.getTreeRoot()?.leftSon?.key) assertEquals(2, tree.size()) @@ -104,7 +103,7 @@ class SimpleBSTTests { @Test fun `remove one right son vertex test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(2, "two"), Pair(3, "three"))) + tree.putAll(mapOf(Pair(1, "one"), Pair(2, "two"), Pair(3, "three"))) tree.remove(2) assertEquals(3, tree.getTreeRoot()?.rightSon?.key) assertEquals(2, tree.size()) @@ -112,7 +111,7 @@ class SimpleBSTTests { @Test fun `remove two sons vertex test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(2, "two"), Pair(0, "zero"))) + tree.putAll(mapOf(Pair(1, "one"), Pair(2, "two"), Pair(0, "zero"))) tree.remove(1) assertEquals(2, tree.getTreeRoot()?.key) assertEquals(2, tree.size()) @@ -120,16 +119,14 @@ class SimpleBSTTests { @Test fun `remove two sons with right subtree vertex test`() { - val tree: TestSimpleBST = TestSimpleBST( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") - ) - ) + tree.putAll(mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two") + )) tree.remove(1) assertEquals(2, tree.getTreeRoot()?.key) assertEquals(5, tree.size()) @@ -137,16 +134,14 @@ class SimpleBSTTests { @Test fun `remove many vertex test`() { - val tree: TestSimpleBST = TestSimpleBST( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") - ) - ) + tree.putAll(mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two") + )) for (key in 0..5) { tree.remove(key) } @@ -156,9 +151,19 @@ class SimpleBSTTests { @Test fun `remove non-existing value`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) + tree.put(1, "one") val deletedValue = tree.remove(100) assertEquals(null, deletedValue) assertEquals(1, tree.size()) } + + @Test + fun `put vertex after remove root test`() { + tree.put(1, "one") + val deletedValue = tree.remove(1) + assertEquals("one", deletedValue) + tree.put(2, "two") + assertEquals("two", tree.getTreeRoot()?.value) + assertEquals(1, tree.size()) + } } \ No newline at end of file From ebc16997d041647d83d60ecbc712028021a3caca Mon Sep 17 00:00:00 2001 From: Victoria Lustyuk <130183523+vicitori@users.noreply.github.com> Date: Mon, 1 Apr 2024 22:24:04 +0300 Subject: [PATCH 149/227] refactor: update README.md --- README.md | 83 ++++++++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 48f976c..ef1a027 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,31 @@ -

badge +

badge badge -badge

+badge

-# BinTreeKit - - -## Table of Contents -- [About Project](#about-project) -- [Usage](#usage) -- [Library Features](#library-features) - - [Constructors](#constructors) - - [Methods](#methods) - - [Tree Properties](#tree-properties) - - [Iterator](#iterator) - - [Constructors](#constructors-1) - - [Methods](#methods-1) -- [Developers](#developers) -- [Contributing](#contributing) -- [License](#license) +

BinTreeKit

## About Project `BinTreeKit` is a library that provides implementations for three types of trees: `SimpleBinarySearchTree`, `AVLSearchTree` and `RBSearchTree`. The library is designed to simplify the process of managing hierarchical data, allowing Kotlin developers to focus on building robust and scalable applications. +
+ Table of Contents + + + - [About Project](#about-project) + - [Usage](#usage) + - [Library Features](#library-features) + - [Constructors](#constructors) + - [Methods](#methods) + - [Tree Properties](#tree-properties) + - [Iterator](#iterator) + - [Constructors](#constructors-1) + - [Methods](#methods-1) + - [Developers](#developers) + - [Contributing](#contributing) + - [License](#license) +
+ ## Usage 1. **Importing Classes:** @@ -64,55 +67,47 @@ for (pair in avlTree) { ## Library Features -#### Constructors +### Constructors - `constructor(comparator: Comparator? = null)` - constructs a new AbstractBinarySearchTree instance with the given comparator. - `constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null)` - constructs a new AbstractBinarySearchTree instance initialized with the contents of the given map. + > The `comparator` to be used optional for ordering keys in the tree. - The `comparator` to be used optional for ordering keys in the tree. - - -#### Methods - -- put - - - `put(key: K, value: V, replaceIfExists : Boolean = true)` - inserts the specified key-value pair into the tree. - - `putAll(map: Map, replaceIfExists: Boolean = true)` - inserts all key-value pairs from the given map into the tree. +### Methods - replaceIfExists is an optional (default is true) Boolean flag indicating whether to replace the value if the key already exists in the tree. +- `put(key: K, value: V, replaceIfExists : Boolean = true)` - inserts the specified key-value pair into the tree. -- remove +- `putAll(map: Map, replaceIfExists: Boolean = true)` - inserts all key-value pairs from the given map into the tree. - - `remove(key: K): V?` - removes the key-value pair with the specified key from the tree and returns value associated with the removed key, or `null` if the key was not found in the tree. + > `replaceIfExists` is an optional (default is true) Boolean flag indicating whether to replace the value if the key already exists in the tree. -- get +- `remove(key: K): V?` - removes the key-value pair with the specified key from the tree and returns value associated with the removed key, or `null` if the key was not found in the tree. - - `get(key: K): V?` - retrieves the value associated with the specified key from the tree and returns value associated with the specified key, or `null` if the key was not found in the tree. - - `getPair(key: K): Pair?` - retrieves the key-value pair associated with the specified key from the tree and returns the key-value pair associated with the specified key, or `null` if the key was not found in the tree. +- `get(key: K): V?` - retrieves the value associated with the specified key from the tree and returns value associated with the specified key, or `null` if the key was not found in the tree. - - `getMin(): V?` - retrieves the value associated with the minimum key in the tree and returns the value associated with the minimum key, or `null` if the tree is empty. +- `getPair(key: K): Pair?` - retrieves the key-value pair associated with the specified key from the tree and returns the key-value pair associated with the specified key, or `null` if the key was not found in the tree. - - `getMax(): V?` - retrieves the value associated with the maximum key in the tree and returns the value associated with the maximum key, or `null` if the tree is empty. +- `getMin(): V?` - retrieves the value associated with the minimum key in the tree and returns the value associated with the minimum key, or `null` if the tree is empty. - - `getMinKeyPair(): Pair?` - retrieves the key-value pair associated with the minimum key in the tree and returns the key-value pair associated with the minimum key, or `null` if the tree is empty. +- `getMax(): V?` - retrieves the value associated with the maximum key in the tree and returns the value associated with the maximum key, or `null` if the tree is empty. - - `getMaxKeyPair(): Pair?` - retrieves the key-value pair associated with the maximum key in the tree and returns the key-value pair associated with the maximum key, or `null` if the tree is empty. +- `getMinKeyPair(): Pair?` - retrieves the key-value pair associated with the minimum key in the tree and returns the key-value pair associated with the minimum key, or `null` if the tree is empty. +- `getMaxKeyPair(): Pair?` - retrieves the key-value pair associated with the maximum key in the tree and returns the key-value pair associated with the maximum key, or `null` if the tree is empty. -- others - - `size(): Long` - returns the number of key-value pairs in the tree. +- `size(): Long` - returns the number of key-value pairs in the tree. - - `isEmpty(): Boolean` checks whether the tree is empty and returns `true` if the tree is empty, `false` otherwise. +- `isEmpty(): Boolean` checks whether the tree is empty and returns `true` if the tree is empty, `false` otherwise. -#### Tree Properties +### Tree Properties - `size: Long` - the number of key-value pairs currently stored in the tree. @@ -120,11 +115,11 @@ for (pair in avlTree) { - `isEmpty: Boolean` - indicates whether the tree is empty. -#### Iterator +### Iterator ###### Constructors - `constructor(vertex: N?)` - constructs a new TreeIterator instance with the specified starting vertex. - vertex is the starting vertex of the iterator. + > `vertex` is the starting vertex of the iterator. ###### Methods From 3ffbbfa03eb0242198eab49f33c037c361615f3e Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 1 Apr 2024 23:51:57 +0300 Subject: [PATCH 150/227] ci: implement linter --- .github/workflows/ktlint.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/ktlint.yml diff --git a/.github/workflows/ktlint.yml b/.github/workflows/ktlint.yml new file mode 100644 index 0000000..8fcfbd4 --- /dev/null +++ b/.github/workflows/ktlint.yml @@ -0,0 +1,23 @@ +name: ktlint + +on: + pull_request: + branches: + - main + - develop + push: + branches: + - main + - develop + workflow_dispatch: + +jobs: + ktlint: + runs-on: ubuntu-latest + + steps: + - name: "checkout" + uses: actions/checkout@v2 + + - name: "ktlint" + uses: "block42-blockchain-company/ktlint-action@master" \ No newline at end of file From f70e0245bd6bb9d8ee47a287456d4514b7cf55f8 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 00:11:33 +0300 Subject: [PATCH 151/227] style: changes according to linter --- lib/src/main/kotlin/iterator/TreeIterator.kt | 5 +- lib/src/main/kotlin/trees/AVLSearchTree.kt | 189 ++++++++++-------- .../kotlin/trees/AbstractBinarySearchTree.kt | 40 ++-- lib/src/main/kotlin/trees/RBSearchTree.kt | 166 ++++++++------- .../kotlin/trees/SimpleBinarySearchTree.kt | 18 +- lib/src/test/kotlin/AVLTreeTests | 0 lib/src/test/kotlin/SimpleBSTreeTests.kt | 49 ++--- lib/src/test/kotlin/TestSimpleBST.kt | 4 +- 8 files changed, 252 insertions(+), 219 deletions(-) delete mode 100644 lib/src/test/kotlin/AVLTreeTests diff --git a/lib/src/main/kotlin/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt index bad1c15..e8ba2b2 100644 --- a/lib/src/main/kotlin/iterator/TreeIterator.kt +++ b/lib/src/main/kotlin/iterator/TreeIterator.kt @@ -1,10 +1,11 @@ package main.iterator + import main.vertexes.InterfaceBSTVertex import java.util.LinkedList -internal class TreeIterator>( +internal class TreeIterator>( vertex: N? -): Iterator> { +) : Iterator> { private val stack = LinkedList() init { diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index c8d55db..c216a21 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -1,11 +1,12 @@ package main.trees + import main.vertexes.AVLVertex -class AVLSearchTree : AbstractBinarySearchTree> { +class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { if (!isEmpty()) { - when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { + when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { null, root -> {} else -> root = putRecReturned } @@ -15,22 +16,26 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ } - private fun putRec(key: K, value: V, - replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { - fun putRecShort(vrtx : AVLVertex) : AVLVertex? { + private fun putRec( + key: K, value: V, + replaceIfExists: Boolean, vertex: AVLVertex + ): AVLVertex? { + fun putRecShort(vrtx: AVLVertex): AVLVertex? { return putRec(key, value, replaceIfExists, vrtx) - } - val nextCallReturned : AVLVertex? + } + + val nextCallReturned: AVLVertex? when (compareKeys(key, vertex.key)) { -1 -> { - if (vertex.leftSon == null){ + if (vertex.leftSon == null) { vertex.leftSon = AVLVertex(key, value) vertex.sonsHeightDiff++ size++ return vertex } - nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) + nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) } + 0 -> { if (replaceIfExists) { vertex.key = key @@ -38,6 +43,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { } return null } + else -> { if (vertex.rightSon == null) { vertex.rightSon = AVLVertex(key, value) @@ -45,36 +51,37 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex } - nextCallReturned = putRecShort(vertex.rightSon as AVLVertex ) + nextCallReturned = putRecShort(vertex.rightSon as AVLVertex) } } if (nextCallReturned == null) return null - fun doBalanceChoreWhenLeftSubTreeChanged() : AVLVertex? { + fun doBalanceChoreWhenLeftSubTreeChanged(): AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null if (vertex.sonsHeightDiff + 1 == 2) return balance(vertex) vertex.sonsHeightDiff++ - return vertex + return vertex } - fun doBalanceChoreWhenRightSubTreeChanged() : AVLVertex? { + + fun doBalanceChoreWhenRightSubTreeChanged(): AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null if (vertex.sonsHeightDiff - 1 == -2) return balance(vertex) vertex.sonsHeightDiff-- return vertex } - when (nextCallReturned){ + when (nextCallReturned) { vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() - vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() + vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() else -> { if (compareKeys(nextCallReturned.key, vertex.key) == -1) { - vertex.leftSon = nextCallReturned - return doBalanceChoreWhenLeftSubTreeChanged() + vertex.leftSon = nextCallReturned + return doBalanceChoreWhenLeftSubTreeChanged() } - vertex.rightSon = nextCallReturned - return doBalanceChoreWhenRightSubTreeChanged() + vertex.rightSon = nextCallReturned + return doBalanceChoreWhenRightSubTreeChanged() } } } - + override fun remove(key: K): V? { if (!isEmpty()) { val removeRecReturned = removeRec(key, root as AVLVertex) @@ -84,6 +91,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { if (removeRecReturned.component2() != root) root = removeRecReturned.component2() } + RemovalStage.C -> root = null } return removeRecReturned.component3() @@ -91,13 +99,13 @@ class AVLSearchTree : AbstractBinarySearchTree> { return null } - enum class RemovalStage {A, B, C} + enum class RemovalStage { A, B, C } // a - don't need tree changes anymore // b - probably need some tree changes, but not nulling // c - need to null due "Son" property of (if exists) the parent of removed vertex + b - private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { - val nextCallReturned : Triple ?, V?> + private fun removeRec(key: K, vertex: AVLVertex): Triple, V?> { + val nextCallReturned: Triple?, V?> // Triple consists of: // 1) removal stage // 2) if RemovalStage == a : just a vertex (don't need it later) @@ -107,46 +115,54 @@ class AVLSearchTree : AbstractBinarySearchTree> { when (compareKeys(key, vertex.key)) { -1 -> { if (vertex.leftSon == null) return Triple(RemovalStage.A, vertex, null) - nextCallReturned = removeRec(key, vertex.leftSon as AVLVertex) + nextCallReturned = removeRec(key, vertex.leftSon as AVLVertex) } + 1 -> { if (vertex.rightSon == null) return Triple(RemovalStage.A, vertex, null) - nextCallReturned = removeRec(key, vertex.rightSon as AVLVertex) + nextCallReturned = removeRec(key, vertex.rightSon as AVLVertex) } + else -> { return when ((vertex.leftSon == null) to (vertex.rightSon == null)) { true to true -> { size-- Triple(RemovalStage.C, vertex, vertex.value) } + true to false -> { size-- - Triple(RemovalStage.C, vertex.rightSon as AVLVertex, vertex.value) - } - false to true -> { + Triple(RemovalStage.C, vertex.rightSon as AVLVertex, vertex.value) + } + + false to true -> { size-- - Triple(RemovalStage.C, vertex.leftSon as AVLVertex, vertex.value) + Triple(RemovalStage.C, vertex.leftSon as AVLVertex, vertex.value) } - else -> Triple(RemovalStage.C, - prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) + + else -> Triple( + RemovalStage.C, + prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value + ) } - } + } } - fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { + fun doBalanceChoreWhenLeftSubTreeChanged(): Triple, V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff - 1 == -2) + if (vertex.sonsHeightDiff - 1 == -2) return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) vertex.sonsHeightDiff-- - return Triple(RemovalStage.B, vertex, nextCallReturned.third) + return Triple(RemovalStage.B, vertex, nextCallReturned.third) } - fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { + + fun doBalanceChoreWhenRightSubTreeChanged(): Triple, V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff + 1 == 2) + if (vertex.sonsHeightDiff + 1 == 2) return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) vertex.sonsHeightDiff++ - return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) + return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) } when (nextCallReturned.component1()) { RemovalStage.A -> return nextCallReturned @@ -159,28 +175,31 @@ class AVLSearchTree : AbstractBinarySearchTree> { vertex.leftSon = nextCallReturned.component2() return doBalanceChoreWhenLeftSubTreeChanged() } + else -> { vertex.rightSon = nextCallReturned.component2() return doBalanceChoreWhenRightSubTreeChanged() } } } + RemovalStage.C -> when (compareKeys(nextCallReturned.component2().key, vertex.key)) { -1 -> { vertex.leftSon = null return doBalanceChoreWhenLeftSubTreeChanged() } + else -> { vertex.rightSon = null return doBalanceChoreWhenRightSubTreeChanged() } - } - + } + } } - private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex? { + private fun prepareLargestLowerToReplaceVertex(vertex: AVLVertex): AVLVertex? { val substitute = getMaxKeyNodeRec(vertex.leftSon) if (substitute == null) return null remove(substitute.key) @@ -190,21 +209,21 @@ class AVLSearchTree : AbstractBinarySearchTree> { return substitute } - private fun balance(curVertex: AVLVertex) : AVLVertex { - var (rightSon, leftSon) = List?>(2){null} - fun setTwoSonHeightDiffs(values : Pair) { + private fun balance(curVertex: AVLVertex): AVLVertex { + var (rightSon, leftSon) = List?>(2) { null } + fun setTwoSonHeightDiffs(values: Pair) { curVertex.sonsHeightDiff = values.component1() - if (rightSon != null){ - (rightSon as AVLVertex).sonsHeightDiff = values.component2() + if (rightSon != null) { + (rightSon as AVLVertex).sonsHeightDiff = values.component2() return } - (leftSon as AVLVertex).sonsHeightDiff = values.component2() + (leftSon as AVLVertex).sonsHeightDiff = values.component2() } - - if(curVertex.sonsHeightDiff == -1) { - rightSon = curVertex.rightSon as AVLVertex + + if (curVertex.sonsHeightDiff == -1) { + rightSon = curVertex.rightSon as AVLVertex return if (rightSon.sonsHeightDiff == 1) { - val rightSonSLeftSon = rightSon.leftSon as AVLVertex + val rightSonSLeftSon = rightSon.leftSon as AVLVertex val subtreeRoot = bigRotateLeft(curVertex, rightSon) setTwoSonHeightDiffs( when (rightSonSLeftSon.sonsHeightDiff) { @@ -215,66 +234,68 @@ class AVLSearchTree : AbstractBinarySearchTree> { ) rightSonSLeftSon.sonsHeightDiff = 0 subtreeRoot - } - else { + } else { val subtreeRoot = rotateLeft(curVertex, rightSon) setTwoSonHeightDiffs( if (rightSon.sonsHeightDiff == 0) -1 to 1 else 0 to 0 - ) + ) subtreeRoot } } - leftSon = curVertex.leftSon as AVLVertex - return if (leftSon.sonsHeightDiff == -1) { - val leftSonSRightSon = leftSon.rightSon as AVLVertex - val subtreeRoot = bigRotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( - when (leftSonSRightSon.sonsHeightDiff) { - -1 -> 0 to 1 - 1 -> -1 to 0 - else -> 0 to 0 - } - ) - leftSonSRightSon.sonsHeightDiff = 0 - subtreeRoot - } - else { - val subtreeRoot = rotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( - if (leftSon.sonsHeightDiff == 0) 1 to -1 - else 0 to 0 - ) - subtreeRoot - } + leftSon = curVertex.leftSon as AVLVertex + return if (leftSon.sonsHeightDiff == -1) { + val leftSonSRightSon = leftSon.rightSon as AVLVertex + val subtreeRoot = bigRotateRight(curVertex, leftSon) + setTwoSonHeightDiffs( + when (leftSonSRightSon.sonsHeightDiff) { + -1 -> 0 to 1 + 1 -> -1 to 0 + else -> 0 to 0 + } + ) + leftSonSRightSon.sonsHeightDiff = 0 + subtreeRoot + } else { + val subtreeRoot = rotateRight(curVertex, leftSon) + setTwoSonHeightDiffs( + if (leftSon.sonsHeightDiff == 0) 1 to -1 + else 0 to 0 + ) + subtreeRoot + } } - private fun rotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { + private fun rotateLeft(curVertex: AVLVertex, rightSon: AVLVertex): AVLVertex { curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex return rightSon } - private fun rotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { + private fun rotateRight(curVertex: AVLVertex, leftSon: AVLVertex): AVLVertex { curVertex.leftSon = leftSon.rightSon leftSon.rightSon = curVertex return leftSon } - - private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { - val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) + + private fun bigRotateLeft(curVertex: AVLVertex, rightSon: AVLVertex): AVLVertex { + val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) curVertex.rightSon = curRightSon return rotateLeft(curVertex, curRightSon) } - private fun bigRotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { - val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) + private fun bigRotateRight(curVertex: AVLVertex, leftSon: AVLVertex): AVLVertex { + val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) curVertex.leftSon = curLeftSon return rotateRight(curVertex, curLeftSon) } constructor (comparator: Comparator? = null) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) } diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index d88c536..d985204 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -1,22 +1,29 @@ package main.trees + import main.vertexes.InterfaceBSTVertex import main.iterator.TreeIterator abstract class AbstractBinarySearchTree> { protected var comparator: Comparator? = null - protected var size : Long = 0L - protected var root : N? = null + protected var size: Long = 0L + protected var root: N? = null operator fun iterator(): Iterator> { return TreeIterator(root) } - fun size(): Long {return size} + fun size(): Long { + return size + } + + fun isEmpty(): Boolean { + return size == 0L + } - fun isEmpty(): Boolean {return size == 0L} - - fun get(key: K): V? {return getRec(key)} + fun get(key: K): V? { + return getRec(key) + } fun getPair(key: K): Pair? { val value = get(key) @@ -28,7 +35,7 @@ abstract class AbstractBinarySearchTree> { return if (minKeyNode == null) null else minKeyNode.value } - fun getMax(): V?{ + fun getMax(): V? { val maxKeyNode = getMaxKeyNodeRec() return if (maxKeyNode == null) null else maxKeyNode.value } @@ -43,7 +50,7 @@ abstract class AbstractBinarySearchTree> { return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) } - abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) + abstract fun put(key: K, value: V, replaceIfExists: Boolean = true) fun putAll(map: Map, replaceIfExists: Boolean = true) { for (pair in map) put(pair.key, pair.value, replaceIfExists) @@ -65,7 +72,7 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMinKeyNodeRec(vertex: N? = root) : N? { + protected fun getMinKeyNodeRec(vertex: N? = root): N? { if (vertex == null) return null else { return if (vertex.leftSon == null) vertex @@ -73,7 +80,7 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMaxKeyNodeRec(vertex: N? = root) : N? { + protected fun getMaxKeyNodeRec(vertex: N? = root): N? { if (vertex == null) return null else { return if (vertex.rightSon == null) vertex @@ -81,19 +88,18 @@ abstract class AbstractBinarySearchTree> { } } - protected fun compareKeys(firstKey: K, secondKey: K): Int{ + protected fun compareKeys(firstKey: K, secondKey: K): Int { val cpr = comparator return if (cpr != null) { when (cpr.compare(firstKey, secondKey)) { - in Int.MIN_VALUE .. -1 -> -1 - 0 -> 0 + in Int.MIN_VALUE..-1 -> -1 + 0 -> 0 else -> 1 } - } - else { + } else { val comparableKey = firstKey as Comparable - when (comparableKey.compareTo(secondKey)) { - in Int.MIN_VALUE .. -1 -> -1 + when (comparableKey.compareTo(secondKey)) { + in Int.MIN_VALUE..-1 -> -1 0 -> 0 else -> 1 } diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index e9546a3..7aed4b0 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -1,35 +1,34 @@ package main.trees + import main.vertexes.RBVertex -class RBSearchTree : AbstractBinarySearchTree> { +class RBSearchTree : AbstractBinarySearchTree> { - //4 cases we need to look at - //1) remove red vertex with 0 children -> just remove vetrex + // 4 cases we need to look at + // 1) remove red vertex with 0 children -> just remove vetrex - //2) remove red or black vertex with 2 children -> - //find min vertex on the right subtree and swap it's key and value with - //key and value of vertex that we need to remove - //Now we can work with vertex which has 1 or 0 children + // 2) remove red or black vertex with 2 children -> + // find min vertex on the right subtree and swap it's key and value with + // key and value of vertex that we need to remove + // Now we can work with vertex which has 1 or 0 children - //3) remove black vetrex with 1 child -> child can be only red - //so we just swap child's key and value with key and value that we need to remove - //and look at case 1) + // 3) remove black vetrex with 1 child -> child can be only red + // so we just swap child's key and value with key and value that we need to remove + // and look at case 1) - //4) remove black vertex with 0 children -> just remove vertex + // 4) remove black vertex with 0 children -> just remove vertex override fun remove(key: K): V? { val vertex: RBVertex = getVertex(key) ?: return null val value = vertex.value var isVertexRed = vertex.isRed var child: RBVertex? = null - if (countChildren(vertex) < 2){ + if (countChildren(vertex) < 2) { child = getChild(vertex) replaceVertexBy(vertex, child) - } - - else{ + } else { val vertexForSwap = getMinKeyNodeRec(vertex.rightSon) - vertexForSwap?.let{ + vertexForSwap?.let { vertex.key = it.key vertex.value = it.value isVertexRed = it.isRed @@ -43,32 +42,32 @@ class RBSearchTree : AbstractBinarySearchTree> { return value } - //we need to balance tree after removal black vertex with 0 children - //in this fun we need to look at vertex's parent and brother + // we need to balance tree after removal black vertex with 0 children + // in this fun we need to look at vertex's parent and brother - //1) brother is black and brother's rightSon is red -> we paint - //brother in parent's color, parent and brother's rightSon in black - //then rotate left + // 1) brother is black and brother's rightSon is red -> we paint + // brother in parent's color, parent and brother's rightSon in black + // then rotate left - //2) brother is black and brother's leftSon is red (rightSon - black) -> - //we swap colors of brother and brother's leftSon and rotate right - //then look at case 1 + // 2) brother is black and brother's leftSon is red (rightSon - black) -> + // we swap colors of brother and brother's leftSon and rotate right + // then look at case 1 - //3) brother is black and both sons are black -> we make brother red - //then we need to launch algorithm from the parent because of it - //can be red, so we have red parent and red son or black so - //the black height of all subtree decreased + // 3) brother is black and both sons are black -> we make brother red + // then we need to launch algorithm from the parent because of it + // can be red, so we have red parent and red son or black so + // the black height of all subtree decreased - //4) brother is red -> make brother black, parent red and - //rotate left. We move conflict on level below, then we look at the previous cases - private fun balanceAfterRemove(vertex: RBVertex?){ + // 4) brother is red -> make brother black, parent red and + // rotate left. We move conflict on level below, then we look at the previous cases + private fun balanceAfterRemove(vertex: RBVertex?) { var currentVertex = vertex - while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)){ + while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { var brother: RBVertex? - if (currentVertex == currentVertex?.parent?.leftSon){ + if (currentVertex == currentVertex?.parent?.leftSon) { brother = currentVertex?.parent?.rightSon - if (brother?.isRed == true){ + if (brother?.isRed == true) { brother.isRed = false currentVertex?.parent?.isRed = true val vertexForRotate = currentVertex?.parent @@ -77,13 +76,12 @@ class RBSearchTree : AbstractBinarySearchTree> { } if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null)){ + (brother?.rightSon?.isRed == false || brother?.rightSon == null) + ) { brother?.isRed = true currentVertex = currentVertex?.parent - } - - else{ - if (brother.rightSon?.isRed == false || brother.rightSon == null){ + } else { + if (brother.rightSon?.isRed == false || brother.rightSon == null) { brother.leftSon?.isRed = false brother.isRed = true rotateRight(brother) @@ -98,12 +96,10 @@ class RBSearchTree : AbstractBinarySearchTree> { vertexForRotate?.let { rotateLeft(vertexForRotate) } currentVertex = root } - } - - else{ + } else { brother = currentVertex?.parent?.leftSon - if (brother?.isRed == true){ + if (brother?.isRed == true) { brother.isRed = false currentVertex?.parent?.isRed = true val vertexForRotate = currentVertex?.parent @@ -112,13 +108,12 @@ class RBSearchTree : AbstractBinarySearchTree> { } if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null)){ + (brother?.rightSon?.isRed == false || brother?.rightSon == null) + ) { brother?.isRed = true currentVertex = currentVertex?.parent - } - - else{ - if (brother.leftSon?.isRed == false || brother.leftSon == null){ + } else { + if (brother.leftSon?.isRed == false || brother.leftSon == null) { brother.rightSon?.isRed = false brother.isRed = true rotateLeft(brother) @@ -138,17 +133,18 @@ class RBSearchTree : AbstractBinarySearchTree> { currentVertex?.isRed = false } - //finds vertex by corresponding key - //if such vertex doesn't exist returns null + // finds vertex by corresponding key + // if such vertex doesn't exist returns null private fun getVertex(key: K): RBVertex? { var currentVertex: RBVertex? = root - while (currentVertex?.key != key){ + while (currentVertex?.key != key) { if (currentVertex == null) return null - when (compareKeys(key, currentVertex.key)){ + when (compareKeys(key, currentVertex.key)) { -1 -> { currentVertex = currentVertex.leftSon } + 1 -> { currentVertex = currentVertex.rightSon } @@ -157,24 +153,26 @@ class RBSearchTree : AbstractBinarySearchTree> { return currentVertex } - //finds free place and inserts newVertex, colors it in red - //if vertex with such key exists, replaces it + // finds free place and inserts newVertex, colors it in red + // if vertex with such key exists, replaces it override fun put(key: K, value: V, replaceIfExists: Boolean) { var currentVertex: RBVertex? = root var parent: RBVertex? = null var isLeft: Boolean = false while (currentVertex != null) { - when (compareKeys(key, currentVertex.key)){ + when (compareKeys(key, currentVertex.key)) { -1 -> { parent = currentVertex currentVertex = currentVertex.leftSon isLeft = true } + 0 -> { if (replaceIfExists) currentVertex.value = value break } + 1 -> { parent = currentVertex currentVertex = currentVertex.rightSon @@ -183,7 +181,7 @@ class RBSearchTree : AbstractBinarySearchTree> { } } - if (currentVertex == null){ + if (currentVertex == null) { currentVertex = RBVertex(key, value, null, null, true, parent) if (isLeft) parent?.let { parent.leftSon = currentVertex } else parent?.let { parent.rightSon = currentVertex } @@ -192,35 +190,33 @@ class RBSearchTree : AbstractBinarySearchTree> { balanceAfterPut(currentVertex) } - //we need to balance tree in two cases - //1) when newVertex is root, so our root is red - //2) when parent of our newVertex is red(because newVertex is also red) + // we need to balance tree in two cases + // 1) when newVertex is root, so our root is red + // 2) when parent of our newVertex is red(because newVertex is also red) - //in first case we just make the root black - //in second case we need to look at the newVertex's uncle + // in first case we just make the root black + // in second case we need to look at the newVertex's uncle - //if uncle is red, we make it black and newVertex's parent black and grandparent red - //launch algorithm to grandfather because now it's color changed to red + // if uncle is red, we make it black and newVertex's parent black and grandparent red + // launch algorithm to grandfather because now it's color changed to red - //if uncle is black we also make newVertex's parent black, grandparent red - //and rotate it right + // if uncle is black we also make newVertex's parent black, grandparent red + // and rotate it right private fun balanceAfterPut(vertex: RBVertex) { var currentVertex = vertex - while (currentVertex.parent?.isRed == true){ + while (currentVertex.parent?.isRed == true) { val grandparent = currentVertex.parent?.parent - if (currentVertex.parent == grandparent?.leftSon){ + if (currentVertex.parent == grandparent?.leftSon) { val uncle = grandparent?.rightSon - if (uncle?.isRed == true){ + if (uncle?.isRed == true) { currentVertex.parent?.isRed = false uncle.isRed = false grandparent.isRed = true currentVertex = grandparent - } - - else { + } else { if (currentVertex == currentVertex.parent?.rightSon) { currentVertex = currentVertex.parent ?: currentVertex rotateLeft(currentVertex) @@ -231,19 +227,15 @@ class RBSearchTree : AbstractBinarySearchTree> { val vertexForRightRotate = currentVertex.parent?.parent vertexForRightRotate?.let { rotateRight(vertexForRightRotate) } } - } - - else { + } else { val uncle = grandparent?.leftSon - if (uncle?.isRed == true){ + if (uncle?.isRed == true) { currentVertex.parent?.isRed = false uncle.isRed = false grandparent.isRed = true currentVertex = grandparent - } - - else { + } else { if (currentVertex == currentVertex.parent?.leftSon) { currentVertex = currentVertex.parent ?: currentVertex rotateRight(currentVertex) @@ -268,15 +260,15 @@ class RBSearchTree : AbstractBinarySearchTree> { private fun getChild(vertex: RBVertex) = if (vertex.leftSon != null) vertex.leftSon else vertex.rightSon - private fun replaceVertexBy(oldVertex: RBVertex, newVertex: RBVertex?){ + private fun replaceVertexBy(oldVertex: RBVertex, newVertex: RBVertex?) { if (root == oldVertex) root = newVertex else if (oldVertex == oldVertex.parent?.leftSon) oldVertex.parent?.leftSon = newVertex else oldVertex.parent?.rightSon = newVertex newVertex?.parent = oldVertex.parent } - //suppose that vertex has a rightSon - //swap parent and rightSon, rightSon's leftSon becomes parent's rightSon + // suppose that vertex has a rightSon + // swap parent and rightSon, rightSon's leftSon becomes parent's rightSon private fun rotateLeft(vertex: RBVertex) { val rightVertex: RBVertex? = vertex.rightSon vertex.rightSon = rightVertex?.leftSon @@ -291,12 +283,12 @@ class RBSearchTree : AbstractBinarySearchTree> { rightVertex?.leftSon = vertex } - //suppose that vertex has a leftSon - //swap parent and leftSon, leftSon's rightSon becomes parent's leftSon + // suppose that vertex has a leftSon + // swap parent and leftSon, leftSon's rightSon becomes parent's leftSon private fun rotateRight(vertex: RBVertex) { val leftVertex: RBVertex? = vertex.leftSon vertex.leftSon = leftVertex?.rightSon - leftVertex?.rightSon.let { leftVertex?.rightSon?.parent = vertex} + leftVertex?.rightSon.let { leftVertex?.rightSon?.parent = vertex } leftVertex?.parent = vertex.parent when { vertex.parent == null -> root = leftVertex @@ -309,5 +301,9 @@ class RBSearchTree : AbstractBinarySearchTree> { constructor(comparator: Comparator? = null) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) } diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index d165ea8..796613d 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -1,7 +1,8 @@ package main.trees + import main.vertexes.SimpleBSTVertex -open class SimpleBinarySearchTree : AbstractBinarySearchTree> { +open class SimpleBinarySearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { if (root == null) { @@ -19,15 +20,14 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree { if (vertex.rightSon == null) { vertex.rightSon = SimpleBSTVertex(key, value) size++ - } - else putRec(key, value, replaceIfExists, vertex.rightSon) + } else putRec(key, value, replaceIfExists, vertex.rightSon) } } } @@ -47,11 +47,13 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree { val (updatedRightSon, deletedValue, isRemoved) = removeRec(key, vertex.rightSon) vertex.rightSon = updatedRightSon return Triple(vertex, deletedValue, isRemoved) } + else -> { val deletedValue: V = vertex.value if (vertex.leftSon == null || vertex.rightSon == null) { @@ -76,5 +78,9 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree?) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) } diff --git a/lib/src/test/kotlin/AVLTreeTests b/lib/src/test/kotlin/AVLTreeTests deleted file mode 100644 index e69de29..0000000 diff --git a/lib/src/test/kotlin/SimpleBSTreeTests.kt b/lib/src/test/kotlin/SimpleBSTreeTests.kt index 3204aa6..22956c9 100644 --- a/lib/src/test/kotlin/SimpleBSTreeTests.kt +++ b/lib/src/test/kotlin/SimpleBSTreeTests.kt @@ -55,7 +55,7 @@ class SimpleBSTTests { @Test fun `put many vertexes test`() { val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(0, "hello"))) - for (key in 1 .. 6) { + for (key in 1..6) { tree.put(key, "hello") } assertEquals(7, tree.size()) @@ -64,12 +64,12 @@ class SimpleBSTTests { @Test fun `put many vertexes with method putAll() test`() { val map: Map = mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two") ) val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) tree.putAll(map) @@ -103,7 +103,8 @@ class SimpleBSTTests { @Test fun `remove one left son vertex test`() { - val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"), Pair(0, "zero"), Pair(-1, "negative"))) + val tree: TestSimpleBST = + TestSimpleBST(mapOf(Pair(1, "one"), Pair(0, "zero"), Pair(-1, "negative"))) tree.remove(0) assertEquals(-1, tree.getTreeRoot()?.leftSon?.key) assertEquals(2, tree.size()) @@ -128,14 +129,14 @@ class SimpleBSTTests { @Test fun `remove two sons with right subtree vertex test`() { val tree: TestSimpleBST = TestSimpleBST( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") - ) + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two") + ) ) tree.remove(1) assertEquals(2, tree.getTreeRoot()?.key) @@ -145,14 +146,14 @@ class SimpleBSTTests { @Test fun `remove many vertex test`() { val tree: TestSimpleBST = TestSimpleBST( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") - ) + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two") + ) ) for (key in 0..5) { tree.remove(key) diff --git a/lib/src/test/kotlin/TestSimpleBST.kt b/lib/src/test/kotlin/TestSimpleBST.kt index 02b3dea..903537f 100644 --- a/lib/src/test/kotlin/TestSimpleBST.kt +++ b/lib/src/test/kotlin/TestSimpleBST.kt @@ -2,7 +2,9 @@ import main.trees.SimpleBinarySearchTree import main.vertexes.SimpleBSTVertex class TestSimpleBST : SimpleBinarySearchTree { - fun getTreeRoot(): SimpleBSTVertex? {return root} + fun getTreeRoot(): SimpleBSTVertex? { + return root + } constructor(comparator: Comparator?) : super(comparator) constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) From 897458300b28a3b072a6b88c6bfbdf1c927bd1ad Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 00:23:42 +0300 Subject: [PATCH 152/227] style: final changes according to linter --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 8 ++++---- lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt | 3 +-- lib/src/main/kotlin/vertexes/AVLVertex.kt | 4 ++-- lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt | 2 +- .../kotlin/{SimpleBSTreeTests.kt => SimpleBSTTests.kt} | 2 +- lib/src/test/kotlin/TestSimpleBST.kt | 9 ++++++--- 6 files changed, 15 insertions(+), 13 deletions(-) rename lib/src/test/kotlin/{SimpleBSTreeTests.kt => SimpleBSTTests.kt} (99%) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index c216a21..ca7e28d 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -17,8 +17,10 @@ class AVLSearchTree : AbstractBinarySearchTree> { } private fun putRec( - key: K, value: V, - replaceIfExists: Boolean, vertex: AVLVertex + key: K, + value: V, + replaceIfExists: Boolean, + vertex: AVLVertex ): AVLVertex? { fun putRecShort(vrtx: AVLVertex): AVLVertex? { return putRec(key, value, replaceIfExists, vrtx) @@ -195,7 +197,6 @@ class AVLSearchTree : AbstractBinarySearchTree> { return doBalanceChoreWhenRightSubTreeChanged() } } - } } @@ -242,7 +243,6 @@ class AVLSearchTree : AbstractBinarySearchTree> { ) subtreeRoot } - } leftSon = curVertex.leftSon as AVLVertex return if (leftSon.sonsHeightDiff == -1) { diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index d985204..ff62554 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -1,7 +1,7 @@ package main.trees -import main.vertexes.InterfaceBSTVertex import main.iterator.TreeIterator +import main.vertexes.InterfaceBSTVertex abstract class AbstractBinarySearchTree> { @@ -103,7 +103,6 @@ abstract class AbstractBinarySearchTree> { 0 -> 0 else -> 1 } - } } diff --git a/lib/src/main/kotlin/vertexes/AVLVertex.kt b/lib/src/main/kotlin/vertexes/AVLVertex.kt index 291bc9a..6194c2d 100644 --- a/lib/src/main/kotlin/vertexes/AVLVertex.kt +++ b/lib/src/main/kotlin/vertexes/AVLVertex.kt @@ -3,7 +3,7 @@ package main.vertexes class AVLVertex( override var key: K, override var value: V -): InterfaceBSTVertex> { +) : InterfaceBSTVertex> { override var leftSon: AVLVertex? = null override var rightSon: AVLVertex? = null @@ -14,7 +14,7 @@ class AVLVertex( value: V, leftSon: AVLVertex?, rightSon: AVLVertex?, - sonsHeightDiff : Int = 0 + sonsHeightDiff: Int = 0 ) : this(key, value) { this.leftSon = leftSon this.rightSon = rightSon diff --git a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt index 2e76767..9041ed6 100644 --- a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt +++ b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt @@ -3,7 +3,7 @@ package main.vertexes class SimpleBSTVertex( override var key: K, override var value: V -): InterfaceBSTVertex> { +) : InterfaceBSTVertex> { override var leftSon: SimpleBSTVertex? = null override var rightSon: SimpleBSTVertex? = null diff --git a/lib/src/test/kotlin/SimpleBSTreeTests.kt b/lib/src/test/kotlin/SimpleBSTTests.kt similarity index 99% rename from lib/src/test/kotlin/SimpleBSTreeTests.kt rename to lib/src/test/kotlin/SimpleBSTTests.kt index 22956c9..0dcab62 100644 --- a/lib/src/test/kotlin/SimpleBSTreeTests.kt +++ b/lib/src/test/kotlin/SimpleBSTTests.kt @@ -169,4 +169,4 @@ class SimpleBSTTests { assertEquals(null, deletedValue) assertEquals(1, tree.size()) } -} \ No newline at end of file +} diff --git a/lib/src/test/kotlin/TestSimpleBST.kt b/lib/src/test/kotlin/TestSimpleBST.kt index 903537f..5e7c2d5 100644 --- a/lib/src/test/kotlin/TestSimpleBST.kt +++ b/lib/src/test/kotlin/TestSimpleBST.kt @@ -7,6 +7,9 @@ class TestSimpleBST : SimpleBinarySearchTree { } constructor(comparator: Comparator?) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) - : super(map, replaceIfExists, comparator) -} \ No newline at end of file + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) +} From 5dd7e5388bb37790db7fd795dadd753cb87cb3dd Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 00:44:25 +0300 Subject: [PATCH 153/227] chore: delete extra code --- lib/src/main/kotlin/iterator/TreeIterator.kt | 5 +- lib/src/main/kotlin/trees/AVLSearchTree.kt | 278 +-------------- .../kotlin/trees/AbstractBinarySearchTree.kt | 40 ++- lib/src/main/kotlin/trees/RBSearchTree.kt | 319 +---------------- .../kotlin/trees/SimpleBinarySearchTree.kt | 17 +- lib/src/main/kotlin/vertexes/AVLVertex.kt | 4 +- .../main/kotlin/vertexes/SimpleBSTVertex.kt | 2 +- lib/src/test/kotlin/trees/RBSearchTreeTest.kt | 325 ------------------ 8 files changed, 56 insertions(+), 934 deletions(-) delete mode 100644 lib/src/test/kotlin/trees/RBSearchTreeTest.kt diff --git a/lib/src/main/kotlin/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt index bad1c15..e8ba2b2 100644 --- a/lib/src/main/kotlin/iterator/TreeIterator.kt +++ b/lib/src/main/kotlin/iterator/TreeIterator.kt @@ -1,10 +1,11 @@ package main.iterator + import main.vertexes.InterfaceBSTVertex import java.util.LinkedList -internal class TreeIterator>( +internal class TreeIterator>( vertex: N? -): Iterator> { +) : Iterator> { private val stack = LinkedList() init { diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index c8d55db..bde5010 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -1,280 +1,22 @@ package main.trees + import main.vertexes.AVLVertex -class AVLSearchTree : AbstractBinarySearchTree> { +class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { - if (!isEmpty()) { - when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { - null, root -> {} - else -> root = putRecReturned - } - return - } - root = AVLVertex(key, value) - size++ + TODO() } - private fun putRec(key: K, value: V, - replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { - fun putRecShort(vrtx : AVLVertex) : AVLVertex? { - return putRec(key, value, replaceIfExists, vrtx) - } - val nextCallReturned : AVLVertex? - when (compareKeys(key, vertex.key)) { - -1 -> { - if (vertex.leftSon == null){ - vertex.leftSon = AVLVertex(key, value) - vertex.sonsHeightDiff++ - size++ - return vertex - } - nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) - } - 0 -> { - if (replaceIfExists) { - vertex.key = key - vertex.value = value - } - return null - } - else -> { - if (vertex.rightSon == null) { - vertex.rightSon = AVLVertex(key, value) - vertex.sonsHeightDiff-- - size++ - return vertex - } - nextCallReturned = putRecShort(vertex.rightSon as AVLVertex ) - } - } - if (nextCallReturned == null) return null - fun doBalanceChoreWhenLeftSubTreeChanged() : AVLVertex? { - if (nextCallReturned.sonsHeightDiff == 0) return null - if (vertex.sonsHeightDiff + 1 == 2) return balance(vertex) - vertex.sonsHeightDiff++ - return vertex - } - fun doBalanceChoreWhenRightSubTreeChanged() : AVLVertex? { - if (nextCallReturned.sonsHeightDiff == 0) return null - if (vertex.sonsHeightDiff - 1 == -2) return balance(vertex) - vertex.sonsHeightDiff-- - return vertex - } - when (nextCallReturned){ - vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() - vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() - else -> { - if (compareKeys(nextCallReturned.key, vertex.key) == -1) { - vertex.leftSon = nextCallReturned - return doBalanceChoreWhenLeftSubTreeChanged() - } - vertex.rightSon = nextCallReturned - return doBalanceChoreWhenRightSubTreeChanged() - } - } - } - override fun remove(key: K): V? { - if (!isEmpty()) { - val removeRecReturned = removeRec(key, root as AVLVertex) - when (removeRecReturned.first) { - RemovalStage.A -> {} - RemovalStage.B -> { - if (removeRecReturned.component2() != root) - root = removeRecReturned.component2() - } - RemovalStage.C -> root = null - } - return removeRecReturned.component3() - } - return null - } - - enum class RemovalStage {A, B, C} - // a - don't need tree changes anymore - // b - probably need some tree changes, but not nulling - // c - need to null due "Son" property of (if exists) the parent of removed vertex + b - - private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { - val nextCallReturned : Triple ?, V?> - // Triple consists of: - // 1) removal stage - // 2) if RemovalStage == a : just a vertex (don't need it later) - // if RemovalStage == b : the root of the changed subtree - // if RemovalStage == c : the removed vertex - // 3) a value of the removed vertex (or null if key not exists) - when (compareKeys(key, vertex.key)) { - -1 -> { - if (vertex.leftSon == null) return Triple(RemovalStage.A, vertex, null) - nextCallReturned = removeRec(key, vertex.leftSon as AVLVertex) - } - 1 -> { - if (vertex.rightSon == null) return Triple(RemovalStage.A, vertex, null) - nextCallReturned = removeRec(key, vertex.rightSon as AVLVertex) - } - else -> { - return when ((vertex.leftSon == null) to (vertex.rightSon == null)) { - true to true -> { - size-- - Triple(RemovalStage.C, vertex, vertex.value) - } - true to false -> { - size-- - Triple(RemovalStage.C, vertex.rightSon as AVLVertex, vertex.value) - } - false to true -> { - size-- - Triple(RemovalStage.C, vertex.leftSon as AVLVertex, vertex.value) - } - else -> Triple(RemovalStage.C, - prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) - } - } - } - fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { - if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) - return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff - 1 == -2) - return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) - vertex.sonsHeightDiff-- - return Triple(RemovalStage.B, vertex, nextCallReturned.third) - } - fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { - if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) - return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff + 1 == 2) - return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) - vertex.sonsHeightDiff++ - return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) - } - when (nextCallReturned.component1()) { - RemovalStage.A -> return nextCallReturned - RemovalStage.B -> when (nextCallReturned.component2()) { - vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() - vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() - else -> - when (compareKeys(nextCallReturned.component2().key, vertex.key)) { - -1 -> { - vertex.leftSon = nextCallReturned.component2() - return doBalanceChoreWhenLeftSubTreeChanged() - } - else -> { - vertex.rightSon = nextCallReturned.component2() - return doBalanceChoreWhenRightSubTreeChanged() - } - } - } - RemovalStage.C -> - when (compareKeys(nextCallReturned.component2().key, vertex.key)) { - -1 -> { - vertex.leftSon = null - return doBalanceChoreWhenLeftSubTreeChanged() - } - else -> { - vertex.rightSon = null - return doBalanceChoreWhenRightSubTreeChanged() - } - } - - } - } - - private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex? { - val substitute = getMaxKeyNodeRec(vertex.leftSon) - if (substitute == null) return null - remove(substitute.key) - substitute.leftSon = vertex.leftSon - substitute.rightSon = vertex.rightSon - substitute.sonsHeightDiff = vertex.sonsHeightDiff - return substitute - } - - private fun balance(curVertex: AVLVertex) : AVLVertex { - var (rightSon, leftSon) = List?>(2){null} - fun setTwoSonHeightDiffs(values : Pair) { - curVertex.sonsHeightDiff = values.component1() - if (rightSon != null){ - (rightSon as AVLVertex).sonsHeightDiff = values.component2() - return - } - (leftSon as AVLVertex).sonsHeightDiff = values.component2() - } - - if(curVertex.sonsHeightDiff == -1) { - rightSon = curVertex.rightSon as AVLVertex - return if (rightSon.sonsHeightDiff == 1) { - val rightSonSLeftSon = rightSon.leftSon as AVLVertex - val subtreeRoot = bigRotateLeft(curVertex, rightSon) - setTwoSonHeightDiffs( - when (rightSonSLeftSon.sonsHeightDiff) { - 1 -> 0 to -1 - -1 -> 1 to 0 - else -> 0 to 0 - } - ) - rightSonSLeftSon.sonsHeightDiff = 0 - subtreeRoot - } - else { - val subtreeRoot = rotateLeft(curVertex, rightSon) - setTwoSonHeightDiffs( - if (rightSon.sonsHeightDiff == 0) -1 to 1 - else 0 to 0 - ) - subtreeRoot - } - - } - leftSon = curVertex.leftSon as AVLVertex - return if (leftSon.sonsHeightDiff == -1) { - val leftSonSRightSon = leftSon.rightSon as AVLVertex - val subtreeRoot = bigRotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( - when (leftSonSRightSon.sonsHeightDiff) { - -1 -> 0 to 1 - 1 -> -1 to 0 - else -> 0 to 0 - } - ) - leftSonSRightSon.sonsHeightDiff = 0 - subtreeRoot - } - else { - val subtreeRoot = rotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( - if (leftSon.sonsHeightDiff == 0) 1 to -1 - else 0 to 0 - ) - subtreeRoot - } - } - - private fun rotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { - curVertex.rightSon = rightSon.leftSon - rightSon.leftSon = curVertex - return rightSon - } - - private fun rotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { - curVertex.leftSon = leftSon.rightSon - leftSon.rightSon = curVertex - return leftSon - } - - private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { - val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) - curVertex.rightSon = curRightSon - return rotateLeft(curVertex, curRightSon) - } - - private fun bigRotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { - val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) - curVertex.leftSon = curLeftSon - return rotateRight(curVertex, curLeftSon) + TODO() } constructor (comparator: Comparator? = null) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) -} + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) +} \ No newline at end of file diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index d88c536..d985204 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -1,22 +1,29 @@ package main.trees + import main.vertexes.InterfaceBSTVertex import main.iterator.TreeIterator abstract class AbstractBinarySearchTree> { protected var comparator: Comparator? = null - protected var size : Long = 0L - protected var root : N? = null + protected var size: Long = 0L + protected var root: N? = null operator fun iterator(): Iterator> { return TreeIterator(root) } - fun size(): Long {return size} + fun size(): Long { + return size + } + + fun isEmpty(): Boolean { + return size == 0L + } - fun isEmpty(): Boolean {return size == 0L} - - fun get(key: K): V? {return getRec(key)} + fun get(key: K): V? { + return getRec(key) + } fun getPair(key: K): Pair? { val value = get(key) @@ -28,7 +35,7 @@ abstract class AbstractBinarySearchTree> { return if (minKeyNode == null) null else minKeyNode.value } - fun getMax(): V?{ + fun getMax(): V? { val maxKeyNode = getMaxKeyNodeRec() return if (maxKeyNode == null) null else maxKeyNode.value } @@ -43,7 +50,7 @@ abstract class AbstractBinarySearchTree> { return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) } - abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) + abstract fun put(key: K, value: V, replaceIfExists: Boolean = true) fun putAll(map: Map, replaceIfExists: Boolean = true) { for (pair in map) put(pair.key, pair.value, replaceIfExists) @@ -65,7 +72,7 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMinKeyNodeRec(vertex: N? = root) : N? { + protected fun getMinKeyNodeRec(vertex: N? = root): N? { if (vertex == null) return null else { return if (vertex.leftSon == null) vertex @@ -73,7 +80,7 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMaxKeyNodeRec(vertex: N? = root) : N? { + protected fun getMaxKeyNodeRec(vertex: N? = root): N? { if (vertex == null) return null else { return if (vertex.rightSon == null) vertex @@ -81,19 +88,18 @@ abstract class AbstractBinarySearchTree> { } } - protected fun compareKeys(firstKey: K, secondKey: K): Int{ + protected fun compareKeys(firstKey: K, secondKey: K): Int { val cpr = comparator return if (cpr != null) { when (cpr.compare(firstKey, secondKey)) { - in Int.MIN_VALUE .. -1 -> -1 - 0 -> 0 + in Int.MIN_VALUE..-1 -> -1 + 0 -> 0 else -> 1 } - } - else { + } else { val comparableKey = firstKey as Comparable - when (comparableKey.compareTo(secondKey)) { - in Int.MIN_VALUE .. -1 -> -1 + when (comparableKey.compareTo(secondKey)) { + in Int.MIN_VALUE..-1 -> -1 0 -> 0 else -> 1 } diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index d1cb2cb..071f32a 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -4,323 +4,12 @@ import main.vertexes.RBVertex class RBSearchTree : AbstractBinarySearchTree> { - //4 cases we need to look at - //1) remove red vertex with 0 children -> just remove vertex - - //2) remove red or black vertex with 2 children -> - //find min vertex on the right subtree and swap it's key and value with - //key and value of vertex that we need to remove - //Now we can work with vertex which has 1 or 0 children - - //3) remove black vertex with 1 child -> child can be only red - //so we just swap child's key and value with key and value that we need to remove - //and look at case 1) - - //4) remove black vertex with 0 children -> just remove vertex - override fun remove(key: K): V? { - val vertex: RBVertex = getVertex(key) ?: return null - val value = vertex.value - - if (needToBalance(vertex)) balanceAfterRemove(vertex) - - --size - return value - } - - private fun needToBalance(vertex: RBVertex): Boolean { - when (countChildren(vertex)) { - 0 -> { - if (vertex.isRed) { - replaceVertexBy(vertex, null) - return false - } - return true - } - - 1 -> { - replaceVertexBy(vertex, getChild(vertex)) - return false - } - - 2 -> { - val vertexForSwap = getMinKeyNodeRec(vertex.rightSon) - vertexForSwap?.let { - val key = vertex.key - vertex.key = it.key - it.key = key - - val value = vertex.value - vertex.value = it.value - it.value = value - - needToBalance(vertexForSwap) - } - } - } - return false - } - - //we need to balance tree after removal black vertex with 0 children - //in this fun we need to look at vertex's parent and brother - - //1) brother is black and brother's rightSon is red -> we paint - //brother in parent's color, parent and brother's rightSon in black - //then rotate left - - //2) brother is black and brother's leftSon is red (rightSon - black) -> - //we swap colors of brother and brother's leftSon and rotate right - //then look at case 1 - - //3) brother is black and both sons are black -> we make brother red - //then we need to launch algorithm from the parent because of it - //can be red, so we have red parent and red son or black so - //the black height of all subtree decreased - - //4) brother is red -> make brother black, parent red and - //rotate left. We move conflict on level below, then we look at the previous cases - private fun balanceAfterRemove(vertex: RBVertex?) { - var currentVertex = vertex - while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { - var brother: RBVertex? - if (currentVertex == currentVertex?.parent?.leftSon) { - brother = currentVertex?.parent?.rightSon - - if (brother?.isRed == true) { - brother.isRed = false - currentVertex?.parent?.isRed = true - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateLeft(vertexForRotate) } - brother = currentVertex?.parent?.rightSon - } - - if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null) - ) { - brother?.isRed = true - currentVertex = currentVertex?.parent - if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null - } else { - if (brother.rightSon?.isRed == false || brother.rightSon == null) { - brother.leftSon?.isRed = false - brother.isRed = true - rotateRight(brother) - brother = currentVertex?.parent?.rightSon - } - - val parentColor = currentVertex?.parent?.isRed - parentColor?.let { brother?.isRed = parentColor } - currentVertex?.parent?.isRed = false - brother?.rightSon?.isRed = false - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateLeft(vertexForRotate) } - if (currentVertex == vertex) currentVertex?.parent?.leftSon = null - currentVertex = root - } - } else { - brother = currentVertex?.parent?.leftSon - - if (brother?.isRed == true) { - brother.isRed = false - currentVertex?.parent?.isRed = true - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateRight(vertexForRotate) } - brother = currentVertex?.parent?.leftSon - } - - if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null) - ) { - brother?.isRed = true - currentVertex = currentVertex?.parent - if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null - } else { - if (brother.leftSon?.isRed == false || brother.leftSon == null) { - brother.rightSon?.isRed = false - brother.isRed = true - rotateLeft(brother) - brother = currentVertex?.parent?.leftSon - } - - val parentColor = currentVertex?.parent?.isRed - parentColor?.let { brother?.isRed = parentColor } - currentVertex?.parent?.isRed = false - brother?.leftSon?.isRed = false - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateRight(vertexForRotate) } - if (currentVertex == vertex) currentVertex?.parent?.rightSon = null - currentVertex = root - } - } - } - currentVertex?.isRed = false - } - - //finds vertex by corresponding key - //if such vertex doesn't exist returns null - private fun getVertex(key: K): RBVertex? { - var currentVertex: RBVertex? = root - - while (currentVertex?.key != key) { - if (currentVertex == null) return null - when (compareKeys(key, currentVertex.key)) { - -1 -> { - currentVertex = currentVertex.leftSon - } - - 1 -> { - currentVertex = currentVertex.rightSon - } - } - } - return currentVertex - } - - //finds free place and inserts newVertex, colors it in red - //if vertex with such key exists, replaces it override fun put(key: K, value: V, replaceIfExists: Boolean) { - var currentVertex: RBVertex? = root - var parent: RBVertex? = null - var isLeft: Boolean = false - - while (currentVertex != null) { - when (compareKeys(key, currentVertex.key)) { - -1 -> { - parent = currentVertex - currentVertex = currentVertex.leftSon - isLeft = true - } - - 0 -> { - if (replaceIfExists) currentVertex.value = value - break - } - - 1 -> { - parent = currentVertex - currentVertex = currentVertex.rightSon - isLeft = false - } - } - } - - if (currentVertex == null) { - currentVertex = RBVertex(key, value, null, null, true, parent) - if (root == null) root = currentVertex - else if (isLeft) parent?.let { parent.leftSon = currentVertex } - else parent?.let { parent.rightSon = currentVertex } - } - - balanceAfterPut(currentVertex) - ++size + TODO() } - //we need to balance tree in two cases - //1) when newVertex is root, so our root is red - //2) when parent of our newVertex is red(because newVertex is also red) - - //in first case we just make the root black - //in second case we need to look at the newVertex's uncle - - //if uncle is red, we make it black and newVertex's parent black and grandparent red - //launch algorithm to grandfather because now it's color changed to red - - //if uncle is black we also make newVertex's parent black, grandparent red - //and rotate it right - private fun balanceAfterPut(vertex: RBVertex) { - var currentVertex = vertex - - while (currentVertex.parent?.isRed == true) { - val grandparent = currentVertex.parent?.parent - - if (currentVertex.parent == grandparent?.leftSon) { - val uncle = grandparent?.rightSon - - if (uncle?.isRed == true) { - currentVertex.parent?.isRed = false - uncle.isRed = false - grandparent.isRed = true - currentVertex = grandparent - } else { - if (currentVertex == currentVertex.parent?.rightSon) { - currentVertex = currentVertex.parent ?: currentVertex - rotateLeft(currentVertex) - } - - currentVertex.parent?.isRed = false - currentVertex.parent?.parent?.isRed = true - val vertexForRightRotate = currentVertex.parent?.parent - vertexForRightRotate?.let { rotateRight(vertexForRightRotate) } - } - } else { - val uncle = grandparent?.leftSon - - if (uncle?.isRed == true) { - currentVertex.parent?.isRed = false - uncle.isRed = false - grandparent.isRed = true - currentVertex = grandparent - } else { - if (currentVertex == currentVertex.parent?.leftSon) { - currentVertex = currentVertex.parent ?: currentVertex - rotateRight(currentVertex) - } - - currentVertex.parent?.isRed = false - currentVertex.parent?.parent?.isRed = true - val vertexForLeftRotate = currentVertex.parent?.parent - vertexForLeftRotate?.let { rotateLeft(vertexForLeftRotate) } - } - } - } - root?.isRed = false - } - - private fun countChildren(vertex: RBVertex): Int { - var numOfChild = 0 - if (vertex.leftSon != null) ++numOfChild - if (vertex.rightSon != null) ++numOfChild - return numOfChild - } - - private fun getChild(vertex: RBVertex) = if (vertex.leftSon != null) vertex.leftSon else vertex.rightSon - - private fun replaceVertexBy(oldVertex: RBVertex, newVertex: RBVertex?) { - if (root == oldVertex) root = newVertex - else if (oldVertex == oldVertex.parent?.leftSon) oldVertex.parent?.leftSon = newVertex - else oldVertex.parent?.rightSon = newVertex - newVertex?.parent = oldVertex.parent - } - - //suppose that vertex has a rightSon - //swap parent and rightSon, rightSon's leftSon becomes parent's rightSon - private fun rotateLeft(vertex: RBVertex) { - val rightVertex: RBVertex? = vertex.rightSon - vertex.rightSon = rightVertex?.leftSon - rightVertex?.leftSon.let { rightVertex?.leftSon?.parent = vertex } - rightVertex?.parent = vertex.parent - when { - vertex.parent == null -> root = rightVertex - vertex == vertex.parent?.rightSon -> vertex.parent?.rightSon = rightVertex - else -> vertex.parent?.leftSon = rightVertex - } - vertex.parent = rightVertex - rightVertex?.leftSon = vertex - } - - //suppose that vertex has a leftSon - //swap parent and leftSon, leftSon's rightSon becomes parent's leftSon - private fun rotateRight(vertex: RBVertex) { - val leftVertex: RBVertex? = vertex.leftSon - vertex.leftSon = leftVertex?.rightSon - leftVertex?.rightSon.let { leftVertex?.rightSon?.parent = vertex } - leftVertex?.parent = vertex.parent - when { - vertex.parent == null -> root = leftVertex - vertex == vertex.parent?.leftSon -> vertex.parent?.leftSon = leftVertex - else -> vertex.parent?.rightSon = leftVertex - } - vertex.parent = leftVertex - leftVertex?.rightSon = vertex + override fun remove(key: K): V? { + TODO() } constructor(comparator: Comparator? = null) : super(comparator) @@ -330,4 +19,4 @@ class RBSearchTree : AbstractBinarySearchTree> { replaceIfExists, comparator ) -} +} \ No newline at end of file diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index 71259a0..6b58d17 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -1,13 +1,22 @@ package main.trees + import main.vertexes.SimpleBSTVertex -class SimpleBinarySearchTree : AbstractBinarySearchTree> { +class SimpleBinarySearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean) { + TODO() + } - override fun remove(key: K): V? {TODO()} + override fun remove(key: K): V? { + TODO() + } constructor(comparator: Comparator?) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) } diff --git a/lib/src/main/kotlin/vertexes/AVLVertex.kt b/lib/src/main/kotlin/vertexes/AVLVertex.kt index 291bc9a..6194c2d 100644 --- a/lib/src/main/kotlin/vertexes/AVLVertex.kt +++ b/lib/src/main/kotlin/vertexes/AVLVertex.kt @@ -3,7 +3,7 @@ package main.vertexes class AVLVertex( override var key: K, override var value: V -): InterfaceBSTVertex> { +) : InterfaceBSTVertex> { override var leftSon: AVLVertex? = null override var rightSon: AVLVertex? = null @@ -14,7 +14,7 @@ class AVLVertex( value: V, leftSon: AVLVertex?, rightSon: AVLVertex?, - sonsHeightDiff : Int = 0 + sonsHeightDiff: Int = 0 ) : this(key, value) { this.leftSon = leftSon this.rightSon = rightSon diff --git a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt index 2e76767..9041ed6 100644 --- a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt +++ b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt @@ -3,7 +3,7 @@ package main.vertexes class SimpleBSTVertex( override var key: K, override var value: V -): InterfaceBSTVertex> { +) : InterfaceBSTVertex> { override var leftSon: SimpleBSTVertex? = null override var rightSon: SimpleBSTVertex? = null diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt deleted file mode 100644 index 0b2fafd..0000000 --- a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt +++ /dev/null @@ -1,325 +0,0 @@ -package trees - -import main.trees.RBSearchTree -import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import kotlin.test.assertEquals - -class RBSearchTreeTest { - private lateinit var rbTree: RBSearchTree - private lateinit var expectedResult: List> - private var result: MutableList> = mutableListOf() - - @BeforeEach - fun setup() { - rbTree = RBSearchTree() - } - - @AfterEach - fun end() { - for (el in rbTree) result.add(el) - assertEquals(expectedResult, result) - } - - @Test - fun `put a root to the tree`() { - rbTree.put(7, "hi") - expectedResult = listOf(Pair(7, "hi")) - } - - @Test - fun `put new vertex to the left`() { - rbTree.put(7, "hi") - rbTree.put(5, "my") - expectedResult = listOf(Pair(7, "hi"), Pair(5, "my")) - } - - @Test - fun `put new vertex to the right`() { - rbTree.put(7, "hi") - rbTree.put(9, "name") - expectedResult = listOf(Pair(7, "hi"), Pair(9, "name")) - } - - @Test - fun `put existing vertex without replace`() { - rbTree.put(7, "hi") - rbTree.put(7, "is", false) - expectedResult = listOf(Pair(7, "hi")) - } - - @Test - fun `put existing vertex with replace`() { - rbTree.put(7, "hi") - rbTree.put(7, "Slim") - expectedResult = listOf(Pair(7, "Slim")) - } - - @Test - fun `balance after put - uncle is rightSon and red`() { - rbTree.put(7, "hi") - rbTree.put(5, "my") - rbTree.put(9, "name") - rbTree.put(6, "is") - expectedResult = listOf(Pair(7, "hi"), Pair(9, "name"), Pair(5, "my"), Pair(6, "is")) - } - - @Test - fun `balance after put - uncle is rightSon and black + newVertex is leftSon`() { - rbTree.put(7, "hi") - rbTree.put(5, "my") - rbTree.put(3, "name") - expectedResult = listOf(Pair(5, "my"), Pair(7, "hi"), Pair(3, "name")) - } - - @Test - fun `balance after put - uncle is rightSon and black + newVertex is rightSon`() { - rbTree.put(7, "hi") - rbTree.put(5, "my") - rbTree.put(6, "name") - expectedResult = listOf(Pair(6, "name"), Pair(7, "hi"), Pair(5, "my")) - } - - @Test - fun `balance after put - uncle is leftSon and red`() { - rbTree.put(7, "hi") - rbTree.put(5, "my") - rbTree.put(9, "name") - rbTree.put(8, "is") - expectedResult = listOf(Pair(7, "hi"), Pair(9, "name"), Pair(8, "is"), Pair(5, "my")) - } - - @Test - fun `balance after put - uncle is leftSon and black + newVertex is rightSon`() { - rbTree.put(7, "hi") - rbTree.put(9, "my") - rbTree.put(10, "name") - expectedResult = listOf(Pair(9, "my"), Pair(10, "name"), Pair(7, "hi")) - } - - @Test - fun `balance after put - uncle is leftSon and black + newVertex is leftSon`() { - rbTree.put(7, "hi") - rbTree.put(9, "my") - rbTree.put(8, "name") - expectedResult = listOf(Pair(8, "name"), Pair(9, "my"), Pair(7, "hi")) - } - - @Test - fun `remove non-existent vertex`() { - rbTree.put(7, "hi") - rbTree.remove(9) - expectedResult = listOf(Pair(7, "hi")) - } - - @Test - fun `delete red vertex with 0 children`() { - rbTree.put(7, "hi") - rbTree.put(9, "my") - rbTree.remove(9) - expectedResult = listOf(Pair(7, "hi")) - } - - @Test - fun `delete black vertex with 1 rightSon`() { - rbTree.put(7, "hi") - rbTree.put(9, "my") - rbTree.remove(7) - expectedResult = listOf(Pair(9, "my")) - } - - @Test - fun `delete black vertex with 1 leftSon`() { - rbTree.put(7, "hi") - rbTree.put(5, "my") - rbTree.remove(7) - expectedResult = listOf(Pair(5, "my")) - } - - @Test - fun `delete black vertex with 2 children`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.remove(7) - expectedResult = listOf(Pair(10, "name"), Pair(4, "my")) - } - - @Test - fun `delete red vertex with 2 children`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(3, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "chka") - rbTree.put(11, "Slim") - rbTree.put(13, "Shady") - rbTree.remove(10) - expectedResult = listOf( - Pair(7, "hi"), Pair(11, "Slim"), Pair(12, "chka"), Pair(13, "Shady"), Pair(9, "chka"), - Pair(4, "my"), Pair(5, "chka"), Pair(3, "is") - ) - } - - @Test - fun `balance after remove - brother is right and black, brother's rightSon - red`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(3, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "chka") - rbTree.put(11, "Slim") - rbTree.put(13, "Shady") - rbTree.remove(9) - expectedResult = listOf( - Pair(7, "hi"), Pair(12, "chka"), Pair(13, "Shady"), Pair(10, "name"), Pair(11, "Slim"), - Pair(4, "my"), Pair(5, "chka"), Pair(3, "is") - ) - } - - @Test - fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(3, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "Slim") - rbTree.put(11, "Shady") - rbTree.remove(9) - expectedResult = listOf( - Pair(7, "hi"), Pair(11, "Shady"), Pair(12, "Slim"), Pair(10, "name"), Pair(4, "my"), - Pair(5, "chka"), Pair(3, "is") - ) - } - - @Test - fun `balance after remove - brother is right and black, both sons - black`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(9, "is") - rbTree.put(12, "Slim") - rbTree.put(11, "Shady") - rbTree.remove(11) - - //now vertexes with keys 9 and 12 are black - rbTree.remove(9) - - expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) - } - - @Test - fun `balance after remove - right brother is red`() { - rbTree.put(60, "sixty") - rbTree.put(33, "thirty-three") - rbTree.put(84, "eighty-four") - rbTree.put(15, "fifteen") - rbTree.put(51, "fifty-one") - rbTree.put(65, "sixty-five") - rbTree.put(96, "ninety-six") - rbTree.put(34, "thirty-four") - rbTree.put(52, "Alblack") - rbTree.put(94, "ninety-four") - rbTree.put(97, "ninety-seven") - rbTree.put(95, "ninety-five") - - //now vertex with key 96 is red, with key 65 - black - rbTree.remove(65) - - expectedResult = listOf( - Pair(60, "sixty"), Pair(96, "ninety-six"), Pair(97, "ninety-seven"), - Pair(94, "ninety-four"), Pair(95, "ninety-five"), Pair(84, "eighty-four"), Pair(33, "thirty-three"), - Pair(51, "fifty-one"), Pair(52, "Alblack"), Pair(34, "thirty-four"), Pair(15, "fifteen") - ) - } - - @Test - fun `balance after remove - brother is left and black, brother's rightSon - red`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "chka") - rbTree.put(1, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(5) - expectedResult = listOf( - Pair(7, "hi"), Pair(10, "name"), Pair(12, "chka"), Pair(9, "chka"), Pair(2, "is"), - Pair(4, "my"), Pair(3, "Shady"), Pair(1, "Slim") - ) - } - - @Test - fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(5) - expectedResult = listOf( - Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(9, "chka"), Pair(3, "Shady"), - Pair(4, "my"), Pair(2, "is") - ) - } - - @Test - fun `balance after remove - brother is left and black, both sons - black`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(3) - - //now vertexes with keys 2 and 5 are black - rbTree.remove(5) - - expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) - } - - @Test - fun `balance after remove - left brother is red`() { - rbTree.put(60, "sixty") - rbTree.put(33, "thirty-three") - rbTree.put(84, "eighty-four") - rbTree.put(15, "fifteen") - rbTree.put(51, "fifty-one") - rbTree.put(65, "sixty-five") - rbTree.put(96, "ninety-six") - rbTree.put(5, "five") - rbTree.put(27, "twenty-seven") - rbTree.put(61, "sixty-one") - rbTree.put(69, "sixty-nine") - rbTree.put(17, "seventeen") - - //now vertex with key 15 is red, with key 51 - black - rbTree.remove(51) - - expectedResult = listOf( - Pair(60, "sixty"), Pair(84, "eighty-four"), Pair(96, "ninety-six"), - Pair(65, "sixty-five"), Pair(69, "sixty-nine"), Pair(61, "sixty-one"), Pair(15, "fifteen"), - Pair(27, "twenty-seven"), Pair(33, "thirty-three"), Pair(17, "seventeen"), Pair(5, "five") - ) - } - - @Test - fun `test secondary constructor`() { - val testMap = mapOf(3 to "three", 1 to "one", 2 to "two") - rbTree = RBSearchTree(testMap) - expectedResult = listOf(Pair(2, "two"), Pair(3, "three"), Pair(1, "one")) - } -} From 21b81bc64b5eac9e8e18d050363d1e13beb35706 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 01:31:36 +0300 Subject: [PATCH 154/227] style: change according to linter --- lib/src/main/kotlin/iterator/TreeIterator.kt | 5 +- lib/src/main/kotlin/trees/AVLSearchTree.kt | 189 ++++++++++-------- .../kotlin/trees/AbstractBinarySearchTree.kt | 40 ++-- .../kotlin/trees/SimpleBinarySearchTree.kt | 17 +- lib/src/main/kotlin/vertexes/AVLVertex.kt | 4 +- .../main/kotlin/vertexes/SimpleBSTVertex.kt | 2 +- .../trees/RBSearchTreeAbstractMethodsTest.kt | 171 ---------------- 7 files changed, 147 insertions(+), 281 deletions(-) delete mode 100644 lib/src/test/kotlin/trees/RBSearchTreeAbstractMethodsTest.kt diff --git a/lib/src/main/kotlin/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt index bad1c15..e8ba2b2 100644 --- a/lib/src/main/kotlin/iterator/TreeIterator.kt +++ b/lib/src/main/kotlin/iterator/TreeIterator.kt @@ -1,10 +1,11 @@ package main.iterator + import main.vertexes.InterfaceBSTVertex import java.util.LinkedList -internal class TreeIterator>( +internal class TreeIterator>( vertex: N? -): Iterator> { +) : Iterator> { private val stack = LinkedList() init { diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index c8d55db..c216a21 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -1,11 +1,12 @@ package main.trees + import main.vertexes.AVLVertex -class AVLSearchTree : AbstractBinarySearchTree> { +class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { if (!isEmpty()) { - when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { + when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { null, root -> {} else -> root = putRecReturned } @@ -15,22 +16,26 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ } - private fun putRec(key: K, value: V, - replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { - fun putRecShort(vrtx : AVLVertex) : AVLVertex? { + private fun putRec( + key: K, value: V, + replaceIfExists: Boolean, vertex: AVLVertex + ): AVLVertex? { + fun putRecShort(vrtx: AVLVertex): AVLVertex? { return putRec(key, value, replaceIfExists, vrtx) - } - val nextCallReturned : AVLVertex? + } + + val nextCallReturned: AVLVertex? when (compareKeys(key, vertex.key)) { -1 -> { - if (vertex.leftSon == null){ + if (vertex.leftSon == null) { vertex.leftSon = AVLVertex(key, value) vertex.sonsHeightDiff++ size++ return vertex } - nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) + nextCallReturned = putRecShort(vertex.leftSon as AVLVertex) } + 0 -> { if (replaceIfExists) { vertex.key = key @@ -38,6 +43,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { } return null } + else -> { if (vertex.rightSon == null) { vertex.rightSon = AVLVertex(key, value) @@ -45,36 +51,37 @@ class AVLSearchTree : AbstractBinarySearchTree> { size++ return vertex } - nextCallReturned = putRecShort(vertex.rightSon as AVLVertex ) + nextCallReturned = putRecShort(vertex.rightSon as AVLVertex) } } if (nextCallReturned == null) return null - fun doBalanceChoreWhenLeftSubTreeChanged() : AVLVertex? { + fun doBalanceChoreWhenLeftSubTreeChanged(): AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null if (vertex.sonsHeightDiff + 1 == 2) return balance(vertex) vertex.sonsHeightDiff++ - return vertex + return vertex } - fun doBalanceChoreWhenRightSubTreeChanged() : AVLVertex? { + + fun doBalanceChoreWhenRightSubTreeChanged(): AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null if (vertex.sonsHeightDiff - 1 == -2) return balance(vertex) vertex.sonsHeightDiff-- return vertex } - when (nextCallReturned){ + when (nextCallReturned) { vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() - vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() + vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() else -> { if (compareKeys(nextCallReturned.key, vertex.key) == -1) { - vertex.leftSon = nextCallReturned - return doBalanceChoreWhenLeftSubTreeChanged() + vertex.leftSon = nextCallReturned + return doBalanceChoreWhenLeftSubTreeChanged() } - vertex.rightSon = nextCallReturned - return doBalanceChoreWhenRightSubTreeChanged() + vertex.rightSon = nextCallReturned + return doBalanceChoreWhenRightSubTreeChanged() } } } - + override fun remove(key: K): V? { if (!isEmpty()) { val removeRecReturned = removeRec(key, root as AVLVertex) @@ -84,6 +91,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { if (removeRecReturned.component2() != root) root = removeRecReturned.component2() } + RemovalStage.C -> root = null } return removeRecReturned.component3() @@ -91,13 +99,13 @@ class AVLSearchTree : AbstractBinarySearchTree> { return null } - enum class RemovalStage {A, B, C} + enum class RemovalStage { A, B, C } // a - don't need tree changes anymore // b - probably need some tree changes, but not nulling // c - need to null due "Son" property of (if exists) the parent of removed vertex + b - private fun removeRec(key: K, vertex : AVLVertex) : Triple , V?> { - val nextCallReturned : Triple ?, V?> + private fun removeRec(key: K, vertex: AVLVertex): Triple, V?> { + val nextCallReturned: Triple?, V?> // Triple consists of: // 1) removal stage // 2) if RemovalStage == a : just a vertex (don't need it later) @@ -107,46 +115,54 @@ class AVLSearchTree : AbstractBinarySearchTree> { when (compareKeys(key, vertex.key)) { -1 -> { if (vertex.leftSon == null) return Triple(RemovalStage.A, vertex, null) - nextCallReturned = removeRec(key, vertex.leftSon as AVLVertex) + nextCallReturned = removeRec(key, vertex.leftSon as AVLVertex) } + 1 -> { if (vertex.rightSon == null) return Triple(RemovalStage.A, vertex, null) - nextCallReturned = removeRec(key, vertex.rightSon as AVLVertex) + nextCallReturned = removeRec(key, vertex.rightSon as AVLVertex) } + else -> { return when ((vertex.leftSon == null) to (vertex.rightSon == null)) { true to true -> { size-- Triple(RemovalStage.C, vertex, vertex.value) } + true to false -> { size-- - Triple(RemovalStage.C, vertex.rightSon as AVLVertex, vertex.value) - } - false to true -> { + Triple(RemovalStage.C, vertex.rightSon as AVLVertex, vertex.value) + } + + false to true -> { size-- - Triple(RemovalStage.C, vertex.leftSon as AVLVertex, vertex.value) + Triple(RemovalStage.C, vertex.leftSon as AVLVertex, vertex.value) } - else -> Triple(RemovalStage.C, - prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value) + + else -> Triple( + RemovalStage.C, + prepareLargestLowerToReplaceVertex(vertex) as AVLVertex, vertex.value + ) } - } + } } - fun doBalanceChoreWhenLeftSubTreeChanged() : Triple , V?> { + fun doBalanceChoreWhenLeftSubTreeChanged(): Triple, V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff - 1 == -2) + if (vertex.sonsHeightDiff - 1 == -2) return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) vertex.sonsHeightDiff-- - return Triple(RemovalStage.B, vertex, nextCallReturned.third) + return Triple(RemovalStage.B, vertex, nextCallReturned.third) } - fun doBalanceChoreWhenRightSubTreeChanged() : Triple , V?> { + + fun doBalanceChoreWhenRightSubTreeChanged(): Triple, V?> { if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff + 1 == 2) + if (vertex.sonsHeightDiff + 1 == 2) return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) vertex.sonsHeightDiff++ - return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) + return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) } when (nextCallReturned.component1()) { RemovalStage.A -> return nextCallReturned @@ -159,28 +175,31 @@ class AVLSearchTree : AbstractBinarySearchTree> { vertex.leftSon = nextCallReturned.component2() return doBalanceChoreWhenLeftSubTreeChanged() } + else -> { vertex.rightSon = nextCallReturned.component2() return doBalanceChoreWhenRightSubTreeChanged() } } } + RemovalStage.C -> when (compareKeys(nextCallReturned.component2().key, vertex.key)) { -1 -> { vertex.leftSon = null return doBalanceChoreWhenLeftSubTreeChanged() } + else -> { vertex.rightSon = null return doBalanceChoreWhenRightSubTreeChanged() } - } - + } + } } - private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex? { + private fun prepareLargestLowerToReplaceVertex(vertex: AVLVertex): AVLVertex? { val substitute = getMaxKeyNodeRec(vertex.leftSon) if (substitute == null) return null remove(substitute.key) @@ -190,21 +209,21 @@ class AVLSearchTree : AbstractBinarySearchTree> { return substitute } - private fun balance(curVertex: AVLVertex) : AVLVertex { - var (rightSon, leftSon) = List?>(2){null} - fun setTwoSonHeightDiffs(values : Pair) { + private fun balance(curVertex: AVLVertex): AVLVertex { + var (rightSon, leftSon) = List?>(2) { null } + fun setTwoSonHeightDiffs(values: Pair) { curVertex.sonsHeightDiff = values.component1() - if (rightSon != null){ - (rightSon as AVLVertex).sonsHeightDiff = values.component2() + if (rightSon != null) { + (rightSon as AVLVertex).sonsHeightDiff = values.component2() return } - (leftSon as AVLVertex).sonsHeightDiff = values.component2() + (leftSon as AVLVertex).sonsHeightDiff = values.component2() } - - if(curVertex.sonsHeightDiff == -1) { - rightSon = curVertex.rightSon as AVLVertex + + if (curVertex.sonsHeightDiff == -1) { + rightSon = curVertex.rightSon as AVLVertex return if (rightSon.sonsHeightDiff == 1) { - val rightSonSLeftSon = rightSon.leftSon as AVLVertex + val rightSonSLeftSon = rightSon.leftSon as AVLVertex val subtreeRoot = bigRotateLeft(curVertex, rightSon) setTwoSonHeightDiffs( when (rightSonSLeftSon.sonsHeightDiff) { @@ -215,66 +234,68 @@ class AVLSearchTree : AbstractBinarySearchTree> { ) rightSonSLeftSon.sonsHeightDiff = 0 subtreeRoot - } - else { + } else { val subtreeRoot = rotateLeft(curVertex, rightSon) setTwoSonHeightDiffs( if (rightSon.sonsHeightDiff == 0) -1 to 1 else 0 to 0 - ) + ) subtreeRoot } } - leftSon = curVertex.leftSon as AVLVertex - return if (leftSon.sonsHeightDiff == -1) { - val leftSonSRightSon = leftSon.rightSon as AVLVertex - val subtreeRoot = bigRotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( - when (leftSonSRightSon.sonsHeightDiff) { - -1 -> 0 to 1 - 1 -> -1 to 0 - else -> 0 to 0 - } - ) - leftSonSRightSon.sonsHeightDiff = 0 - subtreeRoot - } - else { - val subtreeRoot = rotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( - if (leftSon.sonsHeightDiff == 0) 1 to -1 - else 0 to 0 - ) - subtreeRoot - } + leftSon = curVertex.leftSon as AVLVertex + return if (leftSon.sonsHeightDiff == -1) { + val leftSonSRightSon = leftSon.rightSon as AVLVertex + val subtreeRoot = bigRotateRight(curVertex, leftSon) + setTwoSonHeightDiffs( + when (leftSonSRightSon.sonsHeightDiff) { + -1 -> 0 to 1 + 1 -> -1 to 0 + else -> 0 to 0 + } + ) + leftSonSRightSon.sonsHeightDiff = 0 + subtreeRoot + } else { + val subtreeRoot = rotateRight(curVertex, leftSon) + setTwoSonHeightDiffs( + if (leftSon.sonsHeightDiff == 0) 1 to -1 + else 0 to 0 + ) + subtreeRoot + } } - private fun rotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { + private fun rotateLeft(curVertex: AVLVertex, rightSon: AVLVertex): AVLVertex { curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex return rightSon } - private fun rotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { + private fun rotateRight(curVertex: AVLVertex, leftSon: AVLVertex): AVLVertex { curVertex.leftSon = leftSon.rightSon leftSon.rightSon = curVertex return leftSon } - - private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { - val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) + + private fun bigRotateLeft(curVertex: AVLVertex, rightSon: AVLVertex): AVLVertex { + val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) curVertex.rightSon = curRightSon return rotateLeft(curVertex, curRightSon) } - private fun bigRotateRight(curVertex: AVLVertex, leftSon : AVLVertex) : AVLVertex { - val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) + private fun bigRotateRight(curVertex: AVLVertex, leftSon: AVLVertex): AVLVertex { + val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) curVertex.leftSon = curLeftSon return rotateRight(curVertex, curLeftSon) } constructor (comparator: Comparator? = null) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) } diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index d88c536..d985204 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -1,22 +1,29 @@ package main.trees + import main.vertexes.InterfaceBSTVertex import main.iterator.TreeIterator abstract class AbstractBinarySearchTree> { protected var comparator: Comparator? = null - protected var size : Long = 0L - protected var root : N? = null + protected var size: Long = 0L + protected var root: N? = null operator fun iterator(): Iterator> { return TreeIterator(root) } - fun size(): Long {return size} + fun size(): Long { + return size + } + + fun isEmpty(): Boolean { + return size == 0L + } - fun isEmpty(): Boolean {return size == 0L} - - fun get(key: K): V? {return getRec(key)} + fun get(key: K): V? { + return getRec(key) + } fun getPair(key: K): Pair? { val value = get(key) @@ -28,7 +35,7 @@ abstract class AbstractBinarySearchTree> { return if (minKeyNode == null) null else minKeyNode.value } - fun getMax(): V?{ + fun getMax(): V? { val maxKeyNode = getMaxKeyNodeRec() return if (maxKeyNode == null) null else maxKeyNode.value } @@ -43,7 +50,7 @@ abstract class AbstractBinarySearchTree> { return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) } - abstract fun put(key: K, value: V, replaceIfExists : Boolean = true) + abstract fun put(key: K, value: V, replaceIfExists: Boolean = true) fun putAll(map: Map, replaceIfExists: Boolean = true) { for (pair in map) put(pair.key, pair.value, replaceIfExists) @@ -65,7 +72,7 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMinKeyNodeRec(vertex: N? = root) : N? { + protected fun getMinKeyNodeRec(vertex: N? = root): N? { if (vertex == null) return null else { return if (vertex.leftSon == null) vertex @@ -73,7 +80,7 @@ abstract class AbstractBinarySearchTree> { } } - protected fun getMaxKeyNodeRec(vertex: N? = root) : N? { + protected fun getMaxKeyNodeRec(vertex: N? = root): N? { if (vertex == null) return null else { return if (vertex.rightSon == null) vertex @@ -81,19 +88,18 @@ abstract class AbstractBinarySearchTree> { } } - protected fun compareKeys(firstKey: K, secondKey: K): Int{ + protected fun compareKeys(firstKey: K, secondKey: K): Int { val cpr = comparator return if (cpr != null) { when (cpr.compare(firstKey, secondKey)) { - in Int.MIN_VALUE .. -1 -> -1 - 0 -> 0 + in Int.MIN_VALUE..-1 -> -1 + 0 -> 0 else -> 1 } - } - else { + } else { val comparableKey = firstKey as Comparable - when (comparableKey.compareTo(secondKey)) { - in Int.MIN_VALUE .. -1 -> -1 + when (comparableKey.compareTo(secondKey)) { + in Int.MIN_VALUE..-1 -> -1 0 -> 0 else -> 1 } diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index 71259a0..6b58d17 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -1,13 +1,22 @@ package main.trees + import main.vertexes.SimpleBSTVertex -class SimpleBinarySearchTree : AbstractBinarySearchTree> { +class SimpleBinarySearchTree : AbstractBinarySearchTree> { - override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} + override fun put(key: K, value: V, replaceIfExists: Boolean) { + TODO() + } - override fun remove(key: K): V? {TODO()} + override fun remove(key: K): V? { + TODO() + } constructor(comparator: Comparator?) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( + map, + replaceIfExists, + comparator + ) } diff --git a/lib/src/main/kotlin/vertexes/AVLVertex.kt b/lib/src/main/kotlin/vertexes/AVLVertex.kt index 291bc9a..6194c2d 100644 --- a/lib/src/main/kotlin/vertexes/AVLVertex.kt +++ b/lib/src/main/kotlin/vertexes/AVLVertex.kt @@ -3,7 +3,7 @@ package main.vertexes class AVLVertex( override var key: K, override var value: V -): InterfaceBSTVertex> { +) : InterfaceBSTVertex> { override var leftSon: AVLVertex? = null override var rightSon: AVLVertex? = null @@ -14,7 +14,7 @@ class AVLVertex( value: V, leftSon: AVLVertex?, rightSon: AVLVertex?, - sonsHeightDiff : Int = 0 + sonsHeightDiff: Int = 0 ) : this(key, value) { this.leftSon = leftSon this.rightSon = rightSon diff --git a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt index 2e76767..9041ed6 100644 --- a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt +++ b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt @@ -3,7 +3,7 @@ package main.vertexes class SimpleBSTVertex( override var key: K, override var value: V -): InterfaceBSTVertex> { +) : InterfaceBSTVertex> { override var leftSon: SimpleBSTVertex? = null override var rightSon: SimpleBSTVertex? = null diff --git a/lib/src/test/kotlin/trees/RBSearchTreeAbstractMethodsTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeAbstractMethodsTest.kt deleted file mode 100644 index 143707e..0000000 --- a/lib/src/test/kotlin/trees/RBSearchTreeAbstractMethodsTest.kt +++ /dev/null @@ -1,171 +0,0 @@ -package trees - -import main.trees.RBSearchTree -import main.vertexes.RBVertex -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import kotlin.test.assertEquals - -class RBSearchTreeAbstractMethodsTest { - private lateinit var rbTree: RBSearchTree - - @BeforeEach - fun setup() { - rbTree = RBSearchTree() - } - - @Test - fun `test size after put`(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - val previousSize = rbTree.size() - val expectedResult = previousSize + 1 - rbTree.put(11, segment.random()) - assertEquals(expectedResult, rbTree.size()) - } - - @Test - fun `test size after remove`(){ - val segment = 1..10 - val listOfKeys: MutableList = mutableListOf() - for (i in 0 until segment.random()){ - val key = segment.random() - listOfKeys.add(key) - rbTree.put(key, segment.random()) - } - val previousSize = rbTree.size() - val expectedResult = previousSize - 1 - rbTree.remove(listOfKeys.random()) - assertEquals(expectedResult, rbTree.size()) - } - - @Test - fun `size can't be negative`(){ - val segment = 1..10 - val listOfKeys: MutableList = mutableListOf() - for (i in 0 until segment.random()){ - val key = segment.random() - listOfKeys.add(key) - rbTree.put(key, segment.random()) - } - listOfKeys.forEach { rbTree.remove(it) } - rbTree.remove(segment.random()) - assertEquals(0, rbTree.size()) - } - - @Test - fun `check for empty`(){ - val segment = 1..10 - val listOfKeys: MutableList = mutableListOf() - for (i in 0 until segment.random()){ - val key = segment.random() - listOfKeys.add(key) - rbTree.put(key, segment.random()) - } - listOfKeys.forEach { rbTree.remove(it) } - assertEquals(true, rbTree.isEmpty()) - } - - @Test - fun `get`(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - rbTree.put(7, 44536643) - assertEquals(44536643, rbTree.get(7)) - } - - @Test - fun `get but such vertex doesn't exist`(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - assertEquals(null, rbTree.get(11)) - } - - @Test - fun getPair(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - rbTree.put(7, 44536643) - assertEquals(Pair(7, 44536643), rbTree.getPair(7)) - } - - @Test - fun `getPair but such vertex doesn't exist`(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - assertEquals(null, rbTree.getPair(11)) - } - - @Test - fun getMin(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - rbTree.put(1, 44536643) - assertEquals(44536643, rbTree.getMin()) - } - - @Test - fun `getMin but tree is empty`(){ - assertEquals(null, rbTree.getMin()) - } - - @Test - fun getMax(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - rbTree.put(10, 44536643) - assertEquals(44536643, rbTree.getMax()) - } - - @Test - fun `getMax but tree is empty`(){ - assertEquals(null, rbTree.getMax()) - } - - @Test - fun getMinKeyPair(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - rbTree.put(1, 44536643) - assertEquals(Pair(1, 44536643), rbTree.getMinKeyPair()) - } - - @Test - fun `getMinKeyPair but tree is empty`(){ - assertEquals(null, rbTree.getMinKeyPair()) - } - - @Test - fun getMaxKeyPair(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - rbTree.put(10, 44536643) - assertEquals(Pair(10, 44536643), rbTree.getMaxKeyPair()) - } - - @Test - fun `getMaxKeyPair but tree is empty`(){ - assertEquals(null, rbTree.getMaxKeyPair()) - } - -// @Test -// fun putAll(){ -// TODO() -// } - - @Test - fun removeAndReturnPair(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - rbTree.put(7, 44536643) - assertEquals(Pair(7, 44536643), rbTree.removeAndReturnPair(7)) - assertEquals(null, rbTree.get(7)) - } - - @Test - fun `removeAndReturnPair but vertex doesn't exist`(){ - val segment = 1..10 - for (i in 0 until segment.random()) rbTree.put(segment.random(), segment.random()) - assertEquals(null, rbTree.removeAndReturnPair(11)) - } -} \ No newline at end of file From c9e813e094886f96269e78a8ed833bcb283c74ef Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 01:38:07 +0300 Subject: [PATCH 155/227] style: add spaces after // --- lib/src/main/kotlin/trees/RBSearchTree.kt | 82 +++++++++++------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 156f67d..df82664 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -4,19 +4,19 @@ import main.vertexes.RBVertex class RBSearchTree : AbstractBinarySearchTree> { - //4 cases we need to look at - //1) remove red vertex with 0 children -> just remove vertex + // 4 cases we need to look at + // 1) remove red vertex with 0 children -> just remove vertex - //2) remove red or black vertex with 2 children -> - //find min vertex on the right subtree and swap it's key and value with - //key and value of vertex that we need to remove - //Now we can work with vertex which has 1 or 0 children + // 2) remove red or black vertex with 2 children -> + // find min vertex on the right subtree and swap it's key and value with + // key and value of vertex that we need to remove + // Now we can work with vertex which has 1 or 0 children - //3) remove black vertex with 1 child -> child can be only red - //so we just swap child's key and value with key and value that we need to remove - //and look at case 1) + // 3) remove black vertex with 1 child -> child can be only red + // so we just swap child's key and value with key and value that we need to remove + // and look at case 1) - //4) remove black vertex with 0 children -> just remove vertex + // 4) remove black vertex with 0 children -> just remove vertex override fun remove(key: K): V? { val vertex: RBVertex = getVertex(key) ?: return null --size @@ -61,24 +61,24 @@ class RBSearchTree : AbstractBinarySearchTree> { return false } - //we need to balance tree after removal black vertex with 0 children - //in this fun we need to look at vertex's parent and brother + // we need to balance tree after removal black vertex with 0 children + // in this fun we need to look at vertex's parent and brother - //1) brother is black and brother's rightSon is red -> we paint - //brother in parent's color, parent and brother's rightSon in black - //then rotate left + // 1) brother is black and brother's rightSon is red -> we paint + // brother in parent's color, parent and brother's rightSon in black + // then rotate left - //2) brother is black and brother's leftSon is red (rightSon - black) -> - //we swap colors of brother and brother's leftSon and rotate right - //then look at case 1 + // 2) brother is black and brother's leftSon is red (rightSon - black) -> + // we swap colors of brother and brother's leftSon and rotate right + // then look at case 1 - //3) brother is black and both sons are black -> we make brother red - //then we need to launch algorithm from the parent because of it - //can be red, so we have red parent and red son or black so - //the black height of all subtree decreased + // 3) brother is black and both sons are black -> we make brother red + // then we need to launch algorithm from the parent because of it + // can be red, so we have red parent and red son or black so + // the black height of all subtree decreased - //4) brother is red -> make brother black, parent red and - //rotate left. We move conflict on level below, then we look at the previous cases + // 4) brother is red -> make brother black, parent red and + // rotate left. We move conflict on level below, then we look at the previous cases private fun balanceAfterRemove(vertex: RBVertex?) { var currentVertex = vertex while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { @@ -156,8 +156,8 @@ class RBSearchTree : AbstractBinarySearchTree> { currentVertex?.isRed = false } - //finds vertex by corresponding key - //if such vertex doesn't exist returns null + // finds vertex by corresponding key + // if such vertex doesn't exist returns null private fun getVertex(key: K): RBVertex? { var currentVertex: RBVertex? = root @@ -176,8 +176,8 @@ class RBSearchTree : AbstractBinarySearchTree> { return currentVertex } - //finds free place and inserts newVertex, colors it in red - //if vertex with such key exists, replaces it + // finds free place and inserts newVertex, colors it in red + // if vertex with such key exists, replaces it override fun put(key: K, value: V, replaceIfExists: Boolean) { var currentVertex: RBVertex? = root var parent: RBVertex? = null @@ -216,18 +216,18 @@ class RBSearchTree : AbstractBinarySearchTree> { balanceAfterPut(currentVertex) } - //we need to balance tree in two cases - //1) when newVertex is root, so our root is red - //2) when parent of our newVertex is red(because newVertex is also red) + // we need to balance tree in two cases + // 1) when newVertex is root, so our root is red + // 2) when parent of our newVertex is red(because newVertex is also red) - //in first case we just make the root black - //in second case we need to look at the newVertex's uncle + // in first case we just make the root black + // in second case we need to look at the newVertex's uncle - //if uncle is red, we make it black and newVertex's parent black and grandparent red - //launch algorithm to grandfather because now it's color changed to red + // if uncle is red, we make it black and newVertex's parent black and grandparent red + // launch algorithm to grandfather because now it's color changed to red - //if uncle is black we also make newVertex's parent black, grandparent red - //and rotate it right + // if uncle is black we also make newVertex's parent black, grandparent red + // and rotate it right private fun balanceAfterPut(vertex: RBVertex) { var currentVertex = vertex @@ -293,8 +293,8 @@ class RBSearchTree : AbstractBinarySearchTree> { newVertex?.parent = oldVertex.parent } - //suppose that vertex has a rightSon - //swap parent and rightSon, rightSon's leftSon becomes parent's rightSon + // suppose that vertex has a rightSon + // swap parent and rightSon, rightSon's leftSon becomes parent's rightSon private fun rotateLeft(vertex: RBVertex) { val rightVertex: RBVertex? = vertex.rightSon vertex.rightSon = rightVertex?.leftSon @@ -309,8 +309,8 @@ class RBSearchTree : AbstractBinarySearchTree> { rightVertex?.leftSon = vertex } - //suppose that vertex has a leftSon - //swap parent and leftSon, leftSon's rightSon becomes parent's leftSon + // suppose that vertex has a leftSon + // swap parent and leftSon, leftSon's rightSon becomes parent's leftSon private fun rotateRight(vertex: RBVertex) { val leftVertex: RBVertex? = vertex.leftSon vertex.leftSon = leftVertex?.rightSon From bf7c378d2c640bc361688b05414ed3977f997408 Mon Sep 17 00:00:00 2001 From: Victoria Lustyuk <130183523+vicitori@users.noreply.github.com> Date: Tue, 2 Apr 2024 01:42:23 +0300 Subject: [PATCH 156/227] refactor: update code insertions in README.md --- README.md | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index ef1a027..fb5bdc4 100644 --- a/README.md +++ b/README.md @@ -8,23 +8,20 @@ ## About Project `BinTreeKit` is a library that provides implementations for three types of trees: `SimpleBinarySearchTree`, `AVLSearchTree` and `RBSearchTree`. The library is designed to simplify the process of managing hierarchical data, allowing Kotlin developers to focus on building robust and scalable applications. -
- Table of Contents - - - - [About Project](#about-project) - - [Usage](#usage) - - [Library Features](#library-features) - - [Constructors](#constructors) - - [Methods](#methods) - - [Tree Properties](#tree-properties) - - [Iterator](#iterator) - - [Constructors](#constructors-1) - - [Methods](#methods-1) - - [Developers](#developers) - - [Contributing](#contributing) - - [License](#license) -
+ +#### Table of Contents +- [About Project](#about-project) +- [Usage](#usage) +- [Library Features](#library-features) + - [Constructors](#constructors) + - [Methods](#methods) + - [Tree Properties](#tree-properties) + - [Iterator](#iterator) + - [Constructors](#constructors-1) + - [Methods](#methods-1) +- [Developers](#developers) +- [Contributing](#contributing) +- [License](#license) ## Usage @@ -37,30 +34,39 @@ import main.trees.RBSearchTree 2. **Instantiate Trees:** ```kotlin +val map = mapOf(Pair(1, "cat"), Pair(2, "dog")) + // create a Simple Binary Search Tree -val bstTree = SimpleBinarySearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) +val emptyBstTree = SimpleBinarySearchTree() +val bstTree = SimpleBinarySearchTree(map) // create an AVL Search Tree -val avlTree = AVLSearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) +val emptyAvlTree = AVLSearchTree() +val avlTree = AVLSearchTree(map) // create a Red-Black Search Tree -val rbTree = RBSearchTree(mapOf(Pair(1, "cat"), Pair(2, "dog"))) +val emptyRbTree = RBSearchTree() +val rbTree = RBSearchTree(map) ``` + 3. **Use Tree Methods:** ```kotlin // put key-value pairs with different values of replaceIfExists perematers -bstTree.putAll(mapOf(Pair(2, "hamster"), Pair(3, "bird")), true) +bstTree.putAll(map, true) rbTree.put(4, "horse", false) // remove key-value pair from tree and return value println(rbTree.remove(4)) // output: horse bstTree.remove(1) +//get key-value pair from tree +println(avlTree.getMin()) //output: cat + // pairwise iteration for (pair in avlTree) { - print(pair) -} // output: (1, "cat")(2, "dog") + print("${pair.second}, ") +} // output: cat, dog ``` From 221b31ed0e0daa77d5458528cb9837a509426d1c Mon Sep 17 00:00:00 2001 From: Kostya Oreshin <84198636+TerrMen@users.noreply.github.com> Date: Tue, 2 Apr 2024 02:09:15 +0300 Subject: [PATCH 157/227] style: final changes according to the linter --- lib/src/test/kotlin/trees/RBSearchTreeTest.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt index cd4ebea..402aed1 100644 --- a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt @@ -209,7 +209,7 @@ class RBSearchTreeTest { rbTree.put(11, "Shady") rbTree.remove(11) - //now vertexes with keys 9 and 12 are black + // now vertexes with keys 9 and 12 are black rbTree.remove(9) expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) @@ -230,7 +230,7 @@ class RBSearchTreeTest { rbTree.put(97, "ninety-seven") rbTree.put(95, "ninety-five") - //now vertex with key 96 is red, with key 65 - black + // now vertex with key 96 is red, with key 65 - black rbTree.remove(65) expectedResult = listOf( @@ -285,7 +285,7 @@ class RBSearchTreeTest { rbTree.put(3, "Shady") rbTree.remove(3) - //now vertexes with keys 2 and 5 are black + // now vertexes with keys 2 and 5 are black rbTree.remove(5) expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) @@ -306,7 +306,7 @@ class RBSearchTreeTest { rbTree.put(69, "sixty-nine") rbTree.put(17, "seventeen") - //now vertex with key 15 is red, with key 51 - black + // now vertex with key 15 is red, with key 51 - black rbTree.remove(51) expectedResult = listOf( @@ -322,5 +322,4 @@ class RBSearchTreeTest { rbTree = RBSearchTree(testMap) expectedResult = listOf(Pair(2, "two"), Pair(3, "three"), Pair(1, "one")) } - } From b0ca2537640f4db0ffcf365d6121bed583bf452e Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Tue, 2 Apr 2024 02:22:12 +0300 Subject: [PATCH 158/227] docs: add warning about attempting to perform put, remove, or get operations on a non-empty binary search tree with a key that is incomparable with the keys in the tree --- lib/src/main/trees/AVLSearchTree.kt | 13 +++++++++++++ lib/src/main/trees/AbstractBinarySearchTree.kt | 13 +++++++++++++ lib/src/main/trees/RBSearchTree.kt | 13 +++++++++++++ lib/src/main/trees/SimpleBinarySearchTree.kt | 13 +++++++++++++ 4 files changed, 52 insertions(+) diff --git a/lib/src/main/trees/AVLSearchTree.kt b/lib/src/main/trees/AVLSearchTree.kt index 49b7f77..0a64587 100644 --- a/lib/src/main/trees/AVLSearchTree.kt +++ b/lib/src/main/trees/AVLSearchTree.kt @@ -5,6 +5,19 @@ import main.vertexes.AVLVertex * An implementation of a binary search tree that automatically balances itself using AVL rotations. * It extends AbstractBinarySearchTree and uses AVLVertex as vertices. * This class extends AbstractBinarySearchTree and provides methods to put, remove for key-value pairs. + * + * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that + * is incomparable with the keys in the tree, the behavior is as follows: + * + * **Put**: If an attempt is made to put a key-value pair with a key that is incomparable with the existing + * keys in the tree, the insertion operation will fail and the tree will remain unchanged. + * + * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys + * in the tree, the removal operation will fail and the tree will remain unchanged. + * + * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not + * find any matching key-value pair the get operation will fail. + * * @param K the type of keys in the tree * @param V the type of values associated with the keys * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. diff --git a/lib/src/main/trees/AbstractBinarySearchTree.kt b/lib/src/main/trees/AbstractBinarySearchTree.kt index 8b6785b..7426816 100644 --- a/lib/src/main/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/trees/AbstractBinarySearchTree.kt @@ -4,6 +4,19 @@ import main.iterator.TreeIterator /** * An abstract class representing a binary search tree. + * + * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that + * is incomparable with the keys in the tree, the behavior is as follows: + * + * **Put**: If an attempt is made to insert a key-value pair with a key that is incomparable with the existing + * keys in the tree, the insertion operation will fail and the tree will remain unchanged. + * + * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys + * in the tree, the removal operation will fail and the tree will remain unchanged. + * + * **Get**: When searching for a key that is incomparable with the keys in the tree, the search operation will not + * find any matching key-value pair. + * * @param K The type of keys. * @param V The type of values. * @param N The type of vertices implementing the [InterfaceBSTVertex] interface. diff --git a/lib/src/main/trees/RBSearchTree.kt b/lib/src/main/trees/RBSearchTree.kt index 6c0d196..6383203 100644 --- a/lib/src/main/trees/RBSearchTree.kt +++ b/lib/src/main/trees/RBSearchTree.kt @@ -11,6 +11,19 @@ import main.vertexes.RBVertex * - Every leaf (NIL) is black. * - If a vertex is red, then both its children are black. * - Every simple path from a vertex to a descendant leaf (NIL) has the same number of black vertexes. + * + * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that + * is incomparable with the keys in the tree, the behavior is as follows: + * + * **Put**: If an attempt is made to put a key-value pair with a key that is incomparable with the existing + * keys in the tree, the insertion operation will fail and the tree will remain unchanged. + * + * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys + * in the tree, the removal operation will fail and the tree will remain unchanged. + * + * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not + * find any matching key-value pair the get operation will fail. + * * @param K the type of keys in the tree * @param V the type of values associated with the keys * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt index 21fb621..fbb450d 100644 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/trees/SimpleBinarySearchTree.kt @@ -4,6 +4,19 @@ import main.vertexes.SimpleBSTVertex /** * This class represents a simple implementation of a binary search tree. * It extends AbstractBinarySearchTree and uses SimpleBSTVertex as vertices. + * + * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that + * is incomparable with the keys in the tree, the behavior is as follows: + * + * **Put**: If an attempt is made to put a key-value pair with a key that is incomparable with the existing + * keys in the tree, the insertion operation will fail and the tree will remain unchanged. + * + * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys + * in the tree, the removal operation will fail and the tree will remain unchanged. + * + * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not + * find any matching key-value pair the get operation will fail. + * * @param K The type of keys in the tree. * @param V The type of values in the tree. * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. From 0f087948714d0b138a1921d953a0b71d5ad8d0a6 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Tue, 2 Apr 2024 02:38:00 +0300 Subject: [PATCH 159/227] fix: remove the wrong file --- lib/src/main/trees/SimpleBinarySearchTree.kt | 77 -------------------- 1 file changed, 77 deletions(-) delete mode 100644 lib/src/main/trees/SimpleBinarySearchTree.kt diff --git a/lib/src/main/trees/SimpleBinarySearchTree.kt b/lib/src/main/trees/SimpleBinarySearchTree.kt deleted file mode 100644 index fbb450d..0000000 --- a/lib/src/main/trees/SimpleBinarySearchTree.kt +++ /dev/null @@ -1,77 +0,0 @@ -package main.trees -import main.vertexes.SimpleBSTVertex - -/** - * This class represents a simple implementation of a binary search tree. - * It extends AbstractBinarySearchTree and uses SimpleBSTVertex as vertices. - * - * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that - * is incomparable with the keys in the tree, the behavior is as follows: - * - * **Put**: If an attempt is made to put a key-value pair with a key that is incomparable with the existing - * keys in the tree, the insertion operation will fail and the tree will remain unchanged. - * - * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys - * in the tree, the removal operation will fail and the tree will remain unchanged. - * - * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not - * find any matching key-value pair the get operation will fail. - * - * @param K The type of keys in the tree. - * @param V The type of values in the tree. - * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. - * @property size The number of elements in the tree. - * @property root The root vertex of the tree. - */ -class SimpleBinarySearchTree : AbstractBinarySearchTree> { - - /** - * Associates the specified value with the specified key in this tree. - * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. - * @param key the key with which the specified value is to be associated - * @param value the value to be associated with the specified key - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it - */ - override fun put(key: K, value: V, replaceIfExists: Boolean) {TODO()} - - /** - * Recursively inserts a key-value pair into the tree. - * @param key The key to insert. - * @param value The value associated with the key. - * @param replaceIfExists If true, replaces the existing value for the key. - * @param vertex The current vertex in the recursion. - */ - - /** - * Removes the key-value pair associated with the specified key from the tree. - * @param key The key to remove. - * @return The value associated with the removed key, or null if the key is not found. - */ - override fun remove(key: K): V? {TODO()} - - /** - * Recursively removes the key-value pair associated with the specified key from the tree. - * This method traverses the tree recursively to find the node with the given key and removes it. - * If the key is found and the corresponding node has both left and right children, - * the method replaces the node's key and value with those of the minimum key node in its right subtree, - * and then removes the minimum key node from the right subtree. - * If the key is not found, it returns a pair containing the vertex and null value. - * @param key The key to remove. - * @param vertex The current vertex being examined in the recursion. - * @return A pair containing the updated vertex and the value associated with the removed key, or null if the key is not found. - */ - - /** - * Constructs a new binary search tree with the specified comparator. - * @param comparator the comparator to use for comparing keys, or null to use natural ordering - */ - constructor(comparator: Comparator?) : super(comparator) - - /** - * Constructs a new binary search tree and initializes it with the mappings from the specified map. - * @param map the map whose mappings are to be added to this tree - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it - * @param comparator the comparator to use for comparing keys, or null to use natural ordering - */ - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) -} From cbbe0907a1dd8d06ce53a7b7f090411b09529474 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Tue, 2 Apr 2024 02:39:43 +0300 Subject: [PATCH 160/227] docs: add documentation to SimpleBinarySearchTree --- .../kotlin/trees/SimpleBinarySearchTree.kt | 66 ++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index d165ea8..fa532fa 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -1,8 +1,37 @@ package main.trees import main.vertexes.SimpleBSTVertex -open class SimpleBinarySearchTree : AbstractBinarySearchTree> { +/** + * This class represents a simple implementation of a binary search tree. + * It extends AbstractBinarySearchTree and uses SimpleBSTVertex as vertices. + * + * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that + * is incomparable with the keys in the tree, the behavior is as follows: + * + * **Put**: If an attempt is made to put a key-value pair with a key that is incomparable with the existing + * keys in the tree, the insertion operation will fail and the tree will remain unchanged. + * + * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys + * in the tree, the removal operation will fail and the tree will remain unchanged. + * + * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not + * find any matching key-value pair the get operation will fail. + * + * @param K The type of keys in the tree. + * @param V The type of values in the tree. + * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. + * @property size The number of elements in the tree. + * @property root The root vertex of the tree. + */ +class SimpleBinarySearchTree : AbstractBinarySearchTree> { + /** + * Associates the specified value with the specified key in this tree. + * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. + * @param key the key with which the specified value is to be associated + * @param value the value to be associated with the specified key + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + */ override fun put(key: K, value: V, replaceIfExists: Boolean) { if (root == null) { root = SimpleBSTVertex(key, value) @@ -11,6 +40,13 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree? = root) { if (vertex == null) return when (compareKeys(key, vertex.key)) { @@ -32,12 +68,28 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree? = root): Triple?, V?, Boolean> { if (vertex == null) return Triple(null, null, false) @@ -74,7 +126,17 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree?) : super(comparator) + /** + * Constructs a new binary search tree with the specified comparator. + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ + constructor(comparator: Comparator? = null) : super(comparator) + /** + * Constructs a new binary search tree and initializes it with the mappings from the specified map. + * @param map the map whose mappings are to be added to this tree + * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * @param comparator the comparator to use for comparing keys, or null to use natural ordering + */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super(map, replaceIfExists, comparator) } From 947224728ebc3fef2e135e01eed57da72d8e6e26 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 11:46:21 +0300 Subject: [PATCH 161/227] style: changes according to linter --- lib/src/main/kotlin/iterator/TreeIterator.kt | 4 +- lib/src/main/kotlin/trees/AVLSearchTree.kt | 40 +- lib/src/test/kotlin/AVLTreeForTest.kt | 48 ++- lib/src/test/kotlin/AVLTreeTest.kt | 373 +++++++++++-------- lib/src/test/kotlin/TestIterator.kt | 6 +- 5 files changed, 276 insertions(+), 195 deletions(-) diff --git a/lib/src/main/kotlin/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt index e11b5b3..036c139 100644 --- a/lib/src/main/kotlin/iterator/TreeIterator.kt +++ b/lib/src/main/kotlin/iterator/TreeIterator.kt @@ -3,9 +3,9 @@ package main.iterator import main.vertexes.InterfaceBSTVertex import java.util.LinkedList -open class TreeIterator>( +open class TreeIterator>( vertex: N? -): Iterator> { +) : Iterator> { protected val stack = LinkedList() init { diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 0de7c29..1e0cda1 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -2,7 +2,7 @@ package main.trees import main.vertexes.AVLVertex -open class AVLSearchTree : AbstractBinarySearchTree> { +open class AVLSearchTree : AbstractBinarySearchTree> { override fun put(key: K, value: V, replaceIfExists: Boolean) { if (!isEmpty()) { @@ -16,12 +16,15 @@ open class AVLSearchTree : AbstractBinarySearchTree> size++ } - private fun putRec(key: K, value: V, - replaceIfExists: Boolean, vertex: AVLVertex) : AVLVertex? { - fun putRecShort(vrtx : AVLVertex) : AVLVertex? { + private fun putRec( + key: K, value: V, + replaceIfExists: Boolean, vertex: AVLVertex + ): AVLVertex? { + fun putRecShort(vrtx: AVLVertex): AVLVertex? { return putRec(key, value, replaceIfExists, vrtx) } - val nextCallReturned : AVLVertex? + + val nextCallReturned: AVLVertex? when (compareKeys(key, vertex.key)) { -1 -> { if (vertex.leftSon == null) { @@ -97,7 +100,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> return null } - private enum class RemovalStage {A, B, C, D} + private enum class RemovalStage { A, B, C, D } // A - don't need tree changes anymore // B - probably need some tree changes, but not nulling // C - need to null due "Son" property of (if exists) the parent of removed vertex + b @@ -131,14 +134,18 @@ open class AVLSearchTree : AbstractBinarySearchTree> true to false -> { size-- - Triple(RemovalStage.B, vertex.rightSon as AVLVertex, vertex.value) + Triple(RemovalStage.B, vertex.rightSon as AVLVertex, vertex.value) } + false to true -> { size-- - Triple(RemovalStage.B, vertex.leftSon as AVLVertex, vertex.value) + Triple(RemovalStage.B, vertex.leftSon as AVLVertex, vertex.value) } - else -> Triple(RemovalStage.D, - prepareLargestLowerToReplaceVertex(vertex), vertex.value) + + else -> Triple( + RemovalStage.D, + prepareLargestLowerToReplaceVertex(vertex), vertex.value + ) } } } @@ -190,7 +197,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> return doBalanceChoreWhenRightSubTreeChanged() } } - + RemovalStage.D -> { if (compareKeys(nextCallReturned.component2().key, vertex.key) == -1) vertex.leftSon = nextCallReturned.component2() @@ -201,8 +208,8 @@ open class AVLSearchTree : AbstractBinarySearchTree> } } - private fun prepareLargestLowerToReplaceVertex(vertex : AVLVertex ) : AVLVertex { - val substitute = getMaxKeyNodeRec(vertex.leftSon) as AVLVertex + private fun prepareLargestLowerToReplaceVertex(vertex: AVLVertex): AVLVertex { + val substitute = getMaxKeyNodeRec(vertex.leftSon) as AVLVertex remove(substitute.key) substitute.leftSon = vertex.leftSon substitute.rightSon = vertex.rightSon @@ -257,8 +264,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> ) leftSonSRightSon.sonsHeightDiff = 0 subtreeRoot - } - else { + } else { val subtreeRoot = rotateRight(curVertex, leftSon) setTwoSonHeightDiffs( if (leftSon.sonsHeightDiff == 0) 1 to -1 @@ -280,8 +286,8 @@ open class AVLSearchTree : AbstractBinarySearchTree> return leftSon } - private fun bigRotateLeft(curVertex: AVLVertex, rightSon : AVLVertex ) : AVLVertex { - val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) + private fun bigRotateLeft(curVertex: AVLVertex, rightSon: AVLVertex): AVLVertex { + val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) curVertex.rightSon = curRightSon return rotateLeft(curVertex, curRightSon) } diff --git a/lib/src/test/kotlin/AVLTreeForTest.kt b/lib/src/test/kotlin/AVLTreeForTest.kt index 229193a..8a27826 100644 --- a/lib/src/test/kotlin/AVLTreeForTest.kt +++ b/lib/src/test/kotlin/AVLTreeForTest.kt @@ -3,60 +3,72 @@ import main.trees.AVLSearchTree import kotlin.math.max import kotlin.collections.mutableListOf import kotlin.collections.mutableMapOf -class AVLTreeForTest : AVLSearchTree { - fun getRootT() : AVLVertex? {return root} - - fun getVertexesInDFSOrder() : MutableList> { - val vertexes : MutableList> = mutableListOf() +class AVLTreeForTest : AVLSearchTree { + + fun getRootT(): AVLVertex? { + return root + } + + fun getVertexesInDFSOrder(): MutableList> { + val vertexes: MutableList> = mutableListOf() getVertexesRec(root, vertexes) return vertexes } - private fun getVertexesRec(curVertex : AVLVertex?, vrtList: MutableList>) { + + private fun getVertexesRec(curVertex: AVLVertex?, vrtList: MutableList>) { if (curVertex == null) return vrtList.add(curVertex) getVertexesRec(curVertex.leftSon, vrtList) getVertexesRec(curVertex.rightSon, vrtList) } - fun getHeights() : MutableMap { - val heights : MutableMap = mutableMapOf() + + fun getHeights(): MutableMap { + val heights: MutableMap = mutableMapOf() if (root == null) return heights - getHeightsRec(root as AVLVertex, heights) + getHeightsRec(root as AVLVertex, heights) return heights } - private fun getHeightsRec(rootOfSubtree : AVLVertex, heights : MutableMap) : Int { + + private fun getHeightsRec(rootOfSubtree: AVLVertex, heights: MutableMap): Int { return when ((rootOfSubtree.leftSon == null) to (rootOfSubtree.rightSon == null)) { true to true -> { heights.put(rootOfSubtree.key, 0) 0 } + true to false -> { - val height = getHeightsRec(rootOfSubtree.rightSon as AVLVertex, heights) + 1 + val height = getHeightsRec(rootOfSubtree.rightSon as AVLVertex, heights) + 1 heights.put(rootOfSubtree.key, height) height } + false to true -> { - val height = getHeightsRec(rootOfSubtree.leftSon as AVLVertex, heights) + 1 + val height = getHeightsRec(rootOfSubtree.leftSon as AVLVertex, heights) + 1 heights.put(rootOfSubtree.key, height) height } + else -> { - val heightOfLeftSubtree = getHeightsRec(rootOfSubtree.leftSon as AVLVertex, heights) - val heightOfRightSubtree = getHeightsRec(rootOfSubtree.rightSon as AVLVertex, heights) + val heightOfLeftSubtree = getHeightsRec(rootOfSubtree.leftSon as AVLVertex, heights) + val heightOfRightSubtree = getHeightsRec(rootOfSubtree.rightSon as AVLVertex, heights) val height = max(heightOfLeftSubtree, heightOfRightSubtree) + 1 heights.put(rootOfSubtree.key, height) max(heightOfLeftSubtree, heightOfRightSubtree) + 1 } } } - constructor (root: AVLVertex, size: Long, comparator: Comparator? = null) : - super(comparator) { + + constructor (root: AVLVertex, size: Long, comparator: Comparator? = null) : + super(comparator) { this.root = root this.size = size } constructor (comparator: Comparator? = null) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, - comparator: Comparator? = null) : super(map, replaceIfExists, comparator) + constructor( + map: Map, replaceIfExists: Boolean = true, + comparator: Comparator? = null + ) : super(map, replaceIfExists, comparator) } \ No newline at end of file diff --git a/lib/src/test/kotlin/AVLTreeTest.kt b/lib/src/test/kotlin/AVLTreeTest.kt index 6b116e9..25e7243 100644 --- a/lib/src/test/kotlin/AVLTreeTest.kt +++ b/lib/src/test/kotlin/AVLTreeTest.kt @@ -7,9 +7,11 @@ import kotlin.collections.hashMapOf class AVLTreeTest { - private fun makeEmptyTree() : AVLTreeForTest {return AVLTreeForTest()} + private fun makeEmptyTree(): AVLTreeForTest { + return AVLTreeForTest() + } - //putTest + // putTest @Test fun `entry became root after it was added to empty tree`() { @@ -26,7 +28,7 @@ class AVLTreeTest { assert(tree.size() == 1L) } - private fun makeSize1Tree() : AVLTreeForTest { + private fun makeSize1Tree(): AVLTreeForTest { return AVLTreeForTest(AVLVertex('b', '+'), 1L) // init tree by root and size (don't use put) } @@ -37,7 +39,7 @@ class AVLTreeTest { val root = tree.getRootT() assert((root?.rightSon?.key to root?.rightSon?.value) == ('c' to '+')) } - + @Test fun `entry with lesser key became left son after it was added to size 1 tree`() { val tree = makeSize1Tree() @@ -47,7 +49,7 @@ class AVLTreeTest { } @Test - fun `root's sonsHeightDiff decreased by 1 after entry with larger key was added to size 1 tree`(){ + fun `root's sonsHeightDiff decreased by 1 after entry with larger key was added to size 1 tree`() { val tree = makeSize1Tree() tree.put('c', '+') val root = tree.getRootT() @@ -55,7 +57,7 @@ class AVLTreeTest { } @Test - fun `root's sonsHeightDiff increased by 1 after entry with lesser key was added to size 1 tree`(){ + fun `root's sonsHeightDiff increased by 1 after entry with lesser key was added to size 1 tree`() { val tree = makeSize1Tree() tree.put('a', '-') val root = tree.getRootT() @@ -76,13 +78,13 @@ class AVLTreeTest { assert(tree.size() == 2L) } - private fun makeTreeForNeedNotBalanceingPutTest() : AVLTreeForTest { + private fun makeTreeForNeedNotBalanceingPutTest(): AVLTreeForTest { return AVLTreeForTest(AVLVertex(4, 'A', AVLVertex(1, 'I'), AVLVertex(5, 'S')), 3L) } - private fun isTreeConsistsOf(expectedContent : Set>, tree: AVLTreeForTest ) : Boolean { + private fun isTreeConsistsOf(expectedContent: Set>, tree: AVLTreeForTest): Boolean { val vertexes = tree.getVertexesInDFSOrder() - val pairsFromVertexes = (Array(vertexes.size){i -> (vertexes[i].key to vertexes[i].value)}).toSet() + val pairsFromVertexes = (Array(vertexes.size) { i -> (vertexes[i].key to vertexes[i].value) }).toSet() return pairsFromVertexes == expectedContent } @@ -100,14 +102,16 @@ class AVLTreeTest { assert(tree.size() == 4L) } - private fun isTreeSStructureThat(tree : AVLTreeForTest, - order : Array, deps : List>) : Boolean { + private fun isTreeSStructureThat( + tree: AVLTreeForTest, + order: Array, deps: List> + ): Boolean { // Tiple consists of indexes in order of (1)vertex, one's (2)leftSon and (3)RightSon val vertexes = tree.getVertexesInDFSOrder() if (vertexes.size != order.size) return false for (i in order.indices) - if (order[i] != vertexes[i].key) return false - for (dep in deps){ + if (order[i] != vertexes[i].key) return false + for (dep in deps) { if (dep.component2() != null) if (vertexes[dep.component1()].leftSon != vertexes[dep.component2() as Int]) return false @@ -126,22 +130,22 @@ class AVLTreeTest { assert(isTreeSStructureThat(tree, arrayOf(4, 1, 0, 5), expectedDependences)) } - private fun isSonsHeightDiffCorrect(tree : AVLTreeForTest) : Boolean { + private fun isSonsHeightDiffCorrect(tree: AVLTreeForTest): Boolean { val vertexes = tree.getVertexesInDFSOrder() val heights = tree.getHeights() if (vertexes.size != heights.size) return false for (vertex in vertexes) { - val expectedSonsHeightDiff = - when ((vertex.leftSon == null) to (vertex.rightSon == null)) { - true to true -> 0 - true to false -> -1 - (heights[(vertex.rightSon as AVLVertex).key] ?: return false) - false to true -> 1 + (heights[(vertex.leftSon as AVLVertex).key] ?: return false) - else -> { - val heightOfLeftSubtree = heights[(vertex.leftSon as AVLVertex).key] ?: return false - val heightOfRightSubtree = heights[(vertex.rightSon as AVLVertex).key] ?: return false - heightOfLeftSubtree - heightOfRightSubtree + val expectedSonsHeightDiff = + when ((vertex.leftSon == null) to (vertex.rightSon == null)) { + true to true -> 0 + true to false -> -1 - (heights[(vertex.rightSon as AVLVertex).key] ?: return false) + false to true -> 1 + (heights[(vertex.leftSon as AVLVertex).key] ?: return false) + else -> { + val heightOfLeftSubtree = heights[(vertex.leftSon as AVLVertex).key] ?: return false + val heightOfRightSubtree = heights[(vertex.rightSon as AVLVertex).key] ?: return false + heightOfLeftSubtree - heightOfRightSubtree + } } - } if (expectedSonsHeightDiff != vertex.sonsHeightDiff) return false } return true @@ -154,10 +158,10 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForHaveToRotateLeftPutTest() : AVLTreeForTest { + private fun makeTreeForHaveToRotateLeftPutTest(): AVLTreeForTest { val rightSonSRightSon = AVLVertex('h', 'H', AVLVertex('f', 'F'), AVLVertex('i', 'I')) - val rightSon = AVLVertex('e', 'E', AVLVertex('d','D'), rightSonSRightSon, -1) - val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) + val rightSon = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSonSRightSon, -1) + val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) return AVLTreeForTest(root, 8L) } @@ -165,8 +169,10 @@ class AVLTreeTest { fun `content is correct after entry was added (have to rotate left)`() { val tree = makeTreeForHaveToRotateLeftPutTest() tree.put('j', 'J') - val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', - 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') + val expectedContent = setOf( + 'a' to 'A', 'b' to 'B', 'c' to 'C', + 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J' + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -182,10 +188,12 @@ class AVLTreeTest { fun `structure is correct after added (have to rotate left)`() { val tree = makeTreeForHaveToRotateLeftPutTest() tree.put('j', 'J') - val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), - Triple(4, 5, 6), Triple(7, null, 8)) - val expectedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j' ) - assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) + val expectedDependences = listOf( + Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), + Triple(4, 5, 6), Triple(7, null, 8) + ) + val expectedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @Test @@ -195,10 +203,10 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForHaveToRotateRightPutTest() : AVLTreeForTest { + private fun makeTreeForHaveToRotateRightPutTest(): AVLTreeForTest { val leftSonSLeftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) - val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('e','E'), 1) - val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I', null, AVLVertex('j', 'J'), -1), 1) + val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('e', 'E'), 1) + val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I', null, AVLVertex('j', 'J'), -1), 1) return AVLTreeForTest(root, 8L) } @@ -206,8 +214,10 @@ class AVLTreeTest { fun `content is correct after entry was added (have to rotate right)`() { val tree = makeTreeForHaveToRotateRightPutTest() tree.put('a', 'A') - val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', - 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') + val expectedContent = setOf( + 'a' to 'A', 'b' to 'B', 'c' to 'C', + 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J' + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -222,8 +232,10 @@ class AVLTreeTest { fun `structure is correct after added (have to rotate right)`() { val tree = makeTreeForHaveToRotateRightPutTest() tree.put('a', 'A') - val expectedDependences = listOf(Triple(0, 1, 7), Triple(1, 2, 4), Triple(2, 3, null), - Triple(4, 5, 6), Triple(7, null, 8)) + val expectedDependences = listOf( + Triple(0, 1, 7), Triple(1, 2, 4), Triple(2, 3, null), + Triple(4, 5, 6), Triple(7, null, 8) + ) val expectedOrder = arrayOf('h', 'c', 'b', 'a', 'f', 'd', 'e', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -235,9 +247,9 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForHaveToChangeRootByRotateLeftPutTest() : AVLTreeForTest { + private fun makeTreeForHaveToChangeRootByRotateLeftPutTest(): AVLTreeForTest { val rightSon = AVLVertex('h', 'H', AVLVertex('f', 'F'), AVLVertex('i', 'I')) - val root = AVLVertex('e', 'E', AVLVertex('d','D'), rightSon, -1) + val root = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSon, -1) return AVLTreeForTest(root, 5L) } @@ -254,7 +266,7 @@ class AVLTreeTest { val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() tree.put('j', 'J') assert(tree.size() == 6L) - } + } @Test fun `structure is correct after added (rotateLeft changes root)`() { @@ -272,9 +284,9 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForHaveToChangeRootByRotateRightPutTest() : AVLTreeForTest { + private fun makeTreeForHaveToChangeRootByRotateRightPutTest(): AVLTreeForTest { val leftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) - val root = AVLVertex('f', 'F', leftSon, AVLVertex('e','E'), 1) + val root = AVLVertex('f', 'F', leftSon, AVLVertex('e', 'E'), 1) return AVLTreeForTest(root, 5L) } @@ -291,7 +303,7 @@ class AVLTreeTest { val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() tree.put('a', 'A') assert(tree.size() == 6L) - } + } @Test fun `structure is correct after added (rotateRight changes root)`() { @@ -309,10 +321,10 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForHaveToBigRotateLeftPutTest() : AVLTreeForTest { + private fun makeTreeForHaveToBigRotateLeftPutTest(): AVLTreeForTest { val rightSonSRightSon = AVLVertex('i', 'I', AVLVertex('g', 'G'), AVLVertex('j', 'J')) - val rightSon = AVLVertex('e', 'E', AVLVertex('d','D'), rightSonSRightSon, -1) - val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) + val rightSon = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSonSRightSon, -1) + val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) return AVLTreeForTest(root, 8L) } @@ -321,8 +333,10 @@ class AVLTreeTest { fun `content is correct after entry was added (have to big rotate left)(1)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('f', 'F') - val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', - 'd' to 'D', 'e' to 'E', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J') + val expectedContent = setOf( + 'a' to 'A', 'b' to 'B', 'c' to 'C', + 'd' to 'D', 'e' to 'E', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J' + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -330,8 +344,10 @@ class AVLTreeTest { fun `content is correct after entry was added (have to big rotate left)(2)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('h', 'H') - val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', - 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J') + val expectedContent = setOf( + 'a' to 'A', 'b' to 'B', 'c' to 'C', + 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J' + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -353,20 +369,26 @@ class AVLTreeTest { fun `structure is correct after added (have to big rotate left)(1)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('f', 'F') - val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), - Triple(4, 5, 6), Triple(7, null, 8)) + val expectedDependences = listOf( + Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), + Triple(4, 5, 6), Triple(7, null, 8) + ) val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'f', 'i', 'j') - assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } + @Test fun `structure is correct after added (have to big rotate left)(2)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('h', 'H') - val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 6), - Triple(4, 5, null), Triple(6, 7, 8)) + val expectedDependences = listOf( + Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 6), + Triple(4, 5, null), Triple(6, 7, 8) + ) val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'i', 'h', 'j') - assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } + @Test fun `vertexes' sonsHeightDiff are correct after added (have to big rotate left)(1)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() @@ -381,10 +403,10 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForHaveToBigRotateRightPutTest() : AVLTreeForTest { - val leftSonSLeftSon = AVLVertex('b', 'B', AVLVertex('a', 'A'), AVLVertex('d', 'D')) - val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('g','G'), 1) - val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I',null, AVLVertex('j', 'J'), -1), 1) + private fun makeTreeForHaveToBigRotateRightPutTest(): AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', 'B', AVLVertex('a', 'A'), AVLVertex('d', 'D')) + val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('g', 'G'), 1) + val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I', null, AVLVertex('j', 'J'), -1), 1) return AVLTreeForTest(root, 8L) } @@ -393,8 +415,10 @@ class AVLTreeTest { fun `content is correct after entry was added (have to big rotate right)(1)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('c', 'C') - val expectedContent = setOf('a' to 'A','b' to 'B', 'c' to 'C', - 'd' to 'D', 'h' to 'H', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J') + val expectedContent = setOf( + 'a' to 'A', 'b' to 'B', 'c' to 'C', + 'd' to 'D', 'h' to 'H', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J' + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -402,8 +426,10 @@ class AVLTreeTest { fun `content is correct after entry was added (have to big rotate right)(2)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('e', 'E') - val expectedContent = setOf('a' to 'A','b' to 'B', 'f' to 'F', - 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J') + val expectedContent = setOf( + 'a' to 'A', 'b' to 'B', 'f' to 'F', + 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J' + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -426,20 +452,24 @@ class AVLTreeTest { fun `structure is correct after added (have to big rotate right)(1)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('c', 'C') - val expectedDependences = listOf(Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 5), - Triple(5, null, 6), Triple(2, 3, 4)) + val expectedDependences = listOf( + Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 5), + Triple(5, null, 6), Triple(2, 3, 4) + ) val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'c', 'f', 'g', 'i', 'j') - assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @Test fun `structure is correct after added (have to big rotate right)(2)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('e', 'E') - val expectedDependences = listOf(Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 4), - Triple(2, 3, null), Triple(4, 5, 6)) + val expectedDependences = listOf( + Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 4), + Triple(2, 3, null), Triple(4, 5, 6) + ) val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'f', 'e', 'g', 'i', 'j') - assert(isTreeSStructureThat(tree,expectedOrder, expectedDependences)) + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @Test @@ -461,7 +491,7 @@ class AVLTreeTest { val tree = makeSize1Tree() tree.put('b', '-', false) assert(tree.size() == 1L) - assert(tree.getRootT()?.value == '+') + assert(tree.getRootT()?.value == '+') } @Test @@ -470,22 +500,22 @@ class AVLTreeTest { val expectedContent = setOf('a' to 'A', 'b' to 'B') assert(isTreeConsistsOf(expectedContent, tree)) } - + // remove test @Test - fun `delete from emptyTree returns null`(){ + fun `delete from emptyTree returns null`() { val tree = makeEmptyTree() assert(tree.remove(0) == null) } - @Test + @Test fun `tree is empty after deleted root of 'size 1' tree `() { val tree = makeSize1Tree() tree.remove('b') assert(tree.getVertexesInDFSOrder().isEmpty()) } - + @Test fun `size equals 0 after deleted root of 'size 1' tree`() { val tree = makeSize1Tree() @@ -493,7 +523,7 @@ class AVLTreeTest { assert(tree.size() == 0L) } - @Test + @Test fun `remove fun return null if entry's key isn't exists`() { val tree = makeSize1Tree() assert(tree.remove('a') == null) @@ -516,7 +546,7 @@ class AVLTreeTest { } - private fun makeTreeForRemoveLeafWithoutBalanceingTest() : AVLTreeForTest { + private fun makeTreeForRemoveLeafWithoutBalanceingTest(): AVLTreeForTest { return AVLTreeForTest(AVLVertex('r', "r", AVLVertex('n', "n"), AVLVertex('z', "z")), 3L) } @@ -551,7 +581,7 @@ class AVLTreeTest { } @Test - fun `vertex's sonsHeightDiff increased by 1 after deleted one's right leaf (needn't balanceing)`(){ + fun `vertex's sonsHeightDiff increased by 1 after deleted one's right leaf (needn't balanceing)`() { val tree = makeTreeForRemoveLeafWithoutBalanceingTest() tree.remove('z') val root = tree.getRootT() @@ -559,7 +589,7 @@ class AVLTreeTest { } @Test - fun `vertex's sonsHeightDiff decreased by 1 after deleted one's left son (needn't balanceing)`(){ + fun `vertex's sonsHeightDiff decreased by 1 after deleted one's left son (needn't balanceing)`() { val tree = makeTreeForRemoveLeafWithoutBalanceingTest() tree.remove('n') val root = tree.getRootT() @@ -579,8 +609,9 @@ class AVLTreeTest { tree.remove('n') assert(tree.size() == 2L) } - private fun makeTreeForRemoveLeftSonWithOnlyLeftSonTest() : AVLTreeForTest { - val leftSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) + + private fun makeTreeForRemoveLeftSonWithOnlyLeftSonTest(): AVLTreeForTest { + val leftSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) val root = AVLVertex('s', 5, leftSon, AVLVertex('z', 2), 1) return AVLTreeForTest(root, 4L) } @@ -589,14 +620,14 @@ class AVLTreeTest { fun `remove left son with only left son returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() assert(tree.remove('q') == 9) - } + } @Test fun `content is correct after removed left son with only left son (needn't balanceing)`() { val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() tree.remove('q') assert(isTreeConsistsOf(setOf('o' to 0, 's' to 5, 'z' to 2), tree)) - } + } @Test fun `size decreased by 1 after removed left son with only left son (needn't balanceing)`() { @@ -609,7 +640,7 @@ class AVLTreeTest { fun `structure is correct after removed left son with only leftt son (needn't balanceing)`() { val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() tree.remove('q') - assert(isTreeSStructureThat(tree ,arrayOf('s', 'o', 'z'), listOf(Triple(0, 1, 2 )))) + assert(isTreeSStructureThat(tree, arrayOf('s', 'o', 'z'), listOf(Triple(0, 1, 2)))) } @Test @@ -619,8 +650,8 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRemoveLeftSonWithOnlyRightSonTest() : AVLTreeForTest { - val leftSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) + private fun makeTreeForRemoveLeftSonWithOnlyRightSonTest(): AVLTreeForTest { + val leftSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) val root = AVLVertex('s', 5, leftSon, AVLVertex('z', 2), 1) return AVLTreeForTest(root, 4L) } @@ -629,14 +660,14 @@ class AVLTreeTest { fun `remove left son with only right son returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() assert(tree.remove('q') == 9) - } + } @Test fun `content is correct after removed left son with only right son (needn't balanceing)`() { val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() tree.remove('q') assert(isTreeConsistsOf(setOf('r' to 7, 's' to 5, 'z' to 2), tree)) - } + } @Test fun `size decreased by 1 after removed left son with only right son (needn't balanceing)`() { @@ -649,7 +680,7 @@ class AVLTreeTest { fun `structure is correct after removed left son with only right son (needn't balanceing)`() { val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() tree.remove('q') - assert(isTreeSStructureThat(tree ,arrayOf('s', 'r', 'z'), listOf(Triple(0, 1, 2 )))) + assert(isTreeSStructureThat(tree, arrayOf('s', 'r', 'z'), listOf(Triple(0, 1, 2)))) } @Test @@ -659,7 +690,7 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRemoveRightSonWithOnlyLeftSonTest() : AVLTreeForTest { + private fun makeTreeForRemoveRightSonWithOnlyLeftSonTest(): AVLTreeForTest { val rightSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) val root = AVLVertex('i', 1, AVLVertex('b', 6), rightSon, -1) return AVLTreeForTest(root, 4L) @@ -669,14 +700,14 @@ class AVLTreeTest { fun `remove right son with only left son returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() assert(tree.remove('q') == 9) - } + } @Test fun `content is correct after removed right son with only left son (needn't balanceing)`() { val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() tree.remove('q') assert(isTreeConsistsOf(setOf('o' to 0, 'b' to 6, 'i' to 1), tree)) - } + } @Test fun `size decreased by 1 after removed right son with only left son (needn't balanceing)`() { @@ -689,7 +720,7 @@ class AVLTreeTest { fun `structure is correct after removed right son with only left son (needn't balanceing)`() { val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() tree.remove('q') - assert(isTreeSStructureThat(tree ,arrayOf('i', 'b', 'o'), listOf(Triple(0, 1, 2 )))) + assert(isTreeSStructureThat(tree, arrayOf('i', 'b', 'o'), listOf(Triple(0, 1, 2)))) } @Test @@ -699,7 +730,7 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRemoveRightSonWithOnlyRightSonTest() : AVLTreeForTest { + private fun makeTreeForRemoveRightSonWithOnlyRightSonTest(): AVLTreeForTest { val rightSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) val root = AVLVertex('i', 1, AVLVertex('b', 6), rightSon, -1) return AVLTreeForTest(root, 4L) @@ -709,14 +740,14 @@ class AVLTreeTest { fun `remove right son with only right son returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() assert(tree.remove('q') == 9) - } + } @Test fun `content is correct after removed right son with only right son (needn't balanceing)`() { val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() tree.remove('q') assert(isTreeConsistsOf(setOf('r' to 7, 'b' to 6, 'i' to 1), tree)) - } + } @Test fun `size decreased by 1 after removed right son with only right son (needn't balanceing)`() { @@ -729,7 +760,7 @@ class AVLTreeTest { fun `structure is correct after removed right son with only right son (needn't balanceing)`() { val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() tree.remove('q') - assert(isTreeSStructureThat(tree ,arrayOf('i', 'b', 'r'), listOf(Triple(0, 1, 2 )))) + assert(isTreeSStructureThat(tree, arrayOf('i', 'b', 'r'), listOf(Triple(0, 1, 2)))) } @Test @@ -738,14 +769,16 @@ class AVLTreeTest { tree.remove('q') assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRemoveRootWithOnlyLeftSon() : AVLTreeForTest{ + + private fun makeTreeForRemoveRootWithOnlyLeftSon(): AVLTreeForTest { return AVLTreeForTest(AVLVertex("be", "es", (AVLVertex("and", "et")), null, 1), 2L) } + @Test fun `remove root with only left son returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveRootWithOnlyLeftSon() assert(tree.remove("be") == "es") - } + } @Test fun `content is correct after removed root with only left son (needn't balanceing)`() { @@ -761,14 +794,15 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRemoveRootWithOnlyRightSon() : AVLTreeForTest{ + private fun makeTreeForRemoveRootWithOnlyRightSon(): AVLTreeForTest { return AVLTreeForTest(AVLVertex("and", "et", null, (AVLVertex("be", "es")), -1), 2L) } + @Test fun `remove root with only right son returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveRootWithOnlyRightSon() assert(tree.remove("and") == "et") - } + } @Test fun `content is correct after removed root with only right son (needn't balanceing)`() { @@ -784,30 +818,32 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRemoveSonWithBothSons() : AVLTreeForTest { + private fun makeTreeForRemoveSonWithBothSons(): AVLTreeForTest { val eVrt = AVLVertex('e', 'E', AVLVertex('c', 'C'), null, 1) val bVrt = AVLVertex('b', 'B', AVLVertex('a', 'A'), eVrt, -1) - val leftSon = AVLVertex('f', 'F', bVrt, AVLVertex('i', 'I', null, AVLVertex('k', 'K'), -1), 1) + val leftSon = AVLVertex('f', 'F', bVrt, AVLVertex('i', 'I', null, AVLVertex('k', 'K'), -1), 1) val qVrt = AVLVertex('q', 'Q', null, AVLVertex('s', 'S'), -1) val wVrt = AVLVertex('w', 'W', null, AVLVertex('z', 'Z'), -1) val root = AVLVertex('n', 'N', leftSon, AVLVertex('u', 'U', qVrt, wVrt, 0), 1) return AVLTreeForTest(root, 13L) } - + @Test fun `remove left son with both sons returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() assert(tree.remove('f') == 'F') - } + } @Test fun `content is correct after removed left son with both sons (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('f') - val expectedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'e' to 'E','i' to 'I', - 'z' to 'Z', 'k' to 'K', 'n' to 'N', 'u' to 'U', 'q' to 'Q', 's' to 'S', 'w' to 'W') + val expectedContent = setOf( + 'a' to 'A', 'b' to 'B', 'c' to 'C', 'e' to 'E', 'i' to 'I', + 'z' to 'Z', 'k' to 'K', 'n' to 'N', 'u' to 'U', 'q' to 'Q', 's' to 'S', 'w' to 'W' + ) assert(isTreeConsistsOf(expectedContent, tree)) - } + } @Test fun `size decreased by 1 after removed left son with both sons (needn't balanceing)`() { @@ -820,9 +856,11 @@ class AVLTreeTest { fun `structure is correct after removed left son with both sons (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('f') - val expectedDependences = listOf(Triple(0, 1, 7), Triple(1, 2, 5), Triple(2, 3, 4), - Triple (5, null, 6), Triple(7, 8, 10), Triple(10, null, 11)) - val expectedOrder = arrayOf('n', 'e', 'b', 'a', 'c', 'i', 'k', 'u', 'q', 's', 'w','z') + val expectedDependences = listOf( + Triple(0, 1, 7), Triple(1, 2, 5), Triple(2, 3, 4), + Triple(5, null, 6), Triple(7, 8, 10), Triple(10, null, 11) + ) + val expectedOrder = arrayOf('n', 'e', 'b', 'a', 'c', 'i', 'k', 'u', 'q', 's', 'w', 'z') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -837,16 +875,18 @@ class AVLTreeTest { fun `remove right son with both sons returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() assert(tree.remove('u') == 'U') - } + } @Test fun `content is correct after removed right son with both sons (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('u') - val expectedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'e' to 'E', 'i' to 'I', - 'z' to 'Z', 'k' to 'K', 'n' to 'N', 'f' to 'F', 'q' to 'Q', 's' to 'S', 'w' to 'W') + val expectedContent = setOf( + 'a' to 'A', 'b' to 'B', 'c' to 'C', 'e' to 'E', 'i' to 'I', + 'z' to 'Z', 'k' to 'K', 'n' to 'N', 'f' to 'F', 'q' to 'Q', 's' to 'S', 'w' to 'W' + ) assert(isTreeConsistsOf(expectedContent, tree)) - } + } @Test fun `size decreased by 1 after removed right son with both sons (needn't balanceing)`() { @@ -859,8 +899,10 @@ class AVLTreeTest { fun `structure is correct after removed right son with both sons (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('u') - val expectedDependences = listOf(Triple(0, 1, 8), Triple(1, 2, 6), Triple(2, 3, 4), - Triple (6, null, 7), Triple(4, 5, null), Triple(8, 9, 10), Triple(10, null, 11)) + val expectedDependences = listOf( + Triple(0, 1, 8), Triple(1, 2, 6), Triple(2, 3, 4), + Triple(6, null, 7), Triple(4, 5, null), Triple(8, 9, 10), Triple(10, null, 11) + ) val expectedOrder = arrayOf('n', 'f', 'b', 'a', 'e', 'c', 'i', 'k', 's', 'q', 'w', 'z') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -871,7 +913,8 @@ class AVLTreeTest { tree.remove('u') assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRemoveRootWithBothSonsTest() : AVLTreeForTest { + + private fun makeTreeForRemoveRootWithBothSonsTest(): AVLTreeForTest { val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), AVLVertex('e', 5), 0) val rightSon = AVLVertex('i', 9, null, AVLVertex('k', 11), -1) val root = AVLVertex('f', 6, leftSon, rightSon, 0) @@ -882,7 +925,7 @@ class AVLTreeTest { fun `remove root with both sons returns due value (needn't balanceing)`() { val tree = makeTreeForRemoveRootWithBothSonsTest() assert(tree.remove('f') == 6) - } + } @Test fun `content is correct after removed root with both sons (needn't balanceing)`() { @@ -914,21 +957,22 @@ class AVLTreeTest { tree.remove('f') assert(isSonsHeightDiffCorrect(tree)) } - - private fun makeTreeForRemoveWithLeftRotate1Test() : AVLTreeForTest { + + private fun makeTreeForRemoveWithLeftRotate1Test(): AVLTreeForTest { val rightSonSRightSon = AVLVertex('o', false, null, AVLVertex('p', true), -1) val rightSon = AVLVertex('m', true, AVLVertex('l', true), rightSonSRightSon, -1) val root = AVLVertex('k', true, AVLVertex('i', false, AVLVertex('a', false), null, 1), rightSon, -1) return AVLTreeForTest(root, 7L) } - private fun makeTreeForRemoveWithLeftRotate2Test() : AVLTreeForTest { + private fun makeTreeForRemoveWithLeftRotate2Test(): AVLTreeForTest { val rightSonSRightSon = AVLVertex('o', false, AVLVertex('n', true), AVLVertex('p', true), 0) val rightSon = AVLVertex('m', true, AVLVertex('l', true), rightSonSRightSon, -1) val root = AVLVertex('k', true, AVLVertex('i', false, AVLVertex('a', false), null, 1), rightSon, -1) return AVLTreeForTest(root, 8L) } - // new subroot initially had sonSHeightDiff == -1 in (1) and 0 in (2) + + // new subroot initially had sonSHeightDiff == -1 in (1) and 0 in (2) @Test fun `returns due value after removed and rotated left(1)`() { val tree = makeTreeForRemoveWithLeftRotate1Test() @@ -945,8 +989,10 @@ class AVLTreeTest { fun `content is correct after removed and rotated left (1)`() { val tree = makeTreeForRemoveWithLeftRotate1Test() tree.remove('l') - val expectedContent = setOf('k' to true, 'i' to false, 'm' to true, - 'o' to false, 'p' to true, 'a' to false) + val expectedContent = setOf( + 'k' to true, 'i' to false, 'm' to true, + 'o' to false, 'p' to true, 'a' to false + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -954,8 +1000,10 @@ class AVLTreeTest { fun `content is correct after removed and rotated left (2)`() { val tree = makeTreeForRemoveWithLeftRotate2Test() tree.remove('l') - val expectedContent = setOf('k' to true, 'i' to false, 'm' to true, - 'o' to false, 'p' to true, 'n' to true, 'a' to false) + val expectedContent = setOf( + 'k' to true, 'i' to false, 'm' to true, + 'o' to false, 'p' to true, 'n' to true, 'a' to false + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -986,8 +1034,10 @@ class AVLTreeTest { fun `structure is correct after removed and rotated left (2)`() { val tree = makeTreeForRemoveWithLeftRotate2Test() tree.remove('l') - val expectedDependences = listOf(Triple(0, 1, 3), Triple(3, 4, 6), - Triple(4, null, 5), Triple(1, 2, null)) + val expectedDependences = listOf( + Triple(0, 1, 3), Triple(3, 4, 6), + Triple(4, null, 5), Triple(1, 2, null) + ) val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'n', 'p') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -1005,23 +1055,23 @@ class AVLTreeTest { tree.remove('l') assert(isSonsHeightDiffCorrect(tree)) } - - private fun makeTreeForRemoveWithRightRotate1Test() : AVLTreeForTest { - val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), null, 1) + + private fun makeTreeForRemoveWithRightRotate1Test(): AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), null, 1) val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) val root = AVLVertex('k', true, leftSon, AVLVertex('m', true, null, AVLVertex('o', false), -1), 1) return AVLTreeForTest(root, 7L) } - - private fun makeTreeForRemoveWithRightRotate2Test() : AVLTreeForTest { - val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), AVLVertex('c', true), 0) + + private fun makeTreeForRemoveWithRightRotate2Test(): AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), AVLVertex('c', true), 0) val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) val root = AVLVertex('k', true, leftSon, AVLVertex('m', true, null, AVLVertex('o', false), -1), 1) return AVLTreeForTest(root, 8L) } - // new subroot initially had sonSHeightDiff == 1 in (1) and 0 in (2) + // new subroot initially had sonSHeightDiff == 1 in (1) and 0 in (2) @Test fun `returns due value after removed and rotated right(1)`() { val tree = makeTreeForRemoveWithRightRotate1Test() @@ -1038,8 +1088,10 @@ class AVLTreeTest { fun `content is correct after removed and rotated right (1)`() { val tree = makeTreeForRemoveWithRightRotate1Test() tree.remove('e') - val expectedContent = setOf('k' to true, 'b' to true, 'm' to true, - 'o' to false, 'd' to true, 'a' to false) + val expectedContent = setOf( + 'k' to true, 'b' to true, 'm' to true, + 'o' to false, 'd' to true, 'a' to false + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -1047,8 +1099,10 @@ class AVLTreeTest { fun `content is correct after removed and rotated right (2)`() { val tree = makeTreeForRemoveWithRightRotate2Test() tree.remove('e') - val expectedContent = setOf('k' to true, 'b' to true, 'm' to true, - 'o' to false, 'd' to true, 'a' to false, 'c' to true) + val expectedContent = setOf( + 'k' to true, 'b' to true, 'm' to true, + 'o' to false, 'd' to true, 'a' to false, 'c' to true + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -1079,8 +1133,10 @@ class AVLTreeTest { fun `structure is correct after removed and rotated right (2)`() { val tree = makeTreeForRemoveWithRightRotate2Test() tree.remove('e') - val expectedDependences = listOf(Triple(0, 1, 5), Triple(1, 2, 3), - Triple(5, null, 6), Triple(3, 4, null)) + val expectedDependences = listOf( + Triple(0, 1, 5), Triple(1, 2, 3), + Triple(5, null, 6), Triple(3, 4, null) + ) val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'c', 'm', 'o') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -1099,9 +1155,9 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRotateLeftChangesRootRemoveTest() : AVLTreeForTest { + private fun makeTreeForRotateLeftChangesRootRemoveTest(): AVLTreeForTest { val root = AVLVertex(1, 1, AVLVertex(0, 0), AVLVertex(3, 3, AVLVertex(2, 2), AVLVertex(5, 5)), -1) - return AVLTreeForTest(root, 5L) + return AVLTreeForTest(root, 5L) } @Test @@ -1141,9 +1197,9 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForRotateRightChangesRootRemoveTest() : AVLTreeForTest { + private fun makeTreeForRotateRightChangesRootRemoveTest(): AVLTreeForTest { val root = AVLVertex(-1, 1, AVLVertex(-3, 3, AVLVertex(-5, 5), AVLVertex(-2, 2)), AVLVertex(0, 0), 1) - return AVLTreeForTest(root, 5L) + return AVLTreeForTest(root, 5L) } @Test @@ -1182,7 +1238,8 @@ class AVLTreeTest { tree.remove(0) assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForBigRotateLeftChangesRootRemoveTest() : AVLTreeForTest { + + private fun makeTreeForBigRotateLeftChangesRootRemoveTest(): AVLTreeForTest { val rightSonSLeftSon = AVLVertex('d', 'D', AVLVertex('c', 'C'), AVLVertex('e', 'E')) val rightSon = AVLVertex('f', 'F', rightSonSLeftSon, AVLVertex('g', 'G'), 1) val root = AVLVertex('b', 'B', AVLVertex('a', 'A', AVLVertex(' ', ' '), null, 1), rightSon, -1) @@ -1199,8 +1256,10 @@ class AVLTreeTest { fun `content is correct after removed (bigRotateLeft changed root)`() { val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() tree.remove(' ') - val expectedContent = setOf('d' to 'D', 'c' to 'C', 'e' to 'E','f' to 'F', - 'g' to 'G', 'b' to 'B', 'a' to 'A') + val expectedContent = setOf( + 'd' to 'D', 'c' to 'C', 'e' to 'E', 'f' to 'F', + 'g' to 'G', 'b' to 'B', 'a' to 'A' + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -1227,9 +1286,9 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } - private fun makeTreeForBigRotateRightChangesRootRemoveTest() : AVLTreeForTest { + private fun makeTreeForBigRotateRightChangesRootRemoveTest(): AVLTreeForTest { val leftSonSRightSon = AVLVertex('e', 5, AVLVertex('c', 3), AVLVertex('d', 4)) - val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), leftSonSRightSon, -1) + val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), leftSonSRightSon, -1) val root = AVLVertex('f', 8, leftSon, AVLVertex('i', 9, null, AVLVertex('k', 10), -1), 1) return AVLTreeForTest(root, 8L) } @@ -1244,8 +1303,10 @@ class AVLTreeTest { fun `content is correct after removed (bigRotateRight changed root)`() { val tree = makeTreeForBigRotateRightChangesRootRemoveTest() tree.remove('k') - val expectedContent = setOf('a' to 1, 'b' to 2, 'c' to 3, 'd' to 4, 'e' to 5, - 'i' to 9, 'f' to 8) + val expectedContent = setOf( + 'a' to 1, 'b' to 2, 'c' to 3, 'd' to 4, 'e' to 5, + 'i' to 9, 'f' to 8 + ) assert(isTreeConsistsOf(expectedContent, tree)) } diff --git a/lib/src/test/kotlin/TestIterator.kt b/lib/src/test/kotlin/TestIterator.kt index 18727a6..0d4cde0 100644 --- a/lib/src/test/kotlin/TestIterator.kt +++ b/lib/src/test/kotlin/TestIterator.kt @@ -2,6 +2,8 @@ import main.vertexes.InterfaceBSTVertex import main.iterator.TreeIterator import java.util.LinkedList -internal class TestIterator>(vertex: N?) : TreeIterator(vertex) { - fun getTreeStack(): LinkedList {return stack} +internal class TestIterator>(vertex: N?) : TreeIterator(vertex) { + fun getTreeStack(): LinkedList { + return stack + } } \ No newline at end of file From 5b6bab2a5683c6e6f704a560e9b637d22102a357 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 11:56:39 +0300 Subject: [PATCH 162/227] style: more changes according to linter --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 7 ++++--- lib/src/test/kotlin/AVLTreeForTest.kt | 11 +++++------ lib/src/test/kotlin/AVLTreeTest.kt | 7 +------ .../kotlin/{TreeIteratorTests.kt => IteratorTests.kt} | 0 lib/src/test/kotlin/TestIterator.kt | 2 +- 5 files changed, 11 insertions(+), 16 deletions(-) rename lib/src/test/kotlin/{TreeIteratorTests.kt => IteratorTests.kt} (100%) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 1e0cda1..22c45ae 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -17,8 +17,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } private fun putRec( - key: K, value: V, - replaceIfExists: Boolean, vertex: AVLVertex + key: K, + value: V, + replaceIfExists: Boolean, + vertex: AVLVertex ): AVLVertex? { fun putRecShort(vrtx: AVLVertex): AVLVertex? { return putRec(key, value, replaceIfExists, vrtx) @@ -204,7 +206,6 @@ open class AVLSearchTree : AbstractBinarySearchTree> else vertex.rightSon = nextCallReturned.component2() return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) } - } } diff --git a/lib/src/test/kotlin/AVLTreeForTest.kt b/lib/src/test/kotlin/AVLTreeForTest.kt index 8a27826..297dcc9 100644 --- a/lib/src/test/kotlin/AVLTreeForTest.kt +++ b/lib/src/test/kotlin/AVLTreeForTest.kt @@ -1,8 +1,8 @@ -import main.vertexes.AVLVertex -import main.trees.AVLSearchTree -import kotlin.math.max import kotlin.collections.mutableListOf import kotlin.collections.mutableMapOf +import kotlin.math.max +import main.vertexes.AVLVertex +import main.trees.AVLSearchTree class AVLTreeForTest : AVLSearchTree { @@ -59,8 +59,7 @@ class AVLTreeForTest : AVLSearchTree { } } - constructor (root: AVLVertex, size: Long, comparator: Comparator? = null) : - super(comparator) { + constructor (root: AVLVertex, size: Long, comparator: Comparator? = null) : super(comparator) { this.root = root this.size = size } @@ -71,4 +70,4 @@ class AVLTreeForTest : AVLSearchTree { map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null ) : super(map, replaceIfExists, comparator) -} \ No newline at end of file +} diff --git a/lib/src/test/kotlin/AVLTreeTest.kt b/lib/src/test/kotlin/AVLTreeTest.kt index 25e7243..da7dcd4 100644 --- a/lib/src/test/kotlin/AVLTreeTest.kt +++ b/lib/src/test/kotlin/AVLTreeTest.kt @@ -1,9 +1,9 @@ import AVLTreeForTest +import kotlin.collections.hashMapOf import main.vertexes.AVLVertex import org.junit.jupiter.api.Test import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.condition.DisabledIf -import kotlin.collections.hashMapOf class AVLTreeTest { @@ -176,7 +176,6 @@ class AVLTreeTest { assert(isTreeConsistsOf(expectedContent, tree)) } - @Test fun `size increased by 1 after added (have to rotate left)`() { val tree = makeTreeForHaveToRotateLeftPutTest() @@ -447,7 +446,6 @@ class AVLTreeTest { assert(tree.size() == 9L) } - @Test fun `structure is correct after added (have to big rotate right)(1)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() @@ -545,7 +543,6 @@ class AVLTreeTest { assert(tree.getRootT()?.value == '+') } - private fun makeTreeForRemoveLeafWithoutBalanceingTest(): AVLTreeForTest { return AVLTreeForTest(AVLVertex('r', "r", AVLVertex('n', "n"), AVLVertex('z', "z")), 3L) } @@ -1063,7 +1060,6 @@ class AVLTreeTest { return AVLTreeForTest(root, 7L) } - private fun makeTreeForRemoveWithRightRotate2Test(): AVLTreeForTest { val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), AVLVertex('c', true), 0) val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) @@ -1333,4 +1329,3 @@ class AVLTreeTest { assert(isSonsHeightDiffCorrect(tree)) } } - diff --git a/lib/src/test/kotlin/TreeIteratorTests.kt b/lib/src/test/kotlin/IteratorTests.kt similarity index 100% rename from lib/src/test/kotlin/TreeIteratorTests.kt rename to lib/src/test/kotlin/IteratorTests.kt diff --git a/lib/src/test/kotlin/TestIterator.kt b/lib/src/test/kotlin/TestIterator.kt index 0d4cde0..8929f04 100644 --- a/lib/src/test/kotlin/TestIterator.kt +++ b/lib/src/test/kotlin/TestIterator.kt @@ -6,4 +6,4 @@ internal class TestIterator>(vertex: N?) : fun getTreeStack(): LinkedList { return stack } -} \ No newline at end of file +} From aae2ece85abefbd11f24745d06c24112ce683f48 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 12:12:24 +0300 Subject: [PATCH 163/227] style: delete extra imports, add cosmetic changes --- lib/src/test/kotlin/AVLTreeForTest.kt | 3 ++- lib/src/test/kotlin/AVLTreeTest.kt | 2 -- lib/src/test/kotlin/IteratorTests.kt | 2 +- lib/src/test/kotlin/TestIterator.kt | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/src/test/kotlin/AVLTreeForTest.kt b/lib/src/test/kotlin/AVLTreeForTest.kt index 297dcc9..1149480 100644 --- a/lib/src/test/kotlin/AVLTreeForTest.kt +++ b/lib/src/test/kotlin/AVLTreeForTest.kt @@ -67,7 +67,8 @@ class AVLTreeForTest : AVLSearchTree { constructor (comparator: Comparator? = null) : super(comparator) constructor( - map: Map, replaceIfExists: Boolean = true, + map: Map, + replaceIfExists: Boolean = true, comparator: Comparator? = null ) : super(map, replaceIfExists, comparator) } diff --git a/lib/src/test/kotlin/AVLTreeTest.kt b/lib/src/test/kotlin/AVLTreeTest.kt index da7dcd4..af59045 100644 --- a/lib/src/test/kotlin/AVLTreeTest.kt +++ b/lib/src/test/kotlin/AVLTreeTest.kt @@ -2,8 +2,6 @@ import AVLTreeForTest import kotlin.collections.hashMapOf import main.vertexes.AVLVertex import org.junit.jupiter.api.Test -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.condition.DisabledIf class AVLTreeTest { diff --git a/lib/src/test/kotlin/IteratorTests.kt b/lib/src/test/kotlin/IteratorTests.kt index 174d0d5..f740ad2 100644 --- a/lib/src/test/kotlin/IteratorTests.kt +++ b/lib/src/test/kotlin/IteratorTests.kt @@ -44,4 +44,4 @@ class IteratorTests { } assertEquals(mutableListOf(Pair(2, "two"), Pair(3, "three"), Pair(150, "one-five-zero"), Pair(1, "one")), list) } -} \ No newline at end of file +} diff --git a/lib/src/test/kotlin/TestIterator.kt b/lib/src/test/kotlin/TestIterator.kt index 8929f04..87f2868 100644 --- a/lib/src/test/kotlin/TestIterator.kt +++ b/lib/src/test/kotlin/TestIterator.kt @@ -1,6 +1,6 @@ +import java.util.LinkedList import main.vertexes.InterfaceBSTVertex import main.iterator.TreeIterator -import java.util.LinkedList internal class TestIterator>(vertex: N?) : TreeIterator(vertex) { fun getTreeStack(): LinkedList { From 4d4420b2c5aa61f22d09d26c1cc84ab31a4ddcc7 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 12:21:20 +0300 Subject: [PATCH 164/227] style: final changes according to linter --- lib/src/test/kotlin/AVLTreeForTest.kt | 2 +- lib/src/test/kotlin/AVLTreeTest.kt | 4 ++-- lib/src/test/kotlin/TestIterator.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/test/kotlin/AVLTreeForTest.kt b/lib/src/test/kotlin/AVLTreeForTest.kt index 1149480..67e626e 100644 --- a/lib/src/test/kotlin/AVLTreeForTest.kt +++ b/lib/src/test/kotlin/AVLTreeForTest.kt @@ -1,8 +1,8 @@ import kotlin.collections.mutableListOf import kotlin.collections.mutableMapOf import kotlin.math.max -import main.vertexes.AVLVertex import main.trees.AVLSearchTree +import main.vertexes.AVLVertex class AVLTreeForTest : AVLSearchTree { diff --git a/lib/src/test/kotlin/AVLTreeTest.kt b/lib/src/test/kotlin/AVLTreeTest.kt index af59045..5cba069 100644 --- a/lib/src/test/kotlin/AVLTreeTest.kt +++ b/lib/src/test/kotlin/AVLTreeTest.kt @@ -1,4 +1,3 @@ -import AVLTreeForTest import kotlin.collections.hashMapOf import main.vertexes.AVLVertex import org.junit.jupiter.api.Test @@ -102,7 +101,8 @@ class AVLTreeTest { private fun isTreeSStructureThat( tree: AVLTreeForTest, - order: Array, deps: List> + order: Array, + deps: List> ): Boolean { // Tiple consists of indexes in order of (1)vertex, one's (2)leftSon and (3)RightSon val vertexes = tree.getVertexesInDFSOrder() diff --git a/lib/src/test/kotlin/TestIterator.kt b/lib/src/test/kotlin/TestIterator.kt index 87f2868..6f02efe 100644 --- a/lib/src/test/kotlin/TestIterator.kt +++ b/lib/src/test/kotlin/TestIterator.kt @@ -1,6 +1,6 @@ import java.util.LinkedList -import main.vertexes.InterfaceBSTVertex import main.iterator.TreeIterator +import main.vertexes.InterfaceBSTVertex internal class TestIterator>(vertex: N?) : TreeIterator(vertex) { fun getTreeStack(): LinkedList { From c51a4e4720e3dde672585897db7cc583f569d41b Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 12:41:30 +0300 Subject: [PATCH 165/227] style: imports in lexicographic order --- lib/build.gradle.kts | 2 - lib/src/main/kotlin/iterator/TreeIterator.kt | 2 +- lib/src/main/kotlin/trees/AVLSearchTree.kt | 117 ++++-- .../kotlin/trees/AbstractBinarySearchTree.kt | 46 ++- lib/src/main/kotlin/trees/RBSearchTree.kt | 41 +- .../kotlin/trees/SimpleBinarySearchTree.kt | 29 +- lib/src/main/kotlin/vertexes/AVLVertex.kt | 5 +- lib/src/main/kotlin/vertexes/RBVertex.kt | 10 +- .../main/kotlin/vertexes/SimpleBSTVertex.kt | 8 +- lib/src/test/kotlin/AVLTreeForTest.kt | 17 +- lib/src/test/kotlin/AVLTreeTest.kt | 373 +++++++++++++----- lib/src/test/kotlin/IteratorTests.kt | 1 - lib/src/test/kotlin/SimpleBSTTests.kt | 56 +-- lib/src/test/kotlin/TestIterator.kt | 2 +- lib/src/test/kotlin/TestSimpleBST.kt | 2 +- lib/src/test/kotlin/trees/RBSearchTreeTest.kt | 111 ++++-- 16 files changed, 562 insertions(+), 260 deletions(-) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 61c261d..dcb7919 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -53,5 +53,3 @@ tasks.named("jacocoTestReport") { html.outputLocation = layout.buildDirectory.dir("jacocoHtml") } } - - diff --git a/lib/src/main/kotlin/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt index 036c139..c23db46 100644 --- a/lib/src/main/kotlin/iterator/TreeIterator.kt +++ b/lib/src/main/kotlin/iterator/TreeIterator.kt @@ -4,7 +4,7 @@ import main.vertexes.InterfaceBSTVertex import java.util.LinkedList open class TreeIterator>( - vertex: N? + vertex: N?, ) : Iterator> { protected val stack = LinkedList() diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 22c45ae..7bbc2ca 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -3,8 +3,11 @@ package main.trees import main.vertexes.AVLVertex open class AVLSearchTree : AbstractBinarySearchTree> { - - override fun put(key: K, value: V, replaceIfExists: Boolean) { + override fun put( + key: K, + value: V, + replaceIfExists: Boolean, + ) { if (!isEmpty()) { when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { null, root -> {} @@ -20,7 +23,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> key: K, value: V, replaceIfExists: Boolean, - vertex: AVLVertex + vertex: AVLVertex, ): AVLVertex? { fun putRecShort(vrtx: AVLVertex): AVLVertex? { return putRec(key, value, replaceIfExists, vrtx) @@ -57,6 +60,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> } } if (nextCallReturned == null) return null + fun doBalanceChoreWhenLeftSubTreeChanged(): AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null if (vertex.sonsHeightDiff + 1 == 2) return balance(vertex) @@ -90,8 +94,9 @@ open class AVLSearchTree : AbstractBinarySearchTree> when (removeRecReturned.first) { RemovalStage.A -> {} RemovalStage.B -> { - if (removeRecReturned.component2() != root) + if (removeRecReturned.component2() != root) { root = removeRecReturned.component2() + } } RemovalStage.C -> root = null @@ -108,7 +113,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> // C - need to null due "Son" property of (if exists) the parent of removed vertex + b // D - need only to change due "Son" property of (if exists) the parent - private fun removeRec(key: K, vertex: AVLVertex): Triple, V?> { + private fun removeRec( + key: K, + vertex: AVLVertex, + ): Triple, V?> { val nextCallReturned: Triple?, V?> // Triple consists of: // 1) removal stage @@ -144,48 +152,56 @@ open class AVLSearchTree : AbstractBinarySearchTree> Triple(RemovalStage.B, vertex.leftSon as AVLVertex, vertex.value) } - else -> Triple( - RemovalStage.D, - prepareLargestLowerToReplaceVertex(vertex), vertex.value - ) + else -> + Triple( + RemovalStage.D, + prepareLargestLowerToReplaceVertex(vertex), + vertex.value, + ) } } } + fun doBalanceChoreWhenLeftSubTreeChanged(): Triple, V?> { - if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) + if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) { return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff - 1 == -2) + } + if (vertex.sonsHeightDiff - 1 == -2) { return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) + } vertex.sonsHeightDiff-- return Triple(RemovalStage.B, vertex, nextCallReturned.third) } fun doBalanceChoreWhenRightSubTreeChanged(): Triple, V?> { - if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) + if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) { return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - if (vertex.sonsHeightDiff + 1 == 2) + } + if (vertex.sonsHeightDiff + 1 == 2) { return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) + } vertex.sonsHeightDiff++ return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) } when (nextCallReturned.component1()) { RemovalStage.A -> return nextCallReturned - RemovalStage.B -> when (nextCallReturned.component2()) { - vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() - vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() - else -> - when (compareKeys(nextCallReturned.component2().key, vertex.key)) { - -1 -> { - vertex.leftSon = nextCallReturned.component2() - return doBalanceChoreWhenLeftSubTreeChanged() - } + RemovalStage.B -> + when (nextCallReturned.component2()) { + vertex.leftSon -> return doBalanceChoreWhenLeftSubTreeChanged() + vertex.rightSon -> return doBalanceChoreWhenRightSubTreeChanged() + else -> + when (compareKeys(nextCallReturned.component2().key, vertex.key)) { + -1 -> { + vertex.leftSon = nextCallReturned.component2() + return doBalanceChoreWhenLeftSubTreeChanged() + } - else -> { - vertex.rightSon = nextCallReturned.component2() - return doBalanceChoreWhenRightSubTreeChanged() + else -> { + vertex.rightSon = nextCallReturned.component2() + return doBalanceChoreWhenRightSubTreeChanged() + } } - } - } + } RemovalStage.C -> when (compareKeys(nextCallReturned.component2().key, vertex.key)) { @@ -201,9 +217,11 @@ open class AVLSearchTree : AbstractBinarySearchTree> } RemovalStage.D -> { - if (compareKeys(nextCallReturned.component2().key, vertex.key) == -1) + if (compareKeys(nextCallReturned.component2().key, vertex.key) == -1) { vertex.leftSon = nextCallReturned.component2() - else vertex.rightSon = nextCallReturned.component2() + } else { + vertex.rightSon = nextCallReturned.component2() + } return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) } } @@ -220,6 +238,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> private fun balance(curVertex: AVLVertex): AVLVertex { var (rightSon, leftSon) = List?>(2) { null } + fun setTwoSonHeightDiffs(values: Pair) { curVertex.sonsHeightDiff = values.component1() if (rightSon != null) { @@ -239,15 +258,18 @@ open class AVLSearchTree : AbstractBinarySearchTree> 1 -> 0 to -1 -1 -> 1 to 0 else -> 0 to 0 - } + }, ) rightSonSLeftSon.sonsHeightDiff = 0 subtreeRoot } else { val subtreeRoot = rotateLeft(curVertex, rightSon) setTwoSonHeightDiffs( - if (rightSon.sonsHeightDiff == 0) -1 to 1 - else 0 to 0 + if (rightSon.sonsHeightDiff == 0) { + -1 to 1 + } else { + 0 to 0 + }, ) subtreeRoot } @@ -261,39 +283,54 @@ open class AVLSearchTree : AbstractBinarySearchTree> -1 -> 0 to 1 1 -> -1 to 0 else -> 0 to 0 - } + }, ) leftSonSRightSon.sonsHeightDiff = 0 subtreeRoot } else { val subtreeRoot = rotateRight(curVertex, leftSon) setTwoSonHeightDiffs( - if (leftSon.sonsHeightDiff == 0) 1 to -1 - else 0 to 0 + if (leftSon.sonsHeightDiff == 0) { + 1 to -1 + } else { + 0 to 0 + }, ) subtreeRoot } } - private fun rotateLeft(curVertex: AVLVertex, rightSon: AVLVertex): AVLVertex { + private fun rotateLeft( + curVertex: AVLVertex, + rightSon: AVLVertex, + ): AVLVertex { curVertex.rightSon = rightSon.leftSon rightSon.leftSon = curVertex return rightSon } - private fun rotateRight(curVertex: AVLVertex, leftSon: AVLVertex): AVLVertex { + private fun rotateRight( + curVertex: AVLVertex, + leftSon: AVLVertex, + ): AVLVertex { curVertex.leftSon = leftSon.rightSon leftSon.rightSon = curVertex return leftSon } - private fun bigRotateLeft(curVertex: AVLVertex, rightSon: AVLVertex): AVLVertex { + private fun bigRotateLeft( + curVertex: AVLVertex, + rightSon: AVLVertex, + ): AVLVertex { val curRightSon = rotateRight(rightSon, rightSon.leftSon as AVLVertex) curVertex.rightSon = curRightSon return rotateLeft(curVertex, curRightSon) } - private fun bigRotateRight(curVertex: AVLVertex, leftSon: AVLVertex): AVLVertex { + private fun bigRotateRight( + curVertex: AVLVertex, + leftSon: AVLVertex, + ): AVLVertex { val curLeftSon = rotateLeft(leftSon, leftSon.rightSon as AVLVertex) curVertex.leftSon = curLeftSon return rotateRight(curVertex, curLeftSon) @@ -304,6 +341,6 @@ open class AVLSearchTree : AbstractBinarySearchTree> constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( map, replaceIfExists, - comparator + comparator, ) } diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index ff62554..fc4b47d 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -4,7 +4,6 @@ import main.iterator.TreeIterator import main.vertexes.InterfaceBSTVertex abstract class AbstractBinarySearchTree> { - protected var comparator: Comparator? = null protected var size: Long = 0L protected var root: N? = null @@ -50,9 +49,16 @@ abstract class AbstractBinarySearchTree> { return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) } - abstract fun put(key: K, value: V, replaceIfExists: Boolean = true) + abstract fun put( + key: K, + value: V, + replaceIfExists: Boolean = true, + ) - fun putAll(map: Map, replaceIfExists: Boolean = true) { + fun putAll( + map: Map, + replaceIfExists: Boolean = true, + ) { for (pair in map) put(pair.key, pair.value, replaceIfExists) } @@ -63,7 +69,10 @@ abstract class AbstractBinarySearchTree> { return if (value == null) null else Pair(key, value) } - private fun getRec(key: K, vertex: N? = root): V? { + private fun getRec( + key: K, + vertex: N? = root, + ): V? { if (vertex == null) return null return when (compareKeys(key, vertex.key)) { 0 -> vertex.value @@ -73,22 +82,33 @@ abstract class AbstractBinarySearchTree> { } protected fun getMinKeyNodeRec(vertex: N? = root): N? { - if (vertex == null) return null - else { - return if (vertex.leftSon == null) vertex - else getMinKeyNodeRec(vertex.leftSon) + if (vertex == null) { + return null + } else { + return if (vertex.leftSon == null) { + vertex + } else { + getMinKeyNodeRec(vertex.leftSon) + } } } protected fun getMaxKeyNodeRec(vertex: N? = root): N? { - if (vertex == null) return null - else { - return if (vertex.rightSon == null) vertex - else getMaxKeyNodeRec(vertex.rightSon) + if (vertex == null) { + return null + } else { + return if (vertex.rightSon == null) { + vertex + } else { + getMaxKeyNodeRec(vertex.rightSon) + } } } - protected fun compareKeys(firstKey: K, secondKey: K): Int { + protected fun compareKeys( + firstKey: K, + secondKey: K, + ): Int { val cpr = comparator return if (cpr != null) { when (cpr.compare(firstKey, secondKey)) { diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index df82664..67951e7 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -3,7 +3,6 @@ package main.trees import main.vertexes.RBVertex class RBSearchTree : AbstractBinarySearchTree> { - // 4 cases we need to look at // 1) remove red vertex with 0 children -> just remove vertex @@ -22,8 +21,11 @@ class RBSearchTree : AbstractBinarySearchTree> { --size val value = vertex.value - if (vertex == root && size == 0L) root = null - else if (needToBalance(vertex)) balanceAfterRemove(vertex) + if (vertex == root && size == 0L) { + root = null + } else if (needToBalance(vertex)) { + balanceAfterRemove(vertex) + } return value } @@ -178,7 +180,11 @@ class RBSearchTree : AbstractBinarySearchTree> { // finds free place and inserts newVertex, colors it in red // if vertex with such key exists, replaces it - override fun put(key: K, value: V, replaceIfExists: Boolean) { + override fun put( + key: K, + value: V, + replaceIfExists: Boolean, + ) { var currentVertex: RBVertex? = root var parent: RBVertex? = null var isLeft: Boolean = false @@ -208,9 +214,13 @@ class RBSearchTree : AbstractBinarySearchTree> { if (currentVertex == null) { currentVertex = RBVertex(key, value, null, null, true, parent) - if (root == null) root = currentVertex - else if (isLeft) parent?.let { parent.leftSon = currentVertex } - else parent?.let { parent.rightSon = currentVertex } + if (root == null) { + root = currentVertex + } else if (isLeft) { + parent?.let { parent.leftSon = currentVertex } + } else { + parent?.let { parent.rightSon = currentVertex } + } } balanceAfterPut(currentVertex) @@ -286,10 +296,17 @@ class RBSearchTree : AbstractBinarySearchTree> { private fun getChild(vertex: RBVertex) = if (vertex.leftSon != null) vertex.leftSon else vertex.rightSon - private fun replaceVertexBy(oldVertex: RBVertex, newVertex: RBVertex?) { - if (root == oldVertex) root = newVertex - else if (oldVertex == oldVertex.parent?.leftSon) oldVertex.parent?.leftSon = newVertex - else oldVertex.parent?.rightSon = newVertex + private fun replaceVertexBy( + oldVertex: RBVertex, + newVertex: RBVertex?, + ) { + if (root == oldVertex) { + root = newVertex + } else if (oldVertex == oldVertex.parent?.leftSon) { + oldVertex.parent?.leftSon = newVertex + } else { + oldVertex.parent?.rightSon = newVertex + } newVertex?.parent = oldVertex.parent } @@ -330,6 +347,6 @@ class RBSearchTree : AbstractBinarySearchTree> { constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( map, replaceIfExists, - comparator + comparator, ) } diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index 796613d..aac245b 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -3,8 +3,11 @@ package main.trees import main.vertexes.SimpleBSTVertex open class SimpleBinarySearchTree : AbstractBinarySearchTree> { - - override fun put(key: K, value: V, replaceIfExists: Boolean) { + override fun put( + key: K, + value: V, + replaceIfExists: Boolean, + ) { if (root == null) { root = SimpleBSTVertex(key, value) size++ @@ -12,7 +15,12 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree? = root) { + private fun putRec( + key: K, + value: V, + replaceIfExists: Boolean = true, + vertex: SimpleBSTVertex? = root, + ) { if (vertex == null) return when (compareKeys(key, vertex.key)) { 0 -> if (replaceIfExists) vertex.value = value @@ -20,14 +28,18 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree { if (vertex.rightSon == null) { vertex.rightSon = SimpleBSTVertex(key, value) size++ - } else putRec(key, value, replaceIfExists, vertex.rightSon) + } else { + putRec(key, value, replaceIfExists, vertex.rightSon) + } } } } @@ -38,7 +50,10 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree? = root): Triple?, V?, Boolean> { + private fun removeRec( + key: K, + vertex: SimpleBSTVertex? = root, + ): Triple?, V?, Boolean> { if (vertex == null) return Triple(null, null, false) when (compareKeys(key, vertex.key)) { @@ -81,6 +96,6 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( map, replaceIfExists, - comparator + comparator, ) } diff --git a/lib/src/main/kotlin/vertexes/AVLVertex.kt b/lib/src/main/kotlin/vertexes/AVLVertex.kt index 6194c2d..a45054a 100644 --- a/lib/src/main/kotlin/vertexes/AVLVertex.kt +++ b/lib/src/main/kotlin/vertexes/AVLVertex.kt @@ -2,9 +2,8 @@ package main.vertexes class AVLVertex( override var key: K, - override var value: V + override var value: V, ) : InterfaceBSTVertex> { - override var leftSon: AVLVertex? = null override var rightSon: AVLVertex? = null var sonsHeightDiff: Int = 0 @@ -14,7 +13,7 @@ class AVLVertex( value: V, leftSon: AVLVertex?, rightSon: AVLVertex?, - sonsHeightDiff: Int = 0 + sonsHeightDiff: Int = 0, ) : this(key, value) { this.leftSon = leftSon this.rightSon = rightSon diff --git a/lib/src/main/kotlin/vertexes/RBVertex.kt b/lib/src/main/kotlin/vertexes/RBVertex.kt index 2f1d9b0..2173de4 100644 --- a/lib/src/main/kotlin/vertexes/RBVertex.kt +++ b/lib/src/main/kotlin/vertexes/RBVertex.kt @@ -2,9 +2,8 @@ package main.vertexes class RBVertex( override var key: K, - override var value: V + override var value: V, ) : InterfaceBSTVertex> { - var isRed = true var parent: RBVertex? = null override var leftSon: RBVertex? = null @@ -16,8 +15,11 @@ class RBVertex( leftSon: RBVertex?, rightSon: RBVertex?, isRed: Boolean, - parent: RBVertex? + parent: RBVertex?, ) : this(key, value) { - this.leftSon = leftSon; this.rightSon = rightSon; this.parent = parent; this.isRed = isRed + this.leftSon = leftSon + this.rightSon = rightSon + this.parent = parent + this.isRed = isRed } } diff --git a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt index 9041ed6..116a973 100644 --- a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt +++ b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt @@ -2,9 +2,8 @@ package main.vertexes class SimpleBSTVertex( override var key: K, - override var value: V + override var value: V, ) : InterfaceBSTVertex> { - override var leftSon: SimpleBSTVertex? = null override var rightSon: SimpleBSTVertex? = null @@ -12,8 +11,9 @@ class SimpleBSTVertex( key: K, value: V, leftSon: SimpleBSTVertex?, - rightSon: SimpleBSTVertex? + rightSon: SimpleBSTVertex?, ) : this(key, value) { - this.leftSon = leftSon; this.rightSon = rightSon + this.leftSon = leftSon + this.rightSon = rightSon } } diff --git a/lib/src/test/kotlin/AVLTreeForTest.kt b/lib/src/test/kotlin/AVLTreeForTest.kt index 67e626e..442ff59 100644 --- a/lib/src/test/kotlin/AVLTreeForTest.kt +++ b/lib/src/test/kotlin/AVLTreeForTest.kt @@ -1,11 +1,10 @@ +import main.trees.AVLSearchTree +import main.vertexes.AVLVertex import kotlin.collections.mutableListOf import kotlin.collections.mutableMapOf import kotlin.math.max -import main.trees.AVLSearchTree -import main.vertexes.AVLVertex class AVLTreeForTest : AVLSearchTree { - fun getRootT(): AVLVertex? { return root } @@ -16,7 +15,10 @@ class AVLTreeForTest : AVLSearchTree { return vertexes } - private fun getVertexesRec(curVertex: AVLVertex?, vrtList: MutableList>) { + private fun getVertexesRec( + curVertex: AVLVertex?, + vrtList: MutableList>, + ) { if (curVertex == null) return vrtList.add(curVertex) getVertexesRec(curVertex.leftSon, vrtList) @@ -30,7 +32,10 @@ class AVLTreeForTest : AVLSearchTree { return heights } - private fun getHeightsRec(rootOfSubtree: AVLVertex, heights: MutableMap): Int { + private fun getHeightsRec( + rootOfSubtree: AVLVertex, + heights: MutableMap, + ): Int { return when ((rootOfSubtree.leftSon == null) to (rootOfSubtree.rightSon == null)) { true to true -> { heights.put(rootOfSubtree.key, 0) @@ -69,6 +74,6 @@ class AVLTreeForTest : AVLSearchTree { constructor( map: Map, replaceIfExists: Boolean = true, - comparator: Comparator? = null + comparator: Comparator? = null, ) : super(map, replaceIfExists, comparator) } diff --git a/lib/src/test/kotlin/AVLTreeTest.kt b/lib/src/test/kotlin/AVLTreeTest.kt index 5cba069..5a5dfd9 100644 --- a/lib/src/test/kotlin/AVLTreeTest.kt +++ b/lib/src/test/kotlin/AVLTreeTest.kt @@ -1,9 +1,8 @@ -import kotlin.collections.hashMapOf import main.vertexes.AVLVertex import org.junit.jupiter.api.Test +import kotlin.collections.hashMapOf class AVLTreeTest { - private fun makeEmptyTree(): AVLTreeForTest { return AVLTreeForTest() } @@ -79,7 +78,10 @@ class AVLTreeTest { return AVLTreeForTest(AVLVertex(4, 'A', AVLVertex(1, 'I'), AVLVertex(5, 'S')), 3L) } - private fun isTreeConsistsOf(expectedContent: Set>, tree: AVLTreeForTest): Boolean { + private fun isTreeConsistsOf( + expectedContent: Set>, + tree: AVLTreeForTest, + ): Boolean { val vertexes = tree.getVertexesInDFSOrder() val pairsFromVertexes = (Array(vertexes.size) { i -> (vertexes[i].key to vertexes[i].value) }).toSet() return pairsFromVertexes == expectedContent @@ -102,7 +104,7 @@ class AVLTreeTest { private fun isTreeSStructureThat( tree: AVLTreeForTest, order: Array, - deps: List> + deps: List>, ): Boolean { // Tiple consists of indexes in order of (1)vertex, one's (2)leftSon and (3)RightSon val vertexes = tree.getVertexesInDFSOrder() @@ -110,12 +112,16 @@ class AVLTreeTest { for (i in order.indices) if (order[i] != vertexes[i].key) return false for (dep in deps) { - if (dep.component2() != null) - if (vertexes[dep.component1()].leftSon != vertexes[dep.component2() as Int]) + if (dep.component2() != null) { + if (vertexes[dep.component1()].leftSon != vertexes[dep.component2() as Int]) { return false - if (dep.component3() != null) - if (vertexes[dep.component1()].rightSon != vertexes[dep.component3() as Int]) + } + } + if (dep.component3() != null) { + if (vertexes[dep.component1()].rightSon != vertexes[dep.component3() as Int]) { return false + } + } } return true } @@ -167,10 +173,18 @@ class AVLTreeTest { fun `content is correct after entry was added (have to rotate left)`() { val tree = makeTreeForHaveToRotateLeftPutTest() tree.put('j', 'J') - val expectedContent = setOf( - 'a' to 'A', 'b' to 'B', 'c' to 'C', - 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J' - ) + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -185,10 +199,14 @@ class AVLTreeTest { fun `structure is correct after added (have to rotate left)`() { val tree = makeTreeForHaveToRotateLeftPutTest() tree.put('j', 'J') - val expectedDependences = listOf( - Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), - Triple(4, 5, 6), Triple(7, null, 8) - ) + val expectedDependences = + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 7), + Triple(4, 5, 6), + Triple(7, null, 8), + ) val expectedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -211,10 +229,18 @@ class AVLTreeTest { fun `content is correct after entry was added (have to rotate right)`() { val tree = makeTreeForHaveToRotateRightPutTest() tree.put('a', 'A') - val expectedContent = setOf( - 'a' to 'A', 'b' to 'B', 'c' to 'C', - 'd' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J' - ) + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -229,10 +255,14 @@ class AVLTreeTest { fun `structure is correct after added (have to rotate right)`() { val tree = makeTreeForHaveToRotateRightPutTest() tree.put('a', 'A') - val expectedDependences = listOf( - Triple(0, 1, 7), Triple(1, 2, 4), Triple(2, 3, null), - Triple(4, 5, 6), Triple(7, null, 8) - ) + val expectedDependences = + listOf( + Triple(0, 1, 7), + Triple(1, 2, 4), + Triple(2, 3, null), + Triple(4, 5, 6), + Triple(7, null, 8), + ) val expectedOrder = arrayOf('h', 'c', 'b', 'a', 'f', 'd', 'e', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -330,10 +360,18 @@ class AVLTreeTest { fun `content is correct after entry was added (have to big rotate left)(1)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('f', 'F') - val expectedContent = setOf( - 'a' to 'A', 'b' to 'B', 'c' to 'C', - 'd' to 'D', 'e' to 'E', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J' - ) + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'g' to 'G', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -341,10 +379,18 @@ class AVLTreeTest { fun `content is correct after entry was added (have to big rotate left)(2)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('h', 'H') - val expectedContent = setOf( - 'a' to 'A', 'b' to 'B', 'c' to 'C', - 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J' - ) + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'g' to 'G', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -366,10 +412,14 @@ class AVLTreeTest { fun `structure is correct after added (have to big rotate left)(1)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('f', 'F') - val expectedDependences = listOf( - Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 7), - Triple(4, 5, 6), Triple(7, null, 8) - ) + val expectedDependences = + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 7), + Triple(4, 5, 6), + Triple(7, null, 8), + ) val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'f', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -378,10 +428,14 @@ class AVLTreeTest { fun `structure is correct after added (have to big rotate left)(2)`() { val tree = makeTreeForHaveToBigRotateLeftPutTest() tree.put('h', 'H') - val expectedDependences = listOf( - Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 6), - Triple(4, 5, null), Triple(6, 7, 8) - ) + val expectedDependences = + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 6), + Triple(4, 5, null), + Triple(6, 7, 8), + ) val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'i', 'h', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -412,10 +466,18 @@ class AVLTreeTest { fun `content is correct after entry was added (have to big rotate right)(1)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('c', 'C') - val expectedContent = setOf( - 'a' to 'A', 'b' to 'B', 'c' to 'C', - 'd' to 'D', 'h' to 'H', 'g' to 'G', 'f' to 'F', 'i' to 'I', 'j' to 'J' - ) + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'h' to 'H', + 'g' to 'G', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -423,10 +485,18 @@ class AVLTreeTest { fun `content is correct after entry was added (have to big rotate right)(2)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('e', 'E') - val expectedContent = setOf( - 'a' to 'A', 'b' to 'B', 'f' to 'F', - 'd' to 'D', 'e' to 'E', 'h' to 'H', 'g' to 'G', 'i' to 'I', 'j' to 'J' - ) + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'f' to 'F', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'g' to 'G', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -448,10 +518,14 @@ class AVLTreeTest { fun `structure is correct after added (have to big rotate right)(1)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('c', 'C') - val expectedDependences = listOf( - Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 5), - Triple(5, null, 6), Triple(2, 3, 4) - ) + val expectedDependences = + listOf( + Triple(0, 1, 7), + Triple(7, null, 8), + Triple(1, 2, 5), + Triple(5, null, 6), + Triple(2, 3, 4), + ) val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'c', 'f', 'g', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -460,10 +534,14 @@ class AVLTreeTest { fun `structure is correct after added (have to big rotate right)(2)`() { val tree = makeTreeForHaveToBigRotateRightPutTest() tree.put('e', 'E') - val expectedDependences = listOf( - Triple(0, 1, 7), Triple(7, null, 8), Triple(1, 2, 4), - Triple(2, 3, null), Triple(4, 5, 6) - ) + val expectedDependences = + listOf( + Triple(0, 1, 7), + Triple(7, null, 8), + Triple(1, 2, 4), + Triple(2, 3, null), + Triple(4, 5, 6), + ) val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'f', 'e', 'g', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -550,8 +628,11 @@ class AVLTreeTest { val tree = makeTreeForRemoveLeafWithoutBalanceingTest() tree.remove('z') val root = tree.getRootT() - if (root != null) assert(root.rightSon == null) - else assert(false) + if (root != null) { + assert(root.rightSon == null) + } else { + assert(false) + } } @Test @@ -559,8 +640,11 @@ class AVLTreeTest { val tree = makeTreeForRemoveLeafWithoutBalanceingTest() tree.remove('n') val root = tree.getRootT() - if (root != null) assert(root.leftSon == null) - else assert(false) + if (root != null) { + assert(root.leftSon == null) + } else { + assert(false) + } } @Test @@ -833,10 +917,21 @@ class AVLTreeTest { fun `content is correct after removed left son with both sons (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('f') - val expectedContent = setOf( - 'a' to 'A', 'b' to 'B', 'c' to 'C', 'e' to 'E', 'i' to 'I', - 'z' to 'Z', 'k' to 'K', 'n' to 'N', 'u' to 'U', 'q' to 'Q', 's' to 'S', 'w' to 'W' - ) + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'e' to 'E', + 'i' to 'I', + 'z' to 'Z', + 'k' to 'K', + 'n' to 'N', + 'u' to 'U', + 'q' to 'Q', + 's' to 'S', + 'w' to 'W', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -851,10 +946,15 @@ class AVLTreeTest { fun `structure is correct after removed left son with both sons (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('f') - val expectedDependences = listOf( - Triple(0, 1, 7), Triple(1, 2, 5), Triple(2, 3, 4), - Triple(5, null, 6), Triple(7, 8, 10), Triple(10, null, 11) - ) + val expectedDependences = + listOf( + Triple(0, 1, 7), + Triple(1, 2, 5), + Triple(2, 3, 4), + Triple(5, null, 6), + Triple(7, 8, 10), + Triple(10, null, 11), + ) val expectedOrder = arrayOf('n', 'e', 'b', 'a', 'c', 'i', 'k', 'u', 'q', 's', 'w', 'z') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -876,10 +976,21 @@ class AVLTreeTest { fun `content is correct after removed right son with both sons (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('u') - val expectedContent = setOf( - 'a' to 'A', 'b' to 'B', 'c' to 'C', 'e' to 'E', 'i' to 'I', - 'z' to 'Z', 'k' to 'K', 'n' to 'N', 'f' to 'F', 'q' to 'Q', 's' to 'S', 'w' to 'W' - ) + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'e' to 'E', + 'i' to 'I', + 'z' to 'Z', + 'k' to 'K', + 'n' to 'N', + 'f' to 'F', + 'q' to 'Q', + 's' to 'S', + 'w' to 'W', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -894,10 +1005,16 @@ class AVLTreeTest { fun `structure is correct after removed right son with both sons (needn't balanceing)`() { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('u') - val expectedDependences = listOf( - Triple(0, 1, 8), Triple(1, 2, 6), Triple(2, 3, 4), - Triple(6, null, 7), Triple(4, 5, null), Triple(8, 9, 10), Triple(10, null, 11) - ) + val expectedDependences = + listOf( + Triple(0, 1, 8), + Triple(1, 2, 6), + Triple(2, 3, 4), + Triple(6, null, 7), + Triple(4, 5, null), + Triple(8, 9, 10), + Triple(10, null, 11), + ) val expectedOrder = arrayOf('n', 'f', 'b', 'a', 'e', 'c', 'i', 'k', 's', 'q', 'w', 'z') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -984,10 +1101,15 @@ class AVLTreeTest { fun `content is correct after removed and rotated left (1)`() { val tree = makeTreeForRemoveWithLeftRotate1Test() tree.remove('l') - val expectedContent = setOf( - 'k' to true, 'i' to false, 'm' to true, - 'o' to false, 'p' to true, 'a' to false - ) + val expectedContent = + setOf( + 'k' to true, + 'i' to false, + 'm' to true, + 'o' to false, + 'p' to true, + 'a' to false, + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -995,10 +1117,16 @@ class AVLTreeTest { fun `content is correct after removed and rotated left (2)`() { val tree = makeTreeForRemoveWithLeftRotate2Test() tree.remove('l') - val expectedContent = setOf( - 'k' to true, 'i' to false, 'm' to true, - 'o' to false, 'p' to true, 'n' to true, 'a' to false - ) + val expectedContent = + setOf( + 'k' to true, + 'i' to false, + 'm' to true, + 'o' to false, + 'p' to true, + 'n' to true, + 'a' to false, + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -1029,10 +1157,13 @@ class AVLTreeTest { fun `structure is correct after removed and rotated left (2)`() { val tree = makeTreeForRemoveWithLeftRotate2Test() tree.remove('l') - val expectedDependences = listOf( - Triple(0, 1, 3), Triple(3, 4, 6), - Triple(4, null, 5), Triple(1, 2, null) - ) + val expectedDependences = + listOf( + Triple(0, 1, 3), + Triple(3, 4, 6), + Triple(4, null, 5), + Triple(1, 2, null), + ) val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'n', 'p') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -1082,10 +1213,15 @@ class AVLTreeTest { fun `content is correct after removed and rotated right (1)`() { val tree = makeTreeForRemoveWithRightRotate1Test() tree.remove('e') - val expectedContent = setOf( - 'k' to true, 'b' to true, 'm' to true, - 'o' to false, 'd' to true, 'a' to false - ) + val expectedContent = + setOf( + 'k' to true, + 'b' to true, + 'm' to true, + 'o' to false, + 'd' to true, + 'a' to false, + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -1093,10 +1229,16 @@ class AVLTreeTest { fun `content is correct after removed and rotated right (2)`() { val tree = makeTreeForRemoveWithRightRotate2Test() tree.remove('e') - val expectedContent = setOf( - 'k' to true, 'b' to true, 'm' to true, - 'o' to false, 'd' to true, 'a' to false, 'c' to true - ) + val expectedContent = + setOf( + 'k' to true, + 'b' to true, + 'm' to true, + 'o' to false, + 'd' to true, + 'a' to false, + 'c' to true, + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -1127,10 +1269,13 @@ class AVLTreeTest { fun `structure is correct after removed and rotated right (2)`() { val tree = makeTreeForRemoveWithRightRotate2Test() tree.remove('e') - val expectedDependences = listOf( - Triple(0, 1, 5), Triple(1, 2, 3), - Triple(5, null, 6), Triple(3, 4, null) - ) + val expectedDependences = + listOf( + Triple(0, 1, 5), + Triple(1, 2, 3), + Triple(5, null, 6), + Triple(3, 4, null), + ) val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'c', 'm', 'o') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) } @@ -1250,10 +1395,16 @@ class AVLTreeTest { fun `content is correct after removed (bigRotateLeft changed root)`() { val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() tree.remove(' ') - val expectedContent = setOf( - 'd' to 'D', 'c' to 'C', 'e' to 'E', 'f' to 'F', - 'g' to 'G', 'b' to 'B', 'a' to 'A' - ) + val expectedContent = + setOf( + 'd' to 'D', + 'c' to 'C', + 'e' to 'E', + 'f' to 'F', + 'g' to 'G', + 'b' to 'B', + 'a' to 'A', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -1297,10 +1448,16 @@ class AVLTreeTest { fun `content is correct after removed (bigRotateRight changed root)`() { val tree = makeTreeForBigRotateRightChangesRootRemoveTest() tree.remove('k') - val expectedContent = setOf( - 'a' to 1, 'b' to 2, 'c' to 3, 'd' to 4, 'e' to 5, - 'i' to 9, 'f' to 8 - ) + val expectedContent = + setOf( + 'a' to 1, + 'b' to 2, + 'c' to 3, + 'd' to 4, + 'e' to 5, + 'i' to 9, + 'f' to 8, + ) assert(isTreeConsistsOf(expectedContent, tree)) } diff --git a/lib/src/test/kotlin/IteratorTests.kt b/lib/src/test/kotlin/IteratorTests.kt index f740ad2..b847ef9 100644 --- a/lib/src/test/kotlin/IteratorTests.kt +++ b/lib/src/test/kotlin/IteratorTests.kt @@ -4,7 +4,6 @@ import org.junit.jupiter.api.Assertions.assertEquals import kotlin.test.Test class IteratorTests { - @Test fun `add in stack`() { val vertex = SimpleBSTVertex(1, "one") diff --git a/lib/src/test/kotlin/SimpleBSTTests.kt b/lib/src/test/kotlin/SimpleBSTTests.kt index 0dcab62..78fd00a 100644 --- a/lib/src/test/kotlin/SimpleBSTTests.kt +++ b/lib/src/test/kotlin/SimpleBSTTests.kt @@ -2,7 +2,6 @@ import org.junit.jupiter.api.Test import kotlin.test.assertEquals class SimpleBSTTests { - @Test fun `get root`() { val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) @@ -63,14 +62,15 @@ class SimpleBSTTests { @Test fun `put many vertexes with method putAll() test`() { - val map: Map = mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") - ) + val map: Map = + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two"), + ) val tree: TestSimpleBST = TestSimpleBST(mapOf(Pair(1, "one"))) tree.putAll(map) assertEquals(6, tree.size()) @@ -128,16 +128,17 @@ class SimpleBSTTests { @Test fun `remove two sons with right subtree vertex test`() { - val tree: TestSimpleBST = TestSimpleBST( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") + val tree: TestSimpleBST = + TestSimpleBST( + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two"), + ), ) - ) tree.remove(1) assertEquals(2, tree.getTreeRoot()?.key) assertEquals(5, tree.size()) @@ -145,16 +146,17 @@ class SimpleBSTTests { @Test fun `remove many vertex test`() { - val tree: TestSimpleBST = TestSimpleBST( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") + val tree: TestSimpleBST = + TestSimpleBST( + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two"), + ), ) - ) for (key in 0..5) { tree.remove(key) } diff --git a/lib/src/test/kotlin/TestIterator.kt b/lib/src/test/kotlin/TestIterator.kt index 6f02efe..1aa1cd6 100644 --- a/lib/src/test/kotlin/TestIterator.kt +++ b/lib/src/test/kotlin/TestIterator.kt @@ -1,6 +1,6 @@ -import java.util.LinkedList import main.iterator.TreeIterator import main.vertexes.InterfaceBSTVertex +import java.util.LinkedList internal class TestIterator>(vertex: N?) : TreeIterator(vertex) { fun getTreeStack(): LinkedList { diff --git a/lib/src/test/kotlin/TestSimpleBST.kt b/lib/src/test/kotlin/TestSimpleBST.kt index 5e7c2d5..20e43e9 100644 --- a/lib/src/test/kotlin/TestSimpleBST.kt +++ b/lib/src/test/kotlin/TestSimpleBST.kt @@ -10,6 +10,6 @@ class TestSimpleBST : SimpleBinarySearchTree { constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( map, replaceIfExists, - comparator + comparator, ) } diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt index 402aed1..5771b93 100644 --- a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/RBSearchTreeTest.kt @@ -158,10 +158,17 @@ class RBSearchTreeTest { rbTree.put(11, "Slim") rbTree.put(13, "Shady") rbTree.remove(10) - expectedResult = listOf( - Pair(7, "hi"), Pair(11, "Slim"), Pair(12, "chka"), Pair(13, "Shady"), Pair(9, "chka"), - Pair(4, "my"), Pair(5, "chka"), Pair(3, "is") - ) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(11, "Slim"), + Pair(12, "chka"), + Pair(13, "Shady"), + Pair(9, "chka"), + Pair(4, "my"), + Pair(5, "chka"), + Pair(3, "is"), + ) } @Test @@ -176,10 +183,17 @@ class RBSearchTreeTest { rbTree.put(11, "Slim") rbTree.put(13, "Shady") rbTree.remove(9) - expectedResult = listOf( - Pair(7, "hi"), Pair(12, "chka"), Pair(13, "Shady"), Pair(10, "name"), Pair(11, "Slim"), - Pair(4, "my"), Pair(5, "chka"), Pair(3, "is") - ) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(12, "chka"), + Pair(13, "Shady"), + Pair(10, "name"), + Pair(11, "Slim"), + Pair(4, "my"), + Pair(5, "chka"), + Pair(3, "is"), + ) } @Test @@ -193,10 +207,16 @@ class RBSearchTreeTest { rbTree.put(12, "Slim") rbTree.put(11, "Shady") rbTree.remove(9) - expectedResult = listOf( - Pair(7, "hi"), Pair(11, "Shady"), Pair(12, "Slim"), Pair(10, "name"), Pair(4, "my"), - Pair(5, "chka"), Pair(3, "is") - ) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(11, "Shady"), + Pair(12, "Slim"), + Pair(10, "name"), + Pair(4, "my"), + Pair(5, "chka"), + Pair(3, "is"), + ) } @Test @@ -233,11 +253,20 @@ class RBSearchTreeTest { // now vertex with key 96 is red, with key 65 - black rbTree.remove(65) - expectedResult = listOf( - Pair(60, "sixty"), Pair(96, "ninety-six"), Pair(97, "ninety-seven"), - Pair(94, "ninety-four"), Pair(95, "ninety-five"), Pair(84, "eighty-four"), Pair(33, "thirty-three"), - Pair(51, "fifty-one"), Pair(52, "Alblack"), Pair(34, "thirty-four"), Pair(15, "fifteen") - ) + expectedResult = + listOf( + Pair(60, "sixty"), + Pair(96, "ninety-six"), + Pair(97, "ninety-seven"), + Pair(94, "ninety-four"), + Pair(95, "ninety-five"), + Pair(84, "eighty-four"), + Pair(33, "thirty-three"), + Pair(51, "fifty-one"), + Pair(52, "Alblack"), + Pair(34, "thirty-four"), + Pair(15, "fifteen"), + ) } @Test @@ -252,10 +281,17 @@ class RBSearchTreeTest { rbTree.put(1, "Slim") rbTree.put(3, "Shady") rbTree.remove(5) - expectedResult = listOf( - Pair(7, "hi"), Pair(10, "name"), Pair(12, "chka"), Pair(9, "chka"), Pair(2, "is"), - Pair(4, "my"), Pair(3, "Shady"), Pair(1, "Slim") - ) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(10, "name"), + Pair(12, "chka"), + Pair(9, "chka"), + Pair(2, "is"), + Pair(4, "my"), + Pair(3, "Shady"), + Pair(1, "Slim"), + ) } @Test @@ -269,10 +305,16 @@ class RBSearchTreeTest { rbTree.put(12, "Slim") rbTree.put(3, "Shady") rbTree.remove(5) - expectedResult = listOf( - Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(9, "chka"), Pair(3, "Shady"), - Pair(4, "my"), Pair(2, "is") - ) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(10, "name"), + Pair(12, "Slim"), + Pair(9, "chka"), + Pair(3, "Shady"), + Pair(4, "my"), + Pair(2, "is"), + ) } @Test @@ -309,11 +351,20 @@ class RBSearchTreeTest { // now vertex with key 15 is red, with key 51 - black rbTree.remove(51) - expectedResult = listOf( - Pair(60, "sixty"), Pair(84, "eighty-four"), Pair(96, "ninety-six"), - Pair(65, "sixty-five"), Pair(69, "sixty-nine"), Pair(61, "sixty-one"), Pair(15, "fifteen"), - Pair(27, "twenty-seven"), Pair(33, "thirty-three"), Pair(17, "seventeen"), Pair(5, "five") - ) + expectedResult = + listOf( + Pair(60, "sixty"), + Pair(84, "eighty-four"), + Pair(96, "ninety-six"), + Pair(65, "sixty-five"), + Pair(69, "sixty-nine"), + Pair(61, "sixty-one"), + Pair(15, "fifteen"), + Pair(27, "twenty-seven"), + Pair(33, "thirty-three"), + Pair(17, "seventeen"), + Pair(5, "five"), + ) } @Test From 93c8412c938b3ee24e1458a8d636ce2733b51914 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Tue, 2 Apr 2024 13:07:29 +0300 Subject: [PATCH 166/227] docs: add param vertex to docs of AVLSearchTree method putRec() --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 0a64587..dd8a142 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -51,6 +51,7 @@ class AVLSearchTree : AbstractBinarySearchTree> { * @param key the key with which the specified value is to be associated * @param value the value to be associated with the specified key * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * @param vertex the current vertex in the recursion * @return the root vertex of the tree after the operation */ private fun putRec(key: K, value: V, From 676469c93339518b385caee930c1a0e30ee0d068 Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 2 Apr 2024 01:49:11 +0300 Subject: [PATCH 167/227] feat : add AbstractTreeTest --- lib/src/test/kotlin/AbstractTreeTest.kt | 242 ++++++++++++++++++++++++ lib/src/test/kotlin/TestTree.kt | 31 +++ 2 files changed, 273 insertions(+) create mode 100644 lib/src/test/kotlin/AbstractTreeTest.kt create mode 100644 lib/src/test/kotlin/TestTree.kt diff --git a/lib/src/test/kotlin/AbstractTreeTest.kt b/lib/src/test/kotlin/AbstractTreeTest.kt new file mode 100644 index 0000000..a88ddad --- /dev/null +++ b/lib/src/test/kotlin/AbstractTreeTest.kt @@ -0,0 +1,242 @@ +import main.vertexes.SimpleBSTVertex +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.* +import java.util.Comparator + +class AbstractTreeTest { + + private fun makeEmptyTree() : TestTree { + return TestTree() + } + + @Test + fun `isEmpty() returns true if tree is empty `() { + val tree = makeEmptyTree() + assert(tree.isEmpty()) + } + + @Test + fun `size() returns 0 if tree is empty`() { + val tree = makeEmptyTree() + assert(tree.size() == 0L) + } + + @Test + fun `get() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.get(intArrayOf(0))) + } + + @Test + fun `getMax() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.getMax()) + } + + @Test + fun `getMin() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.getMin()) + } + + @Test + fun `getMaxKeyPair() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.getMaxKeyPair()) + } + + @Test + fun `getMinKeyPair() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.getMinKeyPair()) + } + + private fun makeTreeWithBothRootSSons() : TestTree { + val leftSon = SimpleBSTVertex('1', "!", SimpleBSTVertex('0', ")"), null) + val rightSon = SimpleBSTVertex('4', "$", SimpleBSTVertex('3', "#"), null) + return TestTree(SimpleBSTVertex('2', "@", leftSon, rightSon), 5L) + } + + @Test + fun `isEmpty() returns false if tree is not empty `() { + val tree = makeTreeWithBothRootSSons() + assertFalse(tree.isEmpty()) + } + + @Test + fun `size() returns not 0 if tree is not empty`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.size() != 0L) + } + + @Test + fun `get() returns null when tree doesn'n contains given key`() { + val tree = makeTreeWithBothRootSSons() + assertNull(tree.get('z')) + } + + @Test + fun `getPair() returns null when tree doesn'n contains given key`() { + val tree = makeTreeWithBothRootSSons() + assertNull(tree.getPair('z')) + } + + @Test + fun `get() returns correct value when tree contains given key in left subtree`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.get('1') == "!") + } + + @Test + fun `getPair() returns correct value when tree contains given key in left subtree`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getPair('1') == ('1' to "!")) + } + + @Test + fun `get() returns correct value when tree contains given key in right subtree`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.get('4') == "$") + } + + @Test + fun `get() returns correct value when root's key was given`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.get('2') == "@") + } + + @Test + fun `get() returns correct value when leaf's key was given`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.get('3') == "#") + } + + @Test + fun `getMin() returns correct value when root has two sons`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getMin() == ")") + } + + @Test + fun `getMax() returns correct value when root has two sons`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getMax() == "$") + } + + @Test + fun `getMinKeyPair() returns correct value when root has two sons`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getMinKeyPair() == ('0' to ")")) + } + + @Test + fun `getMaxKeyPair() returns correct value when root has two sons`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getMaxKeyPair() == ('4' to "$")) + } + + private fun makeTreeWithOnlyLeftRootSSon() : TestTree { + val leftSon = SimpleBSTVertex('1', "!", SimpleBSTVertex('0', ")"), SimpleBSTVertex('2', "@")) + return TestTree(SimpleBSTVertex('3', "#", leftSon, null), 4L) + } + + @Test + fun `getMax() returns correct value when root has only left son`() { + val tree = makeTreeWithOnlyLeftRootSSon() + assert(tree.getMax() == "#") + } + + private fun makeTreeWithOnlyRightRootSSon() : TestTree { + val rightSon = SimpleBSTVertex('6', "^", SimpleBSTVertex('5', "%"), SimpleBSTVertex('8', "*")) + return TestTree(SimpleBSTVertex('3', "#", null, rightSon), 4L) + } + + @Test + fun `getMin() returns correct value when root has only right son`() { + val tree = makeTreeWithOnlyRightRootSSon() + assert(tree.getMin() == "#") + } + + @Test + fun `removeAndReturnPair() returns null when remove() returned null`() { + val tree = TestTree(removeShouldReturns = null) + assertNull(tree.removeAndReturnPair(1)) + } + + @Test + fun `removeAndReturnPair() returns (given key) to (value that remove() returned) pair`() { + val tree = TestTree(removeShouldReturns = '1') + assert (tree.removeAndReturnPair(3) == (3 to '1')) + } + + @Test + fun `putAll() do correct put() call for each map element (1)`() { + val tree = TestTree() + val map = hashMapOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'a' to 'A') + tree.putAll(map) + for (pair in map) + assertNotNull(tree.putWasCalledWithParams.remove(Triple(pair.component1(), pair.component2(), true))) + } + + @Test + fun `putAll() do correct put() call for each map element (2)`() { + val tree = TestTree() + val map = hashMapOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'a' to 'A') + tree.putAll(map, false) + for (pair in map) + assertNotNull(tree.putWasCalledWithParams.remove(Triple(pair.component1(), pair.component2(), false))) + } + + @Test + fun `compareKeys return 1 when key1 larger than key2 (keys are comparable)`() { + val tree = TestTree() + assert (tree.compareKeysT(18, 14) == 1) + } + + @Test + fun `compareKeys return 0 when key1 equals key2 (keys are comparable)`() { + val tree = TestTree() + assert (tree.compareKeysT(18, 18) == 0) + } + + @Test + fun `compareKeys return -1 when key1 lesser than key2 (keys are comparable)`() { + val tree = TestTree() + assert (tree.compareKeysT(14, 18) == -1) + } + + class cmp : Comparator { + override fun compare(o1 : IntArray, o2 : IntArray) : Int { + return o1.sum() - o2.sum() + } + } + + + @Test + fun `compareKeys return 1 when key1 larger than key2 (comparator was given)`() { + val tree = TestTree(cmp()) + assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(-1)) == 1) + } + + @Test + fun `compareKeys return 0 when key1 equals key2 (comparator was given)`() { + val tree = TestTree(cmp()) + assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(0)) == 0) + } + + @Test + fun `compareKeys return -1 when key1 lesser than key2 (comparator was given)`() { + val tree = TestTree(cmp()) + assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1)) == -1) + } + + + @Test + fun `compareKeys fall when keys type doesn't implement compareble && comparator wasn't given`() { + var didItFall = false + val tree = TestTree() + try {tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1))} + catch (e : Exception) {didItFall = true} + assert(didItFall) + } +} diff --git a/lib/src/test/kotlin/TestTree.kt b/lib/src/test/kotlin/TestTree.kt new file mode 100644 index 0000000..e19a65f --- /dev/null +++ b/lib/src/test/kotlin/TestTree.kt @@ -0,0 +1,31 @@ +import main.trees.AbstractBinarySearchTree +import main.vertexes.SimpleBSTVertex + +class TestTree : AbstractBinarySearchTree> { + + var removeShouldReturns : V? = null + var getShouldReturns : V? = null + val putWasCalledWithParams : MutableList> = mutableListOf() + + override fun put(key: K, value: V, replaceIfExists : Boolean) { + putWasCalledWithParams.add(Triple(key, value, replaceIfExists)) + } + + override fun remove(key: K) : V? {return removeShouldReturns} + + fun compareKeysT(firstKey: K, secondKey: K): Int { + return super.compareKeys(firstKey, secondKey) + } + constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : + super(comparator) { + this.root = root + this.size = size + } + + constructor (removeShouldReturns : V?) : super() {this.removeShouldReturns = removeShouldReturns} + + constructor (comparator: Comparator? = null) : super(comparator) + + constructor (map: Map, replaceIfExists: Boolean = true, + comparator: Comparator? = null) : super(map, replaceIfExists, comparator) +} From f9049bb3ee3ee501e87657dd87074562f068233c Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 18:04:18 +0300 Subject: [PATCH 168/227] chore: sort tests into folders --- lib/src/test/kotlin/{ => trees/AVLTree}/AVLTreeForTest.kt | 2 ++ lib/src/test/kotlin/{ => trees/AVLTree}/AVLTreeTest.kt | 2 ++ .../test/kotlin/{ => trees/AbstractTree}/AbstractTreeTest.kt | 2 ++ lib/src/test/kotlin/{ => trees/AbstractTree}/TestTree.kt | 2 ++ .../test/kotlin/trees/{ => RBSearchTree}/RBSearchTreeTest.kt | 2 +- 5 files changed, 9 insertions(+), 1 deletion(-) rename lib/src/test/kotlin/{ => trees/AVLTree}/AVLTreeForTest.kt (99%) rename lib/src/test/kotlin/{ => trees/AVLTree}/AVLTreeTest.kt (99%) rename lib/src/test/kotlin/{ => trees/AbstractTree}/AbstractTreeTest.kt (99%) rename lib/src/test/kotlin/{ => trees/AbstractTree}/TestTree.kt (97%) rename lib/src/test/kotlin/trees/{ => RBSearchTree}/RBSearchTreeTest.kt (99%) diff --git a/lib/src/test/kotlin/AVLTreeForTest.kt b/lib/src/test/kotlin/trees/AVLTree/AVLTreeForTest.kt similarity index 99% rename from lib/src/test/kotlin/AVLTreeForTest.kt rename to lib/src/test/kotlin/trees/AVLTree/AVLTreeForTest.kt index 442ff59..9f65a1c 100644 --- a/lib/src/test/kotlin/AVLTreeForTest.kt +++ b/lib/src/test/kotlin/trees/AVLTree/AVLTreeForTest.kt @@ -1,3 +1,5 @@ +package trees.AVLTree + import main.trees.AVLSearchTree import main.vertexes.AVLVertex import kotlin.collections.mutableListOf diff --git a/lib/src/test/kotlin/AVLTreeTest.kt b/lib/src/test/kotlin/trees/AVLTree/AVLTreeTest.kt similarity index 99% rename from lib/src/test/kotlin/AVLTreeTest.kt rename to lib/src/test/kotlin/trees/AVLTree/AVLTreeTest.kt index 5a5dfd9..41fa4be 100644 --- a/lib/src/test/kotlin/AVLTreeTest.kt +++ b/lib/src/test/kotlin/trees/AVLTree/AVLTreeTest.kt @@ -1,3 +1,5 @@ +package trees.AVLTree + import main.vertexes.AVLVertex import org.junit.jupiter.api.Test import kotlin.collections.hashMapOf diff --git a/lib/src/test/kotlin/AbstractTreeTest.kt b/lib/src/test/kotlin/trees/AbstractTree/AbstractTreeTest.kt similarity index 99% rename from lib/src/test/kotlin/AbstractTreeTest.kt rename to lib/src/test/kotlin/trees/AbstractTree/AbstractTreeTest.kt index a88ddad..224a861 100644 --- a/lib/src/test/kotlin/AbstractTreeTest.kt +++ b/lib/src/test/kotlin/trees/AbstractTree/AbstractTreeTest.kt @@ -1,3 +1,5 @@ +package trees.AbstractTree + import main.vertexes.SimpleBSTVertex import org.junit.jupiter.api.Test import org.junit.jupiter.api.Assertions.* diff --git a/lib/src/test/kotlin/TestTree.kt b/lib/src/test/kotlin/trees/AbstractTree/TestTree.kt similarity index 97% rename from lib/src/test/kotlin/TestTree.kt rename to lib/src/test/kotlin/trees/AbstractTree/TestTree.kt index e19a65f..630ac73 100644 --- a/lib/src/test/kotlin/TestTree.kt +++ b/lib/src/test/kotlin/trees/AbstractTree/TestTree.kt @@ -1,3 +1,5 @@ +package trees.AbstractTree + import main.trees.AbstractBinarySearchTree import main.vertexes.SimpleBSTVertex diff --git a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/RBSearchTree/RBSearchTreeTest.kt similarity index 99% rename from lib/src/test/kotlin/trees/RBSearchTreeTest.kt rename to lib/src/test/kotlin/trees/RBSearchTree/RBSearchTreeTest.kt index 5771b93..f392e81 100644 --- a/lib/src/test/kotlin/trees/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/RBSearchTree/RBSearchTreeTest.kt @@ -1,4 +1,4 @@ -package trees +package trees.RBSearchTree import main.trees.RBSearchTree import org.junit.jupiter.api.AfterEach From 1e12169a41a48ecedeff297beca064b78fc87c25 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 21:04:16 +0300 Subject: [PATCH 169/227] style: changes according to linter --- README.md | 2 +- lib/src/main/kotlin/trees/AVLSearchTree.kt | 6 +- .../kotlin/trees/AbstractBinarySearchTree.kt | 1 - lib/src/main/kotlin/trees/RBSearchTree.kt | 1 - .../kotlin/trees/SimpleBinarySearchTree.kt | 1 - lib/src/test/kotlin/iterator/IteratorTests.kt | 1 - .../kotlin/trees/AbstractTree/TestTree.kt | 33 ------- .../AbstractTreeTest.kt | 89 ++++++++++--------- .../kotlin/trees/abstractTree/TestTree.kt | 46 ++++++++++ .../{AVLTree => avlTree}/AVLTreeForTest.kt | 2 +- .../trees/{AVLTree => avlTree}/AVLTreeTest.kt | 10 ++- .../RBSearchTreeTest.kt | 2 +- .../SimpleBSTreeTest.kt | 60 +++++++------ .../TestSimpleBST.kt | 6 +- 14 files changed, 143 insertions(+), 117 deletions(-) delete mode 100644 lib/src/test/kotlin/trees/AbstractTree/TestTree.kt rename lib/src/test/kotlin/trees/{AbstractTree => abstractTree}/AbstractTreeTest.kt (80%) create mode 100644 lib/src/test/kotlin/trees/abstractTree/TestTree.kt rename lib/src/test/kotlin/trees/{AVLTree => avlTree}/AVLTreeForTest.kt (99%) rename lib/src/test/kotlin/trees/{AVLTree => avlTree}/AVLTreeTest.kt (99%) rename lib/src/test/kotlin/trees/{RBSearchTree => rbTree}/RBSearchTreeTest.kt (99%) rename lib/src/test/kotlin/trees/{SimpleBSTree => simpleBSTree}/SimpleBSTreeTest.kt (82%) rename lib/src/test/kotlin/trees/{SimpleBSTree => simpleBSTree}/TestSimpleBST.kt (75%) diff --git a/README.md b/README.md index fb5bdc4..c2d2824 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ ```kotlin import main.trees.SimpleBinarySearchTree import main.trees.AVLSearchTree -import main.trees.RBSearchTree +import main.trees.rbTree ``` 2. **Instantiate Trees:** diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index fda97a7..2587aa5 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -26,7 +26,6 @@ import main.vertexes.AVLVertex * @property root The root vertex of the tree. */ open class AVLSearchTree : AbstractBinarySearchTree> { - /** * Associates the specified value with the specified key in this tree. * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. @@ -137,7 +136,6 @@ open class AVLSearchTree : AbstractBinarySearchTree> if (!isEmpty()) { val removeRecReturned = removeRec(key, root as AVLVertex) when (removeRecReturned.first) { - RemovalStage.A -> {} RemovalStage.B -> { if (removeRecReturned.component2() != root) { root = removeRecReturned.component2() @@ -146,6 +144,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> RemovalStage.C -> root = null RemovalStage.D -> root = removeRecReturned.component2() + else -> {} } return removeRecReturned.component3() } @@ -174,7 +173,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> /** * Need only to change due "Son" property of (if exists) the parent */ - D + D, } /** @@ -196,7 +195,6 @@ open class AVLSearchTree : AbstractBinarySearchTree> key: K, vertex: AVLVertex, ): Triple, V?> { - /** * Triple consists of: * diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index 008b4dc..76c04ef 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -26,7 +26,6 @@ import main.vertexes.InterfaceBSTVertex * @property root The root vertex of the tree. */ abstract class AbstractBinarySearchTree> { - /** Comparator used for comparing keys. */ protected var comparator: Comparator? = null diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 7650dc4..dfaaa7e 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -32,7 +32,6 @@ import main.vertexes.RBVertex * @property root The root vertex of the tree. */ class RBSearchTree : AbstractBinarySearchTree> { - /** * This method removes the vertex with the given key from the tree and returns its associated value, * maintaining the properties of the red-black tree. diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index 7fa0403..14c124c 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -25,7 +25,6 @@ import main.vertexes.SimpleBSTVertex * @property root The root vertex of the tree. */ open class SimpleBinarySearchTree : AbstractBinarySearchTree> { - /** * Associates the specified value with the specified key in this tree. * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. diff --git a/lib/src/test/kotlin/iterator/IteratorTests.kt b/lib/src/test/kotlin/iterator/IteratorTests.kt index d542361..fb46e01 100644 --- a/lib/src/test/kotlin/iterator/IteratorTests.kt +++ b/lib/src/test/kotlin/iterator/IteratorTests.kt @@ -1,6 +1,5 @@ package iterator -import iterator.TestIterator import main.trees.AVLSearchTree import main.vertexes.SimpleBSTVertex import org.junit.jupiter.api.Assertions.assertEquals diff --git a/lib/src/test/kotlin/trees/AbstractTree/TestTree.kt b/lib/src/test/kotlin/trees/AbstractTree/TestTree.kt deleted file mode 100644 index 630ac73..0000000 --- a/lib/src/test/kotlin/trees/AbstractTree/TestTree.kt +++ /dev/null @@ -1,33 +0,0 @@ -package trees.AbstractTree - -import main.trees.AbstractBinarySearchTree -import main.vertexes.SimpleBSTVertex - -class TestTree : AbstractBinarySearchTree> { - - var removeShouldReturns : V? = null - var getShouldReturns : V? = null - val putWasCalledWithParams : MutableList> = mutableListOf() - - override fun put(key: K, value: V, replaceIfExists : Boolean) { - putWasCalledWithParams.add(Triple(key, value, replaceIfExists)) - } - - override fun remove(key: K) : V? {return removeShouldReturns} - - fun compareKeysT(firstKey: K, secondKey: K): Int { - return super.compareKeys(firstKey, secondKey) - } - constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : - super(comparator) { - this.root = root - this.size = size - } - - constructor (removeShouldReturns : V?) : super() {this.removeShouldReturns = removeShouldReturns} - - constructor (comparator: Comparator? = null) : super(comparator) - - constructor (map: Map, replaceIfExists: Boolean = true, - comparator: Comparator? = null) : super(map, replaceIfExists, comparator) -} diff --git a/lib/src/test/kotlin/trees/AbstractTree/AbstractTreeTest.kt b/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt similarity index 80% rename from lib/src/test/kotlin/trees/AbstractTree/AbstractTreeTest.kt rename to lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt index 224a861..5aded42 100644 --- a/lib/src/test/kotlin/trees/AbstractTree/AbstractTreeTest.kt +++ b/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt @@ -1,13 +1,14 @@ -package trees.AbstractTree +package trees.abstractTree import main.vertexes.SimpleBSTVertex +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Test -import org.junit.jupiter.api.Assertions.* import java.util.Comparator class AbstractTreeTest { - - private fun makeEmptyTree() : TestTree { + private fun makeEmptyTree(): TestTree { return TestTree() } @@ -52,8 +53,8 @@ class AbstractTreeTest { val tree = makeEmptyTree() assertNull(tree.getMinKeyPair()) } - - private fun makeTreeWithBothRootSSons() : TestTree { + + private fun makeTreeWithBothRootSSons(): TestTree { val leftSon = SimpleBSTVertex('1', "!", SimpleBSTVertex('0', ")"), null) val rightSon = SimpleBSTVertex('4', "$", SimpleBSTVertex('3', "#"), null) return TestTree(SimpleBSTVertex('2', "@", leftSon, rightSon), 5L) @@ -107,53 +108,53 @@ class AbstractTreeTest { assert(tree.get('2') == "@") } - @Test + @Test fun `get() returns correct value when leaf's key was given`() { val tree = makeTreeWithBothRootSSons() assert(tree.get('3') == "#") } - @Test + @Test fun `getMin() returns correct value when root has two sons`() { val tree = makeTreeWithBothRootSSons() assert(tree.getMin() == ")") } - @Test + @Test fun `getMax() returns correct value when root has two sons`() { val tree = makeTreeWithBothRootSSons() assert(tree.getMax() == "$") } - @Test + @Test fun `getMinKeyPair() returns correct value when root has two sons`() { val tree = makeTreeWithBothRootSSons() assert(tree.getMinKeyPair() == ('0' to ")")) } - @Test + @Test fun `getMaxKeyPair() returns correct value when root has two sons`() { val tree = makeTreeWithBothRootSSons() assert(tree.getMaxKeyPair() == ('4' to "$")) } - private fun makeTreeWithOnlyLeftRootSSon() : TestTree { + private fun makeTreeWithOnlyLeftRootSSon(): TestTree { val leftSon = SimpleBSTVertex('1', "!", SimpleBSTVertex('0', ")"), SimpleBSTVertex('2', "@")) return TestTree(SimpleBSTVertex('3', "#", leftSon, null), 4L) } - @Test + @Test fun `getMax() returns correct value when root has only left son`() { val tree = makeTreeWithOnlyLeftRootSSon() assert(tree.getMax() == "#") } - private fun makeTreeWithOnlyRightRootSSon() : TestTree { + private fun makeTreeWithOnlyRightRootSSon(): TestTree { val rightSon = SimpleBSTVertex('6', "^", SimpleBSTVertex('5', "%"), SimpleBSTVertex('8', "*")) return TestTree(SimpleBSTVertex('3', "#", null, rightSon), 4L) } - @Test + @Test fun `getMin() returns correct value when root has only right son`() { val tree = makeTreeWithOnlyRightRootSSon() assert(tree.getMin() == "#") @@ -161,14 +162,14 @@ class AbstractTreeTest { @Test fun `removeAndReturnPair() returns null when remove() returned null`() { - val tree = TestTree(removeShouldReturns = null) + val tree = TestTree(removeShouldReturns = null) assertNull(tree.removeAndReturnPair(1)) } @Test fun `removeAndReturnPair() returns (given key) to (value that remove() returned) pair`() { val tree = TestTree(removeShouldReturns = '1') - assert (tree.removeAndReturnPair(3) == (3 to '1')) + assert(tree.removeAndReturnPair(3) == (3 to '1')) } @Test @@ -176,7 +177,7 @@ class AbstractTreeTest { val tree = TestTree() val map = hashMapOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'a' to 'A') tree.putAll(map) - for (pair in map) + for (pair in map) assertNotNull(tree.putWasCalledWithParams.remove(Triple(pair.component1(), pair.component2(), true))) } @@ -185,60 +186,64 @@ class AbstractTreeTest { val tree = TestTree() val map = hashMapOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'a' to 'A') tree.putAll(map, false) - for (pair in map) + for (pair in map) assertNotNull(tree.putWasCalledWithParams.remove(Triple(pair.component1(), pair.component2(), false))) } - @Test + @Test fun `compareKeys return 1 when key1 larger than key2 (keys are comparable)`() { val tree = TestTree() - assert (tree.compareKeysT(18, 14) == 1) + assert(tree.compareKeysT(18, 14) == 1) } - @Test + @Test fun `compareKeys return 0 when key1 equals key2 (keys are comparable)`() { val tree = TestTree() - assert (tree.compareKeysT(18, 18) == 0) + assert(tree.compareKeysT(18, 18) == 0) } - @Test + @Test fun `compareKeys return -1 when key1 lesser than key2 (keys are comparable)`() { val tree = TestTree() - assert (tree.compareKeysT(14, 18) == -1) + assert(tree.compareKeysT(14, 18) == -1) } - - class cmp : Comparator { - override fun compare(o1 : IntArray, o2 : IntArray) : Int { + + class CMP : Comparator { + override fun compare( + o1: IntArray, + o2: IntArray, + ): Int { return o1.sum() - o2.sum() } } - - @Test + @Test fun `compareKeys return 1 when key1 larger than key2 (comparator was given)`() { - val tree = TestTree(cmp()) - assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(-1)) == 1) + val tree = TestTree(CMP()) + assert(tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(-1)) == 1) } - @Test + @Test fun `compareKeys return 0 when key1 equals key2 (comparator was given)`() { - val tree = TestTree(cmp()) - assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(0)) == 0) + val tree = TestTree(CMP()) + assert(tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(0)) == 0) } - @Test + @Test fun `compareKeys return -1 when key1 lesser than key2 (comparator was given)`() { - val tree = TestTree(cmp()) - assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1)) == -1) + val tree = TestTree(CMP()) + assert(tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1)) == -1) } - - + @Test fun `compareKeys fall when keys type doesn't implement compareble && comparator wasn't given`() { var didItFall = false val tree = TestTree() - try {tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1))} - catch (e : Exception) {didItFall = true} + try { + tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1)) + } catch (e: Exception) { + didItFall = true + } assert(didItFall) } } diff --git a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt new file mode 100644 index 0000000..92c6e16 --- /dev/null +++ b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt @@ -0,0 +1,46 @@ +package trees.abstractTree + +import main.trees.AbstractBinarySearchTree +import main.vertexes.SimpleBSTVertex + +class TestTree : AbstractBinarySearchTree> { + var removeShouldReturns: V? = null + var getShouldReturns: V? = null + val putWasCalledWithParams: MutableList> = mutableListOf() + + override fun put( + key: K, + value: V, + replaceIfExists: Boolean, + ) { + putWasCalledWithParams.add(Triple(key, value, replaceIfExists)) + } + + override fun remove(key: K): V? { + return removeShouldReturns + } + + fun compareKeysT( + firstKey: K, + secondKey: K, + ): Int { + return super.compareKeys(firstKey, secondKey) + } + constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : + super(comparator) { + this.root = root + this.size = size + } + + constructor (removeShouldReturns: V?) : super() { + this.removeShouldReturns = removeShouldReturns + } + + constructor (comparator: Comparator? = null) : super(comparator) + + constructor ( + map: Map, + replaceIfExists: Boolean = true, + comparator: Comparator? = null, + ) : super(map, replaceIfExists, comparator) +} diff --git a/lib/src/test/kotlin/trees/AVLTree/AVLTreeForTest.kt b/lib/src/test/kotlin/trees/avlTree/AVLTreeForTest.kt similarity index 99% rename from lib/src/test/kotlin/trees/AVLTree/AVLTreeForTest.kt rename to lib/src/test/kotlin/trees/avlTree/AVLTreeForTest.kt index 9f65a1c..c12b9be 100644 --- a/lib/src/test/kotlin/trees/AVLTree/AVLTreeForTest.kt +++ b/lib/src/test/kotlin/trees/avlTree/AVLTreeForTest.kt @@ -1,4 +1,4 @@ -package trees.AVLTree +package trees.avlTree import main.trees.AVLSearchTree import main.vertexes.AVLVertex diff --git a/lib/src/test/kotlin/trees/AVLTree/AVLTreeTest.kt b/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt similarity index 99% rename from lib/src/test/kotlin/trees/AVLTree/AVLTreeTest.kt rename to lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt index 41fa4be..005051a 100644 --- a/lib/src/test/kotlin/trees/AVLTree/AVLTreeTest.kt +++ b/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt @@ -1,4 +1,4 @@ -package trees.AVLTree + package trees.avlTree import main.vertexes.AVLVertex import org.junit.jupiter.api.Test @@ -600,7 +600,7 @@ class AVLTreeTest { } @Test - fun `remove fun return null if entry's key isn't exists`() { + fun `remove fun return null if entry's key isn't exists(1)`() { val tree = makeSize1Tree() assert(tree.remove('a') == null) } @@ -1027,6 +1027,12 @@ class AVLTreeTest { tree.remove('u') assert(isSonsHeightDiffCorrect(tree)) } + + @Test + fun `remove fun return null if entry's key isn't exists(2)`() { + val tree = makeTreeForRemoveSonWithBothSons() + assert(tree.remove('x') == null) + } private fun makeTreeForRemoveRootWithBothSonsTest(): AVLTreeForTest { val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), AVLVertex('e', 5), 0) diff --git a/lib/src/test/kotlin/trees/RBSearchTree/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt similarity index 99% rename from lib/src/test/kotlin/trees/RBSearchTree/RBSearchTreeTest.kt rename to lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt index f392e81..8bba833 100644 --- a/lib/src/test/kotlin/trees/RBSearchTree/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt @@ -1,4 +1,4 @@ -package trees.RBSearchTree +package trees.rbTree import main.trees.RBSearchTree import org.junit.jupiter.api.AfterEach diff --git a/lib/src/test/kotlin/trees/SimpleBSTree/SimpleBSTreeTest.kt b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt similarity index 82% rename from lib/src/test/kotlin/trees/SimpleBSTree/SimpleBSTreeTest.kt rename to lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt index 99e91f1..0608dd2 100644 --- a/lib/src/test/kotlin/trees/SimpleBSTree/SimpleBSTreeTest.kt +++ b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt @@ -1,4 +1,4 @@ -package trees.SimpleBSTree +package trees.simpleBSTree import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -6,6 +6,7 @@ import kotlin.test.assertEquals class SimpleBSTreeTest { private lateinit var tree: TestSimpleBST + @BeforeEach fun setup() { tree = TestSimpleBST() @@ -53,7 +54,7 @@ class SimpleBSTreeTest { @Test fun `put many vertexes test`() { tree.put(0, "hello") - for (key in 1 .. 6) { + for (key in 1..6) { tree.put(key, "hello") } assertEquals(7, tree.size()) @@ -61,13 +62,16 @@ class SimpleBSTreeTest { @Test fun `put many vertexes with method putAll() test`() { - tree.putAll(mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two"))) + tree.putAll( + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two"), + ), + ) assertEquals(6, tree.size()) } @@ -121,14 +125,16 @@ class SimpleBSTreeTest { @Test fun `remove two sons with right subtree vertex test`() { - tree.putAll(mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") - )) + tree.putAll( + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two"), + ), + ) tree.remove(1) assertEquals(2, tree.getTreeRoot()?.key) assertEquals(5, tree.size()) @@ -136,14 +142,16 @@ class SimpleBSTreeTest { @Test fun `remove many vertex test`() { - tree.putAll(mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two") - )) + tree.putAll( + mapOf( + Pair(1, "one"), + Pair(4, "four"), + Pair(0, "zero"), + Pair(3, "three"), + Pair(5, "five"), + Pair(2, "two"), + ), + ) for (key in 0..5) { tree.remove(key) } @@ -168,4 +176,4 @@ class SimpleBSTreeTest { assertEquals("two", tree.getTreeRoot()?.value) assertEquals(1, tree.size()) } -} \ No newline at end of file +} diff --git a/lib/src/test/kotlin/trees/SimpleBSTree/TestSimpleBST.kt b/lib/src/test/kotlin/trees/simpleBSTree/TestSimpleBST.kt similarity index 75% rename from lib/src/test/kotlin/trees/SimpleBSTree/TestSimpleBST.kt rename to lib/src/test/kotlin/trees/simpleBSTree/TestSimpleBST.kt index 26e32f1..b80da47 100644 --- a/lib/src/test/kotlin/trees/SimpleBSTree/TestSimpleBST.kt +++ b/lib/src/test/kotlin/trees/simpleBSTree/TestSimpleBST.kt @@ -1,4 +1,4 @@ -package trees.SimpleBSTree +package trees.simpleBSTree import main.trees.SimpleBinarySearchTree import main.vertexes.SimpleBSTVertex @@ -9,6 +9,6 @@ class TestSimpleBST : SimpleBinarySearchTree { } constructor(comparator: Comparator? = null) : super(comparator) - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) - : super(map, replaceIfExists, comparator) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : + super(map, replaceIfExists, comparator) } From 1fef4f542be94ae903892f919b48e75d1026adb5 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 2 Apr 2024 21:14:39 +0300 Subject: [PATCH 170/227] style: final changes according to linter --- lib/src/test/kotlin/trees/abstractTree/TestTree.kt | 6 +++--- lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt index 92c6e16..74963f8 100644 --- a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt +++ b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt @@ -28,9 +28,9 @@ class TestTree : AbstractBinarySearchTree> { } constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : super(comparator) { - this.root = root - this.size = size - } + this.root = root + this.size = size + } constructor (removeShouldReturns: V?) : super() { this.removeShouldReturns = removeShouldReturns diff --git a/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt b/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt index 005051a..38b1df9 100644 --- a/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt +++ b/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt @@ -1,4 +1,4 @@ - package trees.avlTree +package trees.avlTree import main.vertexes.AVLVertex import org.junit.jupiter.api.Test @@ -1027,8 +1027,8 @@ class AVLTreeTest { tree.remove('u') assert(isSonsHeightDiffCorrect(tree)) } - - @Test + + @Test fun `remove fun return null if entry's key isn't exists(2)`() { val tree = makeTreeForRemoveSonWithBothSons() assert(tree.remove('x') == null) From 5abc7ba2051712b9a51c23776dd9bee722359f24 Mon Sep 17 00:00:00 2001 From: Kostya Date: Wed, 3 Apr 2024 13:15:09 +0300 Subject: [PATCH 171/227] test: add one more test --- lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt index 8bba833..3fdde9c 100644 --- a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt @@ -113,6 +113,13 @@ class RBSearchTreeTest { expectedResult = listOf(Pair(7, "hi")) } + @Test + fun `remove root`() { + rbTree.put(7, "hi") + rbTree.remove(7) + expectedResult = listOf() + } + @Test fun `delete red vertex with 0 children`() { rbTree.put(7, "hi") From 65bbc1673595c07c3450c6ff24752930ba900511 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Wed, 3 Apr 2024 09:03:16 +0300 Subject: [PATCH 172/227] feat: update tests for SimpleBST --- .../trees/simpleBSTree/SimpleBSTreeTest.kt | 391 +++++++++++++----- 1 file changed, 286 insertions(+), 105 deletions(-) diff --git a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt index 0608dd2..9cd15fd 100644 --- a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt +++ b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt @@ -13,167 +13,348 @@ class SimpleBSTreeTest { } @Test - fun `replacing value of existing key`() { - tree.put(1, "old") - tree.put(1, "new", true) - assertEquals("new", tree.getTreeRoot()?.value) - assertEquals(1, tree.size()) + fun `create tree from map`() { + val map = mapOf(Pair(1, "cat"), Pair(2, "rabbit")) + val tree = TestSimpleBST(map, true) + + assertEquals("cat", tree.getTreeRoot()?.value) + assertEquals("rabbit", tree.getTreeRoot()?.rightSon?.value) + assertEquals(2L, tree.size()) } + // put @Test - fun `create tree from a map`() { - val tree = TestSimpleBST(mapOf(Pair(1, "cat"), Pair(2, "dog"))) - assertEquals("cat", tree.getTreeRoot()?.value) - assertEquals(2, tree.size()) + fun `put key-value pair to empty tree`() { + tree.put(1, "meow") + + assertEquals("meow", tree.getTreeRoot()?.value) + assertEquals(1L, tree.size()) } @Test - fun `non replacing value of existing key`() { + fun `put existing key and do not replace it`() { tree.put(1, "old") tree.put(1, "new", false) + assertEquals("old", tree.getTreeRoot()?.value) - assertEquals(1, tree.size()) + assertEquals(1L, tree.size()) } @Test - fun `put key more than root key test`() { + fun `put existing key and replace it`() { + tree.put(1, "old") + tree.put(1, "new", true) + + assertEquals("new", tree.getTreeRoot()?.value) + assertEquals(1L, tree.size()) + } + + @Test + fun `put key smaller than root key`() { tree.put(1, "one") - tree.put(2, "right") - assertEquals("right", tree.getTreeRoot()?.rightSon?.value) - assertEquals(2, tree.size()) + tree.put(0, "zero") + +// 1 +// ^ +// 0 null + + assertEquals("zero", tree.getTreeRoot()?.leftSon?.value) + assertEquals(2L, tree.size()) } @Test - fun `put key less than root key test`() { + fun `put key smaller than root key, leftSon != null and replace existing key`() { + tree.put(3, "three", true) + tree.put(2, "two dogs", true) + tree.put(2, "two cats", true) + tree.put(1, "one", true) + +// 3 +// ^ +// 2 null +// ^ +// 1 null + + assertEquals("three", tree.getTreeRoot()?.value) + assertEquals("two cats", tree.getTreeRoot()?.leftSon?.value) + assertEquals("one", tree.getTreeRoot()?.leftSon?.leftSon?.value) + assertEquals(3L, tree.size()) + } + + @Test + fun `put key smaller than root key and leftSon != null and do not replace existing key`() { + tree.put(3, "three", false) + tree.put(2, "two dogs", false) + tree.put(2, "two cats", false) + tree.put(1, "one", false) + +// 3 +// ^ +// 2 null +// ^ +// 1 null + + assertEquals("three", tree.getTreeRoot()?.value) + assertEquals("two dogs", tree.getTreeRoot()?.leftSon?.value) + assertEquals("one", tree.getTreeRoot()?.leftSon?.leftSon?.value) + assertEquals(3, tree.size()) + } + + @Test + fun `put key more than root key`() { tree.put(1, "one") - tree.put(0, "left") - assertEquals("left", tree.getTreeRoot()?.leftSon?.value) + tree.put(2, "two") + + assertEquals("two", tree.getTreeRoot()?.rightSon?.value) assertEquals(2, tree.size()) } @Test - fun `put many vertexes test`() { - tree.put(0, "hello") - for (key in 1..6) { - tree.put(key, "hello") - } - assertEquals(7, tree.size()) + fun `put key more than root key, rightSon != null and replace existing key`() { + tree.put(1, "one", true) + tree.put(2, "two parrots", true) + tree.put(2, "two rabbits", true) + tree.put(3, "three", true) + +// 1 +// ^ +// null 2 +// ^ +// null 3 + + assertEquals("one", tree.getTreeRoot()?.value) + assertEquals("two rabbits", tree.getTreeRoot()?.rightSon?.value) + assertEquals("three", tree.getTreeRoot()?.rightSon?.rightSon?.value) + assertEquals(3, tree.size()) } @Test - fun `put many vertexes with method putAll() test`() { - tree.putAll( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two"), - ), - ) - assertEquals(6, tree.size()) + fun `put key more than root key, rightSon != null and do not replace existing key`() { + tree.put(1, "one", false) + tree.put(2, "two parrots", false) + tree.put(2, "two rabbits", false) + tree.put(3, "three",false) + +// 1 +// ^ +// null 2 +// ^ +// null 3 + + assertEquals("one", tree.getTreeRoot()?.value) + assertEquals("two parrots", tree.getTreeRoot()?.rightSon?.value) + assertEquals("three", tree.getTreeRoot()?.rightSon?.rightSon?.value) + assertEquals(3, tree.size()) } + // remove @Test - fun `put many vertexes with same key test`() { - for (i in 1..6) { - tree.put(1, "one") - } - assertEquals(1, tree.size()) + fun `remove vertex with null key from empty tree`() { + val tree: TestSimpleBST = TestSimpleBST() + val returned = tree.remove(null) + assertEquals(null, tree.getTreeRoot()) + assertEquals(null, returned) + assertEquals(0, tree.size()) } @Test - fun `remove no sons root test`() { - tree.put(1, "one") - tree.remove(1) + fun `remove root vertex without sons`() { + tree.put(5, "five") + val returned = tree.remove(5) assertEquals(null, tree.getTreeRoot()) + assertEquals("five", returned) assertEquals(0, tree.size()) } @Test - fun `remove no sons vertex test`() { - tree.putAll(mapOf(Pair(1, "one"), Pair(0, "zero"))) - tree.remove(0) - assertEquals(null, tree.getTreeRoot()?.leftSon) + fun `remove root vertex with one left son`() { + tree.putAll(mapOf(Pair(5, "five"), Pair(0, "zero"))) + +// 5 +// ^ +// 0 null +// ^ +// null null + + val returned = tree.remove(5) + assertEquals("zero", tree.getTreeRoot()?.value) + assertEquals("five", returned) assertEquals(1, tree.size()) } @Test - fun `remove one left son vertex test`() { - tree.putAll(mapOf(Pair(1, "one"), Pair(0, "zero"), Pair(-1, "negative"))) - tree.remove(0) - assertEquals(-1, tree.getTreeRoot()?.leftSon?.key) - assertEquals(2, tree.size()) + fun `remove root vertex with one right son`() { + tree.putAll(mapOf(Pair(5, "five"), Pair(6, "six"))) + +// 5 +// ^ +// null 6 +// ^ +// null null + + val returned = tree.remove(5) + assertEquals("six", tree.getTreeRoot()?.value) + assertEquals("five", returned) + assertEquals(1, tree.size()) + } + + @Test + fun `remove vertex with smaller key, vertex has not sons`() { + tree.putAll(mapOf(Pair(5, "five"), Pair(0, "zero"))) + +// 5 +// ^ +// 0 null +// ^ +// null null + + val returned = tree.remove(0) + assertEquals("five", tree.getTreeRoot()?.value) + assertEquals("zero", returned) + assertEquals(1, tree.size()) } @Test - fun `remove one right son vertex test`() { - tree.putAll(mapOf(Pair(1, "one"), Pair(2, "two"), Pair(3, "three"))) - tree.remove(2) - assertEquals(3, tree.getTreeRoot()?.rightSon?.key) + fun `remove vertex with smaller key, vertex has one right son`() { + tree.putAll(mapOf( + Pair(5, "five"), + Pair(0, "zero"), + Pair(4, "four"))) + +// 5 +// ^ +// 0 null +// ^ +// null 4 + + val returned = tree.remove(0) + assertEquals("five", tree.getTreeRoot()?.value) + assertEquals("four", tree.getTreeRoot()?.leftSon?.value) + assertEquals("zero", returned) assertEquals(2, tree.size()) } @Test - fun `remove two sons vertex test`() { - tree.putAll(mapOf(Pair(1, "one"), Pair(2, "two"), Pair(0, "zero"))) - tree.remove(1) - assertEquals(2, tree.getTreeRoot()?.key) + fun `remove vertex with smaller key, vertex has one left son`() { + tree.putAll(mapOf( + Pair(5, "five"), + Pair(0, "zero"), + Pair(-1, "minus_one"))) + +// 5 +// ^ +// 0 null +// ^ +// -1 null + + val returned = tree.remove(0) + assertEquals("five", tree.getTreeRoot()?.value) + assertEquals("minus_one", tree.getTreeRoot()?.leftSon?.value) + assertEquals("zero", returned) assertEquals(2, tree.size()) } @Test - fun `remove two sons with right subtree vertex test`() { - tree.putAll( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two"), - ), - ) - tree.remove(1) - assertEquals(2, tree.getTreeRoot()?.key) - assertEquals(5, tree.size()) - } - - @Test - fun `remove many vertex test`() { - tree.putAll( - mapOf( - Pair(1, "one"), - Pair(4, "four"), - Pair(0, "zero"), - Pair(3, "three"), - Pair(5, "five"), - Pair(2, "two"), - ), - ) - for (key in 0..5) { - tree.remove(key) - } - assertEquals(null, tree.getTreeRoot()) - assertEquals(0, tree.size()) + fun `remove vertex with smaller key, vertex has two sons`() { + tree.putAll(mapOf( + Pair(5, "five"), + Pair(0, "zero"), + Pair(-1, "minus_one"), + Pair(4, "four"), + Pair(3, "three"))) + +// 5 +// ^ +// 0 null +// ^ +// -1 4 +// ^ +// 3 null + + val returned = tree.remove(0) + assertEquals("five", tree.getTreeRoot()?.value) + assertEquals("three", tree.getTreeRoot()?.leftSon?.value) + assertEquals("zero", returned) + assertEquals(4, tree.size()) } @Test - fun `remove non-existing value`() { - tree.put(1, "one") - val deletedValue = tree.remove(100) - assertEquals(null, deletedValue) + fun `remove vertex with more key, vertex has not sons`() { + tree.putAll(mapOf(Pair(1, "one"), Pair(5, "five"))) + +// 1 +// ^ +// null 5 + + val returned = tree.remove(5) + assertEquals("one", tree.getTreeRoot()?.value) + assertEquals("five", returned) assertEquals(1, tree.size()) } @Test - fun `put vertex after remove root test`() { - tree.put(1, "one") - val deletedValue = tree.remove(1) - assertEquals("one", deletedValue) - tree.put(2, "two") - assertEquals("two", tree.getTreeRoot()?.value) - assertEquals(1, tree.size()) + fun `remove vertex with more key, vertex has one left son`() { + tree.putAll(mapOf(Pair(1, "one"), Pair(5, "five"), Pair(2, "two"))) + +// 1 +// ^ +// null 5 +// ^ +// 2 null + + val returned = tree.remove(5) + assertEquals("one", tree.getTreeRoot()?.value) + assertEquals("two", tree.getTreeRoot()?.rightSon?.value) + assertEquals("five", returned) + assertEquals(2L, tree.size()) + } + + @Test + fun `remove vertex with more key, vertex has one right son`() { + tree.putAll(mapOf(Pair(1, "one"), Pair(5, "five"), Pair(10, "ten"))) + +// 1 +// ^ +// null 5 +// ^ +// null 10 + + val returned = tree.remove(5) + assertEquals("one", tree.getTreeRoot()?.value) + assertEquals("ten", tree.getTreeRoot()?.rightSon?.value) + assertEquals("five", returned) + assertEquals(2L, tree.size()) + } + + @Test + fun `remove vertex with more key, vertex has two sons`() { + tree.putAll(mapOf( + Pair(1, "one"), + Pair(5, "five"), + Pair(10, "ten"), + Pair(2, "two"), + Pair(6, "six"))) + +// 1 +// ^ +// null 5 +// ^ +// 2 10 +// ^ +// 6 null + + val returned = tree.remove(5) + assertEquals("one", tree.getTreeRoot()?.value) + assertEquals("six", tree.getTreeRoot()?.rightSon?.value) + assertEquals("five", returned) + assertEquals(4L, tree.size()) + } + + @Test + fun `remove vertex with non-existing key`() { + tree.put(1, "cat") + tree.remove(6) + + assertEquals(1L, tree.size()) } } From d63e8535afd8edfe1a86f3637896f82cce081d7c Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Wed, 3 Apr 2024 09:10:44 +0300 Subject: [PATCH 173/227] fix: move check for null root to removeRec() method and remove default initialization of replaceIfExists parameter --- lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index 14c124c..3d0e85a 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -37,10 +37,6 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree : AbstractBinarySearchTree? = root, ) { - if (vertex == null) return + if (vertex == null) { + root = SimpleBSTVertex(key, value) + size++ + return + } when (compareKeys(key, vertex.key)) { 0 -> if (replaceIfExists) vertex.value = value -1 -> { From 28e9ebb33548f3a76d43a5323e6f025464ef3e2e Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Wed, 3 Apr 2024 18:57:05 +0300 Subject: [PATCH 174/227] style: changes according to linter --- .../trees/simpleBSTree/SimpleBSTreeTest.kt | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt index 9cd15fd..47a9e24 100644 --- a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt +++ b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt @@ -133,7 +133,7 @@ class SimpleBSTreeTest { tree.put(1, "one", false) tree.put(2, "two parrots", false) tree.put(2, "two rabbits", false) - tree.put(3, "three",false) + tree.put(3, "three", false) // 1 // ^ @@ -216,10 +216,13 @@ class SimpleBSTreeTest { @Test fun `remove vertex with smaller key, vertex has one right son`() { - tree.putAll(mapOf( - Pair(5, "five"), - Pair(0, "zero"), - Pair(4, "four"))) + tree.putAll( + mapOf( + Pair(5, "five"), + Pair(0, "zero"), + Pair(4, "four") + ) + ) // 5 // ^ @@ -236,10 +239,13 @@ class SimpleBSTreeTest { @Test fun `remove vertex with smaller key, vertex has one left son`() { - tree.putAll(mapOf( - Pair(5, "five"), - Pair(0, "zero"), - Pair(-1, "minus_one"))) + tree.putAll( + mapOf( + Pair(5, "five"), + Pair(0, "zero"), + Pair(-1, "minus_one") + ) + ) // 5 // ^ @@ -256,12 +262,15 @@ class SimpleBSTreeTest { @Test fun `remove vertex with smaller key, vertex has two sons`() { - tree.putAll(mapOf( - Pair(5, "five"), - Pair(0, "zero"), - Pair(-1, "minus_one"), - Pair(4, "four"), - Pair(3, "three"))) + tree.putAll( + mapOf( + Pair(5, "five"), + Pair(0, "zero"), + Pair(-1, "minus_one"), + Pair(4, "four"), + Pair(3, "three") + ) + ) // 5 // ^ @@ -328,12 +337,15 @@ class SimpleBSTreeTest { @Test fun `remove vertex with more key, vertex has two sons`() { - tree.putAll(mapOf( - Pair(1, "one"), - Pair(5, "five"), - Pair(10, "ten"), - Pair(2, "two"), - Pair(6, "six"))) + tree.putAll( + mapOf( + Pair(1, "one"), + Pair(5, "five"), + Pair(10, "ten"), + Pair(2, "two"), + Pair(6, "six") + ) + ) // 1 // ^ From 46945b391e19932c0bdc1675b7852c09304eabd2 Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Wed, 3 Apr 2024 20:59:56 +0300 Subject: [PATCH 175/227] fix: correct AVLTree rotate functions' documentation --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 2587aa5..506b569 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -325,14 +325,14 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Balances the tree starting from the specified vertex. - * @param curVertex the current vertex to start balancing from - * @return the root vertex of the tree after balancing + * Balances the subtree. + * @param curVertex the root vertex of subtree to be balanced + * @return the root vertex of the subtree after balancing */ private fun balance(curVertex: AVLVertex): AVLVertex { var (rightSon, leftSon) = List?>(2) { null } - fun setTwoSonHeightDiffs(values: Pair) { + fun setSonSHeightDiffsOfTwoVerteces(values: Pair) { curVertex.sonsHeightDiff = values.component1() if (rightSon != null) { (rightSon as AVLVertex).sonsHeightDiff = values.component2() @@ -346,7 +346,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> return if (rightSon.sonsHeightDiff == 1) { val rightSonSLeftSon = rightSon.leftSon as AVLVertex val subtreeRoot = bigRotateLeft(curVertex, rightSon) - setTwoSonHeightDiffs( + setSonSHeightDiffsOfTwoVerteces( when (rightSonSLeftSon.sonsHeightDiff) { 1 -> 0 to -1 -1 -> 1 to 0 @@ -357,7 +357,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> subtreeRoot } else { val subtreeRoot = rotateLeft(curVertex, rightSon) - setTwoSonHeightDiffs( + setSonSHeightDiffsOfTwoVerteces( if (rightSon.sonsHeightDiff == 0) { -1 to 1 } else { @@ -371,7 +371,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> return if (leftSon.sonsHeightDiff == -1) { val leftSonSRightSon = leftSon.rightSon as AVLVertex val subtreeRoot = bigRotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( + setSonSHeightDiffsOfTwoVerteces( when (leftSonSRightSon.sonsHeightDiff) { -1 -> 0 to 1 1 -> -1 to 0 @@ -382,7 +382,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> subtreeRoot } else { val subtreeRoot = rotateRight(curVertex, leftSon) - setTwoSonHeightDiffs( + setSonSHeightDiffsOfTwoVerteces( if (leftSon.sonsHeightDiff == 0) { 1 to -1 } else { @@ -394,10 +394,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Performs a single left rotation around the specified vertices. - * @param curVertex the current vertex to rotate around - * @param rightSon the right son vertex - * @return the new root vertex after rotation + * Performs a single left rotation of the subtree. + * @param curVertex the current vertex to rotate around (the subtree's root) + * @param rightSon the right son of the subtree's root + * @return the new root of the subtree after rotation */ private fun rotateLeft( curVertex: AVLVertex, @@ -409,10 +409,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Performs a single right rotation around the specified vertices. - * @param curVertex the current vertex to rotate around - * @param leftSon the left son vertex - * @return the new root vertex after rotation + * Performs a single right rotation of the subtree. + * @param curVertex the current vertex to rotate around (the subtree's root) + * @param leftSon the left son of the subtree's root + * @return the new root of the subtree after rotation */ private fun rotateRight( curVertex: AVLVertex, @@ -424,10 +424,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Performs a big left rotation around the specified vertices. - * @param curVertex the current vertex to rotate around - * @param rightSon the right son vertex - * @return the new root vertex after rotation + * Performs a big left rotation of the subtree. + * @param curVertex the current vertex to rotate around (the subtree's root) + * @param rightSon the right son of the subtree's root + * @return the new root of the subtree after rotation */ private fun bigRotateLeft( curVertex: AVLVertex, @@ -439,10 +439,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Performs a big right rotation around the specified vertices. - * @param curVertex the current vertex to rotate around - * @param leftSon the left son vertex - * @return the new root vertex after rotation + * Performs a big right rotation of the subtree. + * @param curVertex the current vertex to rotate around (the subtree's root) + * @param leftSon the left son vertex of the subtree's root + * @return the new root root of the subtree after rotation */ private fun bigRotateRight( curVertex: AVLVertex, From 0d85520d4f0f7689c22ee13416efa58b2c4659d7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 6 Apr 2024 14:21:20 +0300 Subject: [PATCH 176/227] feat(AbstractTree) : add isNotEmpty() method --- lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index 76c04ef..82daf23 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -59,6 +59,10 @@ abstract class AbstractBinarySearchTree> { return size == 0L } + fun isNotEmpty(): Boolean { + return size != 0L + } + /** * Returns the value associated with the specified key in this tree. * If the key is not found, returns null. From 025a838d038dd24e02c38e43e220c2aa582a49bf Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:04:24 +0300 Subject: [PATCH 177/227] feat: add test coverage --- .github/workflows/ci.yml | 2 ++ .github/workflows/coverage.yml | 45 ++++++++++++++++++++++++++++++++++ .github/workflows/ktlint.yml | 2 ++ 3 files changed, 49 insertions(+) create mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25f9bf2..d0342fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,10 +5,12 @@ on: branches: - main - develop + - fixes-after-1st-review push: branches: - main - develop + - fixes-after-1st-review workflow_dispatch: jobs: diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..dfa67a9 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,45 @@ +name: Jacoco coverage + +on: + pull_request: + branches: + - main + - develop + - fixes-after-1st-review + push: + branches: + - main + - develop + - fixes-after-1st-review + workflow_dispatch: + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Java JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + cache: gradle + distribution: "temurin" + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v3 + - name: Run Coverage + run: | + chmod +x gradlew + ./gradlew testCoverage + - name: Add coverage to PR + id: jacoco + uses: madrapps/jacoco-report@v1.6.1 + with: + paths: | + ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, + ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 40 + min-coverage-changed-files: 60 + pass-emoji: 💪 + fail-emoji: 🤡 \ No newline at end of file diff --git a/.github/workflows/ktlint.yml b/.github/workflows/ktlint.yml index 8fcfbd4..f58f9f6 100644 --- a/.github/workflows/ktlint.yml +++ b/.github/workflows/ktlint.yml @@ -5,10 +5,12 @@ on: branches: - main - develop + - fixes-after-1st-review push: branches: - main - develop + - fixes-after-1st-review workflow_dispatch: jobs: From 92080c1a100457f9c2499838cedaa8232a9e65a1 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:08:41 +0300 Subject: [PATCH 178/227] fix: delete extra code --- .github/workflows/coverage.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index dfa67a9..0004a55 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -28,9 +28,7 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 - name: Run Coverage - run: | - chmod +x gradlew - ./gradlew testCoverage + run: ./gradlew testCoverage - name: Add coverage to PR id: jacoco uses: madrapps/jacoco-report@v1.6.1 From 166b79a1ec73ce89c4c57c6c3a504f291ecb42c3 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:16:23 +0300 Subject: [PATCH 179/227] fix: change name of reports --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0004a55..0877d56 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -28,7 +28,7 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 - name: Run Coverage - run: ./gradlew testCoverage + run: ./gradlew jacocoTestReport - name: Add coverage to PR id: jacoco uses: madrapps/jacoco-report@v1.6.1 From e4274a93f5d6ea5e75a76307c21227c7ae993ce2 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:22:46 +0300 Subject: [PATCH 180/227] fix: add permissions --- .github/workflows/coverage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0877d56..00d7878 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -16,6 +16,8 @@ on: jobs: coverage: runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - name: Checkout repository uses: actions/checkout@v4 From 2705e136305988d5c978a50e2cfc4a1138aae087 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:39:18 +0300 Subject: [PATCH 181/227] feat: add emoji on tests --- .github/workflows/coverage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 00d7878..7b79dae 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -41,5 +41,5 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 40 min-coverage-changed-files: 60 - pass-emoji: 💪 - fail-emoji: 🤡 \ No newline at end of file + pass-emoji: ':partying_face:' + fail-emoji: ':clown_face:' \ No newline at end of file From d140a3f7d02338b6f8fcbf098a1d041cf70f5860 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:50:25 +0300 Subject: [PATCH 182/227] feat: add test report --- .github/workflows/ci.yml | 4 ++++ .github/workflows/coverage.yml | 15 ++++++++++++--- lib/build.gradle.kts | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0342fa..c2df060 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,15 +19,19 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up Java JDK uses: actions/setup-java@v4 with: java-version: 17 cache: gradle distribution: "temurin" + - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 + - name: Build with Gradle run: ./gradlew build + - name: Run tests run: ./gradlew test diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7b79dae..36663ab 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -21,16 +21,25 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up Java JDK uses: actions/setup-java@v4 with: java-version: 17 - cache: gradle distribution: "temurin" + - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 + - name: Run Coverage run: ./gradlew jacocoTestReport + + - name: Generate JaCoCo Badge + uses: cicirello/jacoco-badge-generator@v2 + with: + generate-branches-badge: true + jacoco-csv-file: build/reports/jacoco/test/jacocoTestReport.csv + - name: Add coverage to PR id: jacoco uses: madrapps/jacoco-report@v1.6.1 @@ -41,5 +50,5 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 40 min-coverage-changed-files: 60 - pass-emoji: ':partying_face:' - fail-emoji: ':clown_face:' \ No newline at end of file + pass-emoji: '🥳' + fail-emoji: '🤡' \ No newline at end of file diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index dcb7919..aa9fc85 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -48,7 +48,7 @@ tasks.named("test") { tasks.named("jacocoTestReport") { dependsOn(tasks.test) reports { - csv.required = false + csv.required = true xml.required = false html.outputLocation = layout.buildDirectory.dir("jacocoHtml") } From 15caf8a96ad7f1b2bb00782ee396ad38c4cd68d4 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:06:08 +0300 Subject: [PATCH 183/227] fix: change path to csv --- .github/workflows/coverage.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 36663ab..d55eb74 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -34,11 +34,11 @@ jobs: - name: Run Coverage run: ./gradlew jacocoTestReport - - name: Generate JaCoCo Badge + - name: Generate JaCoCo Report uses: cicirello/jacoco-badge-generator@v2 with: generate-branches-badge: true - jacoco-csv-file: build/reports/jacoco/test/jacocoTestReport.csv + jacoco-csv-file: lib/build/reports/jacoco/test/jacocoTestReport.csv - name: Add coverage to PR id: jacoco @@ -50,5 +50,4 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 40 min-coverage-changed-files: 60 - pass-emoji: '🥳' - fail-emoji: '🤡' \ No newline at end of file + \ No newline at end of file From b56cc5de85bcc19f12caa17a4302c054a4634ddd Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:11:19 +0300 Subject: [PATCH 184/227] feat: add emoji) --- .github/workflows/coverage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index d55eb74..bb43dfa 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -49,5 +49,5 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 40 - min-coverage-changed-files: 60 - \ No newline at end of file + pass-emoji: '🥳' + fail-emoji: '🤡' From 57b758b5e5f6a94a761daa1d025c690ffd142ca1 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:21:25 +0300 Subject: [PATCH 185/227] feat: add title of report --- .github/workflows/coverage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bb43dfa..0718b07 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,6 +48,8 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} + title: '# :lobster: Coverage Report' + update-comment: true min-coverage-overall: 40 pass-emoji: '🥳' fail-emoji: '🤡' From 56362496f2aa97fb0be1319f0a6662a054e864ac Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:26:03 +0300 Subject: [PATCH 186/227] feat: add skip case --- .github/workflows/coverage.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0718b07..b46c41b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,8 +48,9 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} - title: '# :lobster: Coverage Report' + title: '# 🇷🇺 Coverage Report' update-comment: true + skip-if-no-changes: true min-coverage-overall: 40 pass-emoji: '🥳' fail-emoji: '🤡' From f41871e2b93c4652e1e22daa7755202acd424159 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:31:32 +0300 Subject: [PATCH 187/227] test: comment some tests to see changes in report --- .github/workflows/coverage.yml | 2 +- .../kotlin/trees/rbTree/RBSearchTreeTest.kt | 390 +++++++++--------- 2 files changed, 196 insertions(+), 196 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b46c41b..50383f3 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,7 +48,7 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} - title: '# 🇷🇺 Coverage Report' + title: '# 5⃣2⃣ Coverage Report' update-comment: true skip-if-no-changes: true min-coverage-overall: 40 diff --git a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt index 3fdde9c..77258d6 100644 --- a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt @@ -178,201 +178,201 @@ class RBSearchTreeTest { ) } - @Test - fun `balance after remove - brother is right and black, brother's rightSon - red`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(3, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "chka") - rbTree.put(11, "Slim") - rbTree.put(13, "Shady") - rbTree.remove(9) - expectedResult = - listOf( - Pair(7, "hi"), - Pair(12, "chka"), - Pair(13, "Shady"), - Pair(10, "name"), - Pair(11, "Slim"), - Pair(4, "my"), - Pair(5, "chka"), - Pair(3, "is"), - ) - } - - @Test - fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(3, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "Slim") - rbTree.put(11, "Shady") - rbTree.remove(9) - expectedResult = - listOf( - Pair(7, "hi"), - Pair(11, "Shady"), - Pair(12, "Slim"), - Pair(10, "name"), - Pair(4, "my"), - Pair(5, "chka"), - Pair(3, "is"), - ) - } - - @Test - fun `balance after remove - brother is right and black, both sons - black`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(9, "is") - rbTree.put(12, "Slim") - rbTree.put(11, "Shady") - rbTree.remove(11) - - // now vertexes with keys 9 and 12 are black - rbTree.remove(9) - - expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) - } - - @Test - fun `balance after remove - right brother is red`() { - rbTree.put(60, "sixty") - rbTree.put(33, "thirty-three") - rbTree.put(84, "eighty-four") - rbTree.put(15, "fifteen") - rbTree.put(51, "fifty-one") - rbTree.put(65, "sixty-five") - rbTree.put(96, "ninety-six") - rbTree.put(34, "thirty-four") - rbTree.put(52, "Alblack") - rbTree.put(94, "ninety-four") - rbTree.put(97, "ninety-seven") - rbTree.put(95, "ninety-five") - - // now vertex with key 96 is red, with key 65 - black - rbTree.remove(65) - - expectedResult = - listOf( - Pair(60, "sixty"), - Pair(96, "ninety-six"), - Pair(97, "ninety-seven"), - Pair(94, "ninety-four"), - Pair(95, "ninety-five"), - Pair(84, "eighty-four"), - Pair(33, "thirty-three"), - Pair(51, "fifty-one"), - Pair(52, "Alblack"), - Pair(34, "thirty-four"), - Pair(15, "fifteen"), - ) - } - - @Test - fun `balance after remove - brother is left and black, brother's rightSon - red`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "chka") - rbTree.put(1, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(5) - expectedResult = - listOf( - Pair(7, "hi"), - Pair(10, "name"), - Pair(12, "chka"), - Pair(9, "chka"), - Pair(2, "is"), - Pair(4, "my"), - Pair(3, "Shady"), - Pair(1, "Slim"), - ) - } - - @Test - fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(5) - expectedResult = - listOf( - Pair(7, "hi"), - Pair(10, "name"), - Pair(12, "Slim"), - Pair(9, "chka"), - Pair(3, "Shady"), - Pair(4, "my"), - Pair(2, "is"), - ) - } - - @Test - fun `balance after remove - brother is left and black, both sons - black`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(3) - - // now vertexes with keys 2 and 5 are black - rbTree.remove(5) - - expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) - } - - @Test - fun `balance after remove - left brother is red`() { - rbTree.put(60, "sixty") - rbTree.put(33, "thirty-three") - rbTree.put(84, "eighty-four") - rbTree.put(15, "fifteen") - rbTree.put(51, "fifty-one") - rbTree.put(65, "sixty-five") - rbTree.put(96, "ninety-six") - rbTree.put(5, "five") - rbTree.put(27, "twenty-seven") - rbTree.put(61, "sixty-one") - rbTree.put(69, "sixty-nine") - rbTree.put(17, "seventeen") - - // now vertex with key 15 is red, with key 51 - black - rbTree.remove(51) - - expectedResult = - listOf( - Pair(60, "sixty"), - Pair(84, "eighty-four"), - Pair(96, "ninety-six"), - Pair(65, "sixty-five"), - Pair(69, "sixty-nine"), - Pair(61, "sixty-one"), - Pair(15, "fifteen"), - Pair(27, "twenty-seven"), - Pair(33, "thirty-three"), - Pair(17, "seventeen"), - Pair(5, "five"), - ) - } +// @Test +// fun `balance after remove - brother is right and black, brother's rightSon - red`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(3, "is") +// rbTree.put(5, "chka") +// rbTree.put(9, "chka") +// rbTree.put(12, "chka") +// rbTree.put(11, "Slim") +// rbTree.put(13, "Shady") +// rbTree.remove(9) +// expectedResult = +// listOf( +// Pair(7, "hi"), +// Pair(12, "chka"), +// Pair(13, "Shady"), +// Pair(10, "name"), +// Pair(11, "Slim"), +// Pair(4, "my"), +// Pair(5, "chka"), +// Pair(3, "is"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(3, "is") +// rbTree.put(5, "chka") +// rbTree.put(9, "chka") +// rbTree.put(12, "Slim") +// rbTree.put(11, "Shady") +// rbTree.remove(9) +// expectedResult = +// listOf( +// Pair(7, "hi"), +// Pair(11, "Shady"), +// Pair(12, "Slim"), +// Pair(10, "name"), +// Pair(4, "my"), +// Pair(5, "chka"), +// Pair(3, "is"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is right and black, both sons - black`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(9, "is") +// rbTree.put(12, "Slim") +// rbTree.put(11, "Shady") +// rbTree.remove(11) +// +// // now vertexes with keys 9 and 12 are black +// rbTree.remove(9) +// +// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) +// } +// +// @Test +// fun `balance after remove - right brother is red`() { +// rbTree.put(60, "sixty") +// rbTree.put(33, "thirty-three") +// rbTree.put(84, "eighty-four") +// rbTree.put(15, "fifteen") +// rbTree.put(51, "fifty-one") +// rbTree.put(65, "sixty-five") +// rbTree.put(96, "ninety-six") +// rbTree.put(34, "thirty-four") +// rbTree.put(52, "Alblack") +// rbTree.put(94, "ninety-four") +// rbTree.put(97, "ninety-seven") +// rbTree.put(95, "ninety-five") +// +// // now vertex with key 96 is red, with key 65 - black +// rbTree.remove(65) +// +// expectedResult = +// listOf( +// Pair(60, "sixty"), +// Pair(96, "ninety-six"), +// Pair(97, "ninety-seven"), +// Pair(94, "ninety-four"), +// Pair(95, "ninety-five"), +// Pair(84, "eighty-four"), +// Pair(33, "thirty-three"), +// Pair(51, "fifty-one"), +// Pair(52, "Alblack"), +// Pair(34, "thirty-four"), +// Pair(15, "fifteen"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is left and black, brother's rightSon - red`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(2, "is") +// rbTree.put(5, "chka") +// rbTree.put(9, "chka") +// rbTree.put(12, "chka") +// rbTree.put(1, "Slim") +// rbTree.put(3, "Shady") +// rbTree.remove(5) +// expectedResult = +// listOf( +// Pair(7, "hi"), +// Pair(10, "name"), +// Pair(12, "chka"), +// Pair(9, "chka"), +// Pair(2, "is"), +// Pair(4, "my"), +// Pair(3, "Shady"), +// Pair(1, "Slim"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(2, "is") +// rbTree.put(5, "chka") +// rbTree.put(9, "chka") +// rbTree.put(12, "Slim") +// rbTree.put(3, "Shady") +// rbTree.remove(5) +// expectedResult = +// listOf( +// Pair(7, "hi"), +// Pair(10, "name"), +// Pair(12, "Slim"), +// Pair(9, "chka"), +// Pair(3, "Shady"), +// Pair(4, "my"), +// Pair(2, "is"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is left and black, both sons - black`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(2, "is") +// rbTree.put(5, "Slim") +// rbTree.put(3, "Shady") +// rbTree.remove(3) +// +// // now vertexes with keys 2 and 5 are black +// rbTree.remove(5) +// +// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) +// } +// +// @Test +// fun `balance after remove - left brother is red`() { +// rbTree.put(60, "sixty") +// rbTree.put(33, "thirty-three") +// rbTree.put(84, "eighty-four") +// rbTree.put(15, "fifteen") +// rbTree.put(51, "fifty-one") +// rbTree.put(65, "sixty-five") +// rbTree.put(96, "ninety-six") +// rbTree.put(5, "five") +// rbTree.put(27, "twenty-seven") +// rbTree.put(61, "sixty-one") +// rbTree.put(69, "sixty-nine") +// rbTree.put(17, "seventeen") +// +// // now vertex with key 15 is red, with key 51 - black +// rbTree.remove(51) +// +// expectedResult = +// listOf( +// Pair(60, "sixty"), +// Pair(84, "eighty-four"), +// Pair(96, "ninety-six"), +// Pair(65, "sixty-five"), +// Pair(69, "sixty-nine"), +// Pair(61, "sixty-one"), +// Pair(15, "fifteen"), +// Pair(27, "twenty-seven"), +// Pair(33, "thirty-three"), +// Pair(17, "seventeen"), +// Pair(5, "five"), +// ) +// } @Test fun `test secondary constructor`() { From 2f03751127866aed46d5b86508b417c5b1e89016 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:36:46 +0300 Subject: [PATCH 188/227] test: comment some rbtree code to see changes in jacoco report --- .github/workflows/coverage.yml | 1 + lib/src/main/kotlin/trees/RBSearchTree.kt | 154 +++---- .../kotlin/trees/rbTree/RBSearchTreeTest.kt | 390 +++++++++--------- 3 files changed, 273 insertions(+), 272 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 50383f3..4a4fa5b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -52,5 +52,6 @@ jobs: update-comment: true skip-if-no-changes: true min-coverage-overall: 40 + min-coverage-changed-files: 60 pass-emoji: '🥳' fail-emoji: '🤡' diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index dfaaa7e..45bc2a1 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -61,7 +61,7 @@ class RBSearchTree : AbstractBinarySearchTree> { if (vertex == root && size == 0L) { root = null } else if (needToBalance(vertex)) { - balanceAfterRemove(vertex) +// balanceAfterRemove(vertex) } return value @@ -125,82 +125,82 @@ class RBSearchTree : AbstractBinarySearchTree> { * rotate left. We move conflict on level below, then we look at the previous cases * @param vertex The child vertex of the removed vertex or null if the removed vertex had no children. */ - private fun balanceAfterRemove(vertex: RBVertex?) { - var currentVertex = vertex - while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { - var brother: RBVertex? - if (currentVertex == currentVertex?.parent?.leftSon) { - brother = currentVertex?.parent?.rightSon - - if (brother?.isRed == true) { - brother.isRed = false - currentVertex?.parent?.isRed = true - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateLeft(vertexForRotate) } - brother = currentVertex?.parent?.rightSon - } - - if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null) - ) { - brother?.isRed = true - currentVertex = currentVertex?.parent - if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null - } else { - if (brother.rightSon?.isRed == false || brother.rightSon == null) { - brother.leftSon?.isRed = false - brother.isRed = true - rotateRight(brother) - brother = currentVertex?.parent?.rightSon - } - - val parentColor = currentVertex?.parent?.isRed - parentColor?.let { brother?.isRed = parentColor } - currentVertex?.parent?.isRed = false - brother?.rightSon?.isRed = false - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateLeft(vertexForRotate) } - if (currentVertex == vertex) currentVertex?.parent?.leftSon = null - currentVertex = root - } - } else { - brother = currentVertex?.parent?.leftSon - - if (brother?.isRed == true) { - brother.isRed = false - currentVertex?.parent?.isRed = true - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateRight(vertexForRotate) } - brother = currentVertex?.parent?.leftSon - } - - if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null) - ) { - brother?.isRed = true - currentVertex = currentVertex?.parent - if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null - } else { - if (brother.leftSon?.isRed == false || brother.leftSon == null) { - brother.rightSon?.isRed = false - brother.isRed = true - rotateLeft(brother) - brother = currentVertex?.parent?.leftSon - } - - val parentColor = currentVertex?.parent?.isRed - parentColor?.let { brother?.isRed = parentColor } - currentVertex?.parent?.isRed = false - brother?.leftSon?.isRed = false - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateRight(vertexForRotate) } - if (currentVertex == vertex) currentVertex?.parent?.rightSon = null - currentVertex = root - } - } - } - currentVertex?.isRed = false - } +// private fun balanceAfterRemove(vertex: RBVertex?) { +// var currentVertex = vertex +// while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { +// var brother: RBVertex? +// if (currentVertex == currentVertex?.parent?.leftSon) { +// brother = currentVertex?.parent?.rightSon +// +// if (brother?.isRed == true) { +// brother.isRed = false +// currentVertex?.parent?.isRed = true +// val vertexForRotate = currentVertex?.parent +// vertexForRotate?.let { rotateLeft(vertexForRotate) } +// brother = currentVertex?.parent?.rightSon +// } +// +// if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && +// (brother?.rightSon?.isRed == false || brother?.rightSon == null) +// ) { +// brother?.isRed = true +// currentVertex = currentVertex?.parent +// if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null +// } else { +// if (brother.rightSon?.isRed == false || brother.rightSon == null) { +// brother.leftSon?.isRed = false +// brother.isRed = true +// rotateRight(brother) +// brother = currentVertex?.parent?.rightSon +// } +// +// val parentColor = currentVertex?.parent?.isRed +// parentColor?.let { brother?.isRed = parentColor } +// currentVertex?.parent?.isRed = false +// brother?.rightSon?.isRed = false +// val vertexForRotate = currentVertex?.parent +// vertexForRotate?.let { rotateLeft(vertexForRotate) } +// if (currentVertex == vertex) currentVertex?.parent?.leftSon = null +// currentVertex = root +// } +// } else { +// brother = currentVertex?.parent?.leftSon +// +// if (brother?.isRed == true) { +// brother.isRed = false +// currentVertex?.parent?.isRed = true +// val vertexForRotate = currentVertex?.parent +// vertexForRotate?.let { rotateRight(vertexForRotate) } +// brother = currentVertex?.parent?.leftSon +// } +// +// if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && +// (brother?.rightSon?.isRed == false || brother?.rightSon == null) +// ) { +// brother?.isRed = true +// currentVertex = currentVertex?.parent +// if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null +// } else { +// if (brother.leftSon?.isRed == false || brother.leftSon == null) { +// brother.rightSon?.isRed = false +// brother.isRed = true +// rotateLeft(brother) +// brother = currentVertex?.parent?.leftSon +// } +// +// val parentColor = currentVertex?.parent?.isRed +// parentColor?.let { brother?.isRed = parentColor } +// currentVertex?.parent?.isRed = false +// brother?.leftSon?.isRed = false +// val vertexForRotate = currentVertex?.parent +// vertexForRotate?.let { rotateRight(vertexForRotate) } +// if (currentVertex == vertex) currentVertex?.parent?.rightSon = null +// currentVertex = root +// } +// } +// } +// currentVertex?.isRed = false +// } /** * Finds a vertex by corresponding key. If such vertex doesn't exist returns null. diff --git a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt index 77258d6..3fdde9c 100644 --- a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt @@ -178,201 +178,201 @@ class RBSearchTreeTest { ) } -// @Test -// fun `balance after remove - brother is right and black, brother's rightSon - red`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(3, "is") -// rbTree.put(5, "chka") -// rbTree.put(9, "chka") -// rbTree.put(12, "chka") -// rbTree.put(11, "Slim") -// rbTree.put(13, "Shady") -// rbTree.remove(9) -// expectedResult = -// listOf( -// Pair(7, "hi"), -// Pair(12, "chka"), -// Pair(13, "Shady"), -// Pair(10, "name"), -// Pair(11, "Slim"), -// Pair(4, "my"), -// Pair(5, "chka"), -// Pair(3, "is"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(3, "is") -// rbTree.put(5, "chka") -// rbTree.put(9, "chka") -// rbTree.put(12, "Slim") -// rbTree.put(11, "Shady") -// rbTree.remove(9) -// expectedResult = -// listOf( -// Pair(7, "hi"), -// Pair(11, "Shady"), -// Pair(12, "Slim"), -// Pair(10, "name"), -// Pair(4, "my"), -// Pair(5, "chka"), -// Pair(3, "is"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is right and black, both sons - black`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(9, "is") -// rbTree.put(12, "Slim") -// rbTree.put(11, "Shady") -// rbTree.remove(11) -// -// // now vertexes with keys 9 and 12 are black -// rbTree.remove(9) -// -// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) -// } -// -// @Test -// fun `balance after remove - right brother is red`() { -// rbTree.put(60, "sixty") -// rbTree.put(33, "thirty-three") -// rbTree.put(84, "eighty-four") -// rbTree.put(15, "fifteen") -// rbTree.put(51, "fifty-one") -// rbTree.put(65, "sixty-five") -// rbTree.put(96, "ninety-six") -// rbTree.put(34, "thirty-four") -// rbTree.put(52, "Alblack") -// rbTree.put(94, "ninety-four") -// rbTree.put(97, "ninety-seven") -// rbTree.put(95, "ninety-five") -// -// // now vertex with key 96 is red, with key 65 - black -// rbTree.remove(65) -// -// expectedResult = -// listOf( -// Pair(60, "sixty"), -// Pair(96, "ninety-six"), -// Pair(97, "ninety-seven"), -// Pair(94, "ninety-four"), -// Pair(95, "ninety-five"), -// Pair(84, "eighty-four"), -// Pair(33, "thirty-three"), -// Pair(51, "fifty-one"), -// Pair(52, "Alblack"), -// Pair(34, "thirty-four"), -// Pair(15, "fifteen"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is left and black, brother's rightSon - red`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(2, "is") -// rbTree.put(5, "chka") -// rbTree.put(9, "chka") -// rbTree.put(12, "chka") -// rbTree.put(1, "Slim") -// rbTree.put(3, "Shady") -// rbTree.remove(5) -// expectedResult = -// listOf( -// Pair(7, "hi"), -// Pair(10, "name"), -// Pair(12, "chka"), -// Pair(9, "chka"), -// Pair(2, "is"), -// Pair(4, "my"), -// Pair(3, "Shady"), -// Pair(1, "Slim"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(2, "is") -// rbTree.put(5, "chka") -// rbTree.put(9, "chka") -// rbTree.put(12, "Slim") -// rbTree.put(3, "Shady") -// rbTree.remove(5) -// expectedResult = -// listOf( -// Pair(7, "hi"), -// Pair(10, "name"), -// Pair(12, "Slim"), -// Pair(9, "chka"), -// Pair(3, "Shady"), -// Pair(4, "my"), -// Pair(2, "is"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is left and black, both sons - black`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(2, "is") -// rbTree.put(5, "Slim") -// rbTree.put(3, "Shady") -// rbTree.remove(3) -// -// // now vertexes with keys 2 and 5 are black -// rbTree.remove(5) -// -// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) -// } -// -// @Test -// fun `balance after remove - left brother is red`() { -// rbTree.put(60, "sixty") -// rbTree.put(33, "thirty-three") -// rbTree.put(84, "eighty-four") -// rbTree.put(15, "fifteen") -// rbTree.put(51, "fifty-one") -// rbTree.put(65, "sixty-five") -// rbTree.put(96, "ninety-six") -// rbTree.put(5, "five") -// rbTree.put(27, "twenty-seven") -// rbTree.put(61, "sixty-one") -// rbTree.put(69, "sixty-nine") -// rbTree.put(17, "seventeen") -// -// // now vertex with key 15 is red, with key 51 - black -// rbTree.remove(51) -// -// expectedResult = -// listOf( -// Pair(60, "sixty"), -// Pair(84, "eighty-four"), -// Pair(96, "ninety-six"), -// Pair(65, "sixty-five"), -// Pair(69, "sixty-nine"), -// Pair(61, "sixty-one"), -// Pair(15, "fifteen"), -// Pair(27, "twenty-seven"), -// Pair(33, "thirty-three"), -// Pair(17, "seventeen"), -// Pair(5, "five"), -// ) -// } + @Test + fun `balance after remove - brother is right and black, brother's rightSon - red`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(3, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "chka") + rbTree.put(11, "Slim") + rbTree.put(13, "Shady") + rbTree.remove(9) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(12, "chka"), + Pair(13, "Shady"), + Pair(10, "name"), + Pair(11, "Slim"), + Pair(4, "my"), + Pair(5, "chka"), + Pair(3, "is"), + ) + } + + @Test + fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(3, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "Slim") + rbTree.put(11, "Shady") + rbTree.remove(9) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(11, "Shady"), + Pair(12, "Slim"), + Pair(10, "name"), + Pair(4, "my"), + Pair(5, "chka"), + Pair(3, "is"), + ) + } + + @Test + fun `balance after remove - brother is right and black, both sons - black`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(9, "is") + rbTree.put(12, "Slim") + rbTree.put(11, "Shady") + rbTree.remove(11) + + // now vertexes with keys 9 and 12 are black + rbTree.remove(9) + + expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) + } + + @Test + fun `balance after remove - right brother is red`() { + rbTree.put(60, "sixty") + rbTree.put(33, "thirty-three") + rbTree.put(84, "eighty-four") + rbTree.put(15, "fifteen") + rbTree.put(51, "fifty-one") + rbTree.put(65, "sixty-five") + rbTree.put(96, "ninety-six") + rbTree.put(34, "thirty-four") + rbTree.put(52, "Alblack") + rbTree.put(94, "ninety-four") + rbTree.put(97, "ninety-seven") + rbTree.put(95, "ninety-five") + + // now vertex with key 96 is red, with key 65 - black + rbTree.remove(65) + + expectedResult = + listOf( + Pair(60, "sixty"), + Pair(96, "ninety-six"), + Pair(97, "ninety-seven"), + Pair(94, "ninety-four"), + Pair(95, "ninety-five"), + Pair(84, "eighty-four"), + Pair(33, "thirty-three"), + Pair(51, "fifty-one"), + Pair(52, "Alblack"), + Pair(34, "thirty-four"), + Pair(15, "fifteen"), + ) + } + + @Test + fun `balance after remove - brother is left and black, brother's rightSon - red`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "chka") + rbTree.put(1, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(5) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(10, "name"), + Pair(12, "chka"), + Pair(9, "chka"), + Pair(2, "is"), + Pair(4, "my"), + Pair(3, "Shady"), + Pair(1, "Slim"), + ) + } + + @Test + fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(5) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(10, "name"), + Pair(12, "Slim"), + Pair(9, "chka"), + Pair(3, "Shady"), + Pair(4, "my"), + Pair(2, "is"), + ) + } + + @Test + fun `balance after remove - brother is left and black, both sons - black`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(3) + + // now vertexes with keys 2 and 5 are black + rbTree.remove(5) + + expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) + } + + @Test + fun `balance after remove - left brother is red`() { + rbTree.put(60, "sixty") + rbTree.put(33, "thirty-three") + rbTree.put(84, "eighty-four") + rbTree.put(15, "fifteen") + rbTree.put(51, "fifty-one") + rbTree.put(65, "sixty-five") + rbTree.put(96, "ninety-six") + rbTree.put(5, "five") + rbTree.put(27, "twenty-seven") + rbTree.put(61, "sixty-one") + rbTree.put(69, "sixty-nine") + rbTree.put(17, "seventeen") + + // now vertex with key 15 is red, with key 51 - black + rbTree.remove(51) + + expectedResult = + listOf( + Pair(60, "sixty"), + Pair(84, "eighty-four"), + Pair(96, "ninety-six"), + Pair(65, "sixty-five"), + Pair(69, "sixty-nine"), + Pair(61, "sixty-one"), + Pair(15, "fifteen"), + Pair(27, "twenty-seven"), + Pair(33, "thirty-three"), + Pair(17, "seventeen"), + Pair(5, "five"), + ) + } @Test fun `test secondary constructor`() { From ccc41af52be37b7c47699b0486627de4e87bba8c Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:42:53 +0300 Subject: [PATCH 189/227] feat: finally add tests reports --- .github/workflows/coverage.yml | 1 - lib/src/main/kotlin/trees/RBSearchTree.kt | 154 +++++++++++----------- 2 files changed, 77 insertions(+), 78 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4a4fa5b..08e66a4 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -50,7 +50,6 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} title: '# 5⃣2⃣ Coverage Report' update-comment: true - skip-if-no-changes: true min-coverage-overall: 40 min-coverage-changed-files: 60 pass-emoji: '🥳' diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 45bc2a1..dfaaa7e 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -61,7 +61,7 @@ class RBSearchTree : AbstractBinarySearchTree> { if (vertex == root && size == 0L) { root = null } else if (needToBalance(vertex)) { -// balanceAfterRemove(vertex) + balanceAfterRemove(vertex) } return value @@ -125,82 +125,82 @@ class RBSearchTree : AbstractBinarySearchTree> { * rotate left. We move conflict on level below, then we look at the previous cases * @param vertex The child vertex of the removed vertex or null if the removed vertex had no children. */ -// private fun balanceAfterRemove(vertex: RBVertex?) { -// var currentVertex = vertex -// while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { -// var brother: RBVertex? -// if (currentVertex == currentVertex?.parent?.leftSon) { -// brother = currentVertex?.parent?.rightSon -// -// if (brother?.isRed == true) { -// brother.isRed = false -// currentVertex?.parent?.isRed = true -// val vertexForRotate = currentVertex?.parent -// vertexForRotate?.let { rotateLeft(vertexForRotate) } -// brother = currentVertex?.parent?.rightSon -// } -// -// if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && -// (brother?.rightSon?.isRed == false || brother?.rightSon == null) -// ) { -// brother?.isRed = true -// currentVertex = currentVertex?.parent -// if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null -// } else { -// if (brother.rightSon?.isRed == false || brother.rightSon == null) { -// brother.leftSon?.isRed = false -// brother.isRed = true -// rotateRight(brother) -// brother = currentVertex?.parent?.rightSon -// } -// -// val parentColor = currentVertex?.parent?.isRed -// parentColor?.let { brother?.isRed = parentColor } -// currentVertex?.parent?.isRed = false -// brother?.rightSon?.isRed = false -// val vertexForRotate = currentVertex?.parent -// vertexForRotate?.let { rotateLeft(vertexForRotate) } -// if (currentVertex == vertex) currentVertex?.parent?.leftSon = null -// currentVertex = root -// } -// } else { -// brother = currentVertex?.parent?.leftSon -// -// if (brother?.isRed == true) { -// brother.isRed = false -// currentVertex?.parent?.isRed = true -// val vertexForRotate = currentVertex?.parent -// vertexForRotate?.let { rotateRight(vertexForRotate) } -// brother = currentVertex?.parent?.leftSon -// } -// -// if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && -// (brother?.rightSon?.isRed == false || brother?.rightSon == null) -// ) { -// brother?.isRed = true -// currentVertex = currentVertex?.parent -// if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null -// } else { -// if (brother.leftSon?.isRed == false || brother.leftSon == null) { -// brother.rightSon?.isRed = false -// brother.isRed = true -// rotateLeft(brother) -// brother = currentVertex?.parent?.leftSon -// } -// -// val parentColor = currentVertex?.parent?.isRed -// parentColor?.let { brother?.isRed = parentColor } -// currentVertex?.parent?.isRed = false -// brother?.leftSon?.isRed = false -// val vertexForRotate = currentVertex?.parent -// vertexForRotate?.let { rotateRight(vertexForRotate) } -// if (currentVertex == vertex) currentVertex?.parent?.rightSon = null -// currentVertex = root -// } -// } -// } -// currentVertex?.isRed = false -// } + private fun balanceAfterRemove(vertex: RBVertex?) { + var currentVertex = vertex + while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { + var brother: RBVertex? + if (currentVertex == currentVertex?.parent?.leftSon) { + brother = currentVertex?.parent?.rightSon + + if (brother?.isRed == true) { + brother.isRed = false + currentVertex?.parent?.isRed = true + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateLeft(vertexForRotate) } + brother = currentVertex?.parent?.rightSon + } + + if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && + (brother?.rightSon?.isRed == false || brother?.rightSon == null) + ) { + brother?.isRed = true + currentVertex = currentVertex?.parent + if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null + } else { + if (brother.rightSon?.isRed == false || brother.rightSon == null) { + brother.leftSon?.isRed = false + brother.isRed = true + rotateRight(brother) + brother = currentVertex?.parent?.rightSon + } + + val parentColor = currentVertex?.parent?.isRed + parentColor?.let { brother?.isRed = parentColor } + currentVertex?.parent?.isRed = false + brother?.rightSon?.isRed = false + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateLeft(vertexForRotate) } + if (currentVertex == vertex) currentVertex?.parent?.leftSon = null + currentVertex = root + } + } else { + brother = currentVertex?.parent?.leftSon + + if (brother?.isRed == true) { + brother.isRed = false + currentVertex?.parent?.isRed = true + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateRight(vertexForRotate) } + brother = currentVertex?.parent?.leftSon + } + + if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && + (brother?.rightSon?.isRed == false || brother?.rightSon == null) + ) { + brother?.isRed = true + currentVertex = currentVertex?.parent + if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null + } else { + if (brother.leftSon?.isRed == false || brother.leftSon == null) { + brother.rightSon?.isRed = false + brother.isRed = true + rotateLeft(brother) + brother = currentVertex?.parent?.leftSon + } + + val parentColor = currentVertex?.parent?.isRed + parentColor?.let { brother?.isRed = parentColor } + currentVertex?.parent?.isRed = false + brother?.leftSon?.isRed = false + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateRight(vertexForRotate) } + if (currentVertex == vertex) currentVertex?.parent?.rightSon = null + currentVertex = root + } + } + } + currentVertex?.isRed = false + } /** * Finds a vertex by corresponding key. If such vertex doesn't exist returns null. From 9a346bd66f96001a3f469281fc8f9394633980ab Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:49:09 +0300 Subject: [PATCH 190/227] chore: change emoji --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 08e66a4..bcd858c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,7 +48,7 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} - title: '# 5⃣2⃣ Coverage Report' + title: '# 🇷🇺 Coverage Report' update-comment: true min-coverage-overall: 40 min-coverage-changed-files: 60 From 01507c8edde26e2085f1fe504033f4f0ac7d7e3f Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Sun, 7 Apr 2024 12:09:51 +0300 Subject: [PATCH 191/227] fix and refactor AVL tree * fix (AVLTree): use compareKeys() name instead of compare() * fix(AVLTree) : change and rename prepareLargestLowerToReplaceVertex(), remove RemovalStage.D * refactor(AVLTree) : increase/decrease sonSHeightDiff value before balance() call * refactor(AVLTree) : fix typos in code * refactor(AVLTree) : use isNotEmpty() instead of !isEmpty() --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 67 ++++++++-------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 506b569..bc87ba8 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -38,7 +38,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> value: V, replaceIfExists: Boolean, ) { - if (!isEmpty()) { + if (isNotEmpty()) { when (val putRecReturned = putRec(key, value, replaceIfExists, root as AVLVertex)) { null, root -> {} else -> root = putRecReturned @@ -102,15 +102,13 @@ open class AVLSearchTree : AbstractBinarySearchTree> fun doBalanceChoreWhenLeftSubTreeChanged(): AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null - if (vertex.sonsHeightDiff + 1 == 2) return balance(vertex) - vertex.sonsHeightDiff++ + if (++vertex.sonsHeightDiff == 2) return balance(vertex) return vertex } fun doBalanceChoreWhenRightSubTreeChanged(): AVLVertex? { if (nextCallReturned.sonsHeightDiff == 0) return null - if (vertex.sonsHeightDiff - 1 == -2) return balance(vertex) - vertex.sonsHeightDiff-- + if (--vertex.sonsHeightDiff == -2) return balance(vertex) return vertex } when (nextCallReturned) { @@ -133,7 +131,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> * @return the previous value associated with key, or null if there was no mapping for key */ override fun remove(key: K): V? { - if (!isEmpty()) { + if (isNotEmpty()) { val removeRecReturned = removeRec(key, root as AVLVertex) when (removeRecReturned.first) { RemovalStage.B -> { @@ -143,7 +141,6 @@ open class AVLSearchTree : AbstractBinarySearchTree> } RemovalStage.C -> root = null - RemovalStage.D -> root = removeRecReturned.component2() else -> {} } return removeRecReturned.component3() @@ -169,11 +166,6 @@ open class AVLSearchTree : AbstractBinarySearchTree> * Need to null due "Son" property of (if exists) the parent of removed vertex + b */ C, - - /** - * Need only to change due "Son" property of (if exists) the parent - */ - D, } /** @@ -235,12 +227,14 @@ open class AVLSearchTree : AbstractBinarySearchTree> Triple(RemovalStage.B, vertex.leftSon as AVLVertex, vertex.value) } - else -> + else -> { + val valueOfVertex = vertex.value Triple( - RemovalStage.D, - prepareLargestLowerToReplaceVertex(vertex), - vertex.value, + RemovalStage.B, + replaceSubtreeSRootByLargestInItsLeftSubtree(vertex), + valueOfVertex, ) + } } } } @@ -249,10 +243,9 @@ open class AVLSearchTree : AbstractBinarySearchTree> if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) { return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) } - if (vertex.sonsHeightDiff - 1 == -2) { + if (--vertex.sonsHeightDiff == -2) { return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) } - vertex.sonsHeightDiff-- return Triple(RemovalStage.B, vertex, nextCallReturned.third) } @@ -260,10 +253,9 @@ open class AVLSearchTree : AbstractBinarySearchTree> if (nextCallReturned.component2().sonsHeightDiff in listOf(-1, 1)) { return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) } - if (vertex.sonsHeightDiff + 1 == 2) { + if (++vertex.sonsHeightDiff == 2) { return Triple(RemovalStage.B, balance(vertex), nextCallReturned.component3()) } - vertex.sonsHeightDiff++ return Triple(RemovalStage.B, vertex, nextCallReturned.component3()) } when (nextCallReturned.component1()) { @@ -298,15 +290,6 @@ open class AVLSearchTree : AbstractBinarySearchTree> return doBalanceChoreWhenRightSubTreeChanged() } } - - RemovalStage.D -> { - if (compareKeys(nextCallReturned.component2().key, vertex.key) == -1) { - vertex.leftSon = nextCallReturned.component2() - } else { - vertex.rightSon = nextCallReturned.component2() - } - return Triple(RemovalStage.A, vertex, nextCallReturned.component3()) - } } } @@ -315,13 +298,13 @@ open class AVLSearchTree : AbstractBinarySearchTree> * @param vertex the vertex to be replaced * @return the substitute vertex prepared to replace the specified vertex */ - private fun prepareLargestLowerToReplaceVertex(vertex: AVLVertex): AVLVertex { - val substitute = getMaxKeyNodeRec(vertex.leftSon) as AVLVertex - remove(substitute.key) - substitute.leftSon = vertex.leftSon - substitute.rightSon = vertex.rightSon - substitute.sonsHeightDiff = vertex.sonsHeightDiff - return substitute + private fun replaceSubtreeSRootByLargestInItsLeftSubtree (subtreeSInitiallyRoot: AVLVertex): AVLVertex { + val substitute = getMaxKeyNodeRec(subtreeSInitiallyRoot.leftSon) as AVLVertex + val removeRecReturned = removeRec(substitute.key, subtreeSInitiallyRoot) + subtreeSInitiallyRoot.key = substitute.key + subtreeSInitiallyRoot.value = substitute.value + return if (removeRecReturned.component1() == RemovalStage.A) subtreeSInitiallyRoot + else removeRecReturned.component2() } /** @@ -332,7 +315,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> private fun balance(curVertex: AVLVertex): AVLVertex { var (rightSon, leftSon) = List?>(2) { null } - fun setSonSHeightDiffsOfTwoVerteces(values: Pair) { + fun setSonSHeightDiffsOfTwoVertices(values: Pair) { curVertex.sonsHeightDiff = values.component1() if (rightSon != null) { (rightSon as AVLVertex).sonsHeightDiff = values.component2() @@ -341,12 +324,12 @@ open class AVLSearchTree : AbstractBinarySearchTree> (leftSon as AVLVertex).sonsHeightDiff = values.component2() } - if (curVertex.sonsHeightDiff == -1) { + if (curVertex.sonsHeightDiff == -2) { rightSon = curVertex.rightSon as AVLVertex return if (rightSon.sonsHeightDiff == 1) { val rightSonSLeftSon = rightSon.leftSon as AVLVertex val subtreeRoot = bigRotateLeft(curVertex, rightSon) - setSonSHeightDiffsOfTwoVerteces( + setSonSHeightDiffsOfTwoVertices( when (rightSonSLeftSon.sonsHeightDiff) { 1 -> 0 to -1 -1 -> 1 to 0 @@ -357,7 +340,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> subtreeRoot } else { val subtreeRoot = rotateLeft(curVertex, rightSon) - setSonSHeightDiffsOfTwoVerteces( + setSonSHeightDiffsOfTwoVertices( if (rightSon.sonsHeightDiff == 0) { -1 to 1 } else { @@ -371,7 +354,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> return if (leftSon.sonsHeightDiff == -1) { val leftSonSRightSon = leftSon.rightSon as AVLVertex val subtreeRoot = bigRotateRight(curVertex, leftSon) - setSonSHeightDiffsOfTwoVerteces( + setSonSHeightDiffsOfTwoVertices( when (leftSonSRightSon.sonsHeightDiff) { -1 -> 0 to 1 1 -> -1 to 0 @@ -382,7 +365,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> subtreeRoot } else { val subtreeRoot = rotateRight(curVertex, leftSon) - setSonSHeightDiffsOfTwoVerteces( + setSonSHeightDiffsOfTwoVertices( if (leftSon.sonsHeightDiff == 0) { 1 to -1 } else { From fbd42ceda1c967afae69c050cf6d4a6200439c89 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 6 Apr 2024 19:43:12 +0300 Subject: [PATCH 192/227] refactor(AVLTest) : sort tests into classes, fix typos --- .../test/kotlin/trees/avlTree/AVLTreeTest.kt | 1494 ----------------- .../trees/avlTree/AuxiliaryFunctions.kt | 60 + .../avlTree/putTest/HaveToDoBigRotation.kt | 222 +++ .../trees/avlTree/putTest/HaveToRotateLeft.kt | 102 ++ .../avlTree/putTest/HaveToRotateRight.kt | 102 ++ .../kotlin/trees/avlTree/putTest/Other.kt | 27 + .../trees/avlTree/putTest/WithoutBalancing.kt | 113 ++ .../avlTree/removeTest/HaveToDoBigRotation.kt | 116 ++ .../avlTree/removeTest/HaveToRotateLeft.kt | 165 ++ .../avlTree/removeTest/HaveToRotateRight.kt | 166 ++ .../removeTest/withoutBalancing/Other.kt | 338 ++++ .../withoutBalancing/VertexHadTwoSons.kt | 190 +++ 12 files changed, 1601 insertions(+), 1494 deletions(-) delete mode 100644 lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/putTest/Other.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt create mode 100644 lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt diff --git a/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt b/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt deleted file mode 100644 index 38b1df9..0000000 --- a/lib/src/test/kotlin/trees/avlTree/AVLTreeTest.kt +++ /dev/null @@ -1,1494 +0,0 @@ -package trees.avlTree - -import main.vertexes.AVLVertex -import org.junit.jupiter.api.Test -import kotlin.collections.hashMapOf - -class AVLTreeTest { - private fun makeEmptyTree(): AVLTreeForTest { - return AVLTreeForTest() - } - - // putTest - - @Test - fun `entry became root after it was added to empty tree`() { - val tree = makeEmptyTree() - tree.put(0, '0') - val root = tree.getRootT() - assert((root?.key to root?.value) == (0 to '0')) - } - - @Test - fun `size equals 1 after entry was added to empty tree`() { - val tree = makeEmptyTree() - tree.put(0, '0') - assert(tree.size() == 1L) - } - - private fun makeSize1Tree(): AVLTreeForTest { - return AVLTreeForTest(AVLVertex('b', '+'), 1L) // init tree by root and size (don't use put) - } - - @Test - fun `entry with larger key became right son after it was added to size 1 tree`() { - val tree = makeSize1Tree() - tree.put('c', '+') - val root = tree.getRootT() - assert((root?.rightSon?.key to root?.rightSon?.value) == ('c' to '+')) - } - - @Test - fun `entry with lesser key became left son after it was added to size 1 tree`() { - val tree = makeSize1Tree() - tree.put('a', '-') - val root = tree.getRootT() - assert((root?.leftSon?.key to root?.leftSon?.value) == ('a' to '-')) - } - - @Test - fun `root's sonsHeightDiff decreased by 1 after entry with larger key was added to size 1 tree`() { - val tree = makeSize1Tree() - tree.put('c', '+') - val root = tree.getRootT() - assert(root?.sonsHeightDiff == -1) - } - - @Test - fun `root's sonsHeightDiff increased by 1 after entry with lesser key was added to size 1 tree`() { - val tree = makeSize1Tree() - tree.put('a', '-') - val root = tree.getRootT() - assert(root?.sonsHeightDiff == 1) - } - - @Test - fun `size equals 2 after entry with larger key was added to size 1 tree`() { - val tree = makeSize1Tree() - tree.put('c', '+') - assert(tree.size() == 2L) - } - - @Test - fun `size equals 2 after entry with lesser key was added to size 1 tree`() { - val tree = makeSize1Tree() - tree.put('a', '-') - assert(tree.size() == 2L) - } - - private fun makeTreeForNeedNotBalanceingPutTest(): AVLTreeForTest { - return AVLTreeForTest(AVLVertex(4, 'A', AVLVertex(1, 'I'), AVLVertex(5, 'S')), 3L) - } - - private fun isTreeConsistsOf( - expectedContent: Set>, - tree: AVLTreeForTest, - ): Boolean { - val vertexes = tree.getVertexesInDFSOrder() - val pairsFromVertexes = (Array(vertexes.size) { i -> (vertexes[i].key to vertexes[i].value) }).toSet() - return pairsFromVertexes == expectedContent - } - - @Test - fun `content is correct after entry was added (needn't balancing)`() { - val tree = makeTreeForNeedNotBalanceingPutTest() - tree.put(0, 'O') - assert(isTreeConsistsOf(setOf(0 to 'O', 1 to 'I', 5 to 'S', 4 to 'A'), tree)) - } - - @Test - fun `size increased by 1 after added to 'size 2+' tree (needn't balancing)`() { - val tree = makeTreeForNeedNotBalanceingPutTest() - tree.put(0, 'O') - assert(tree.size() == 4L) - } - - private fun isTreeSStructureThat( - tree: AVLTreeForTest, - order: Array, - deps: List>, - ): Boolean { - // Tiple consists of indexes in order of (1)vertex, one's (2)leftSon and (3)RightSon - val vertexes = tree.getVertexesInDFSOrder() - if (vertexes.size != order.size) return false - for (i in order.indices) - if (order[i] != vertexes[i].key) return false - for (dep in deps) { - if (dep.component2() != null) { - if (vertexes[dep.component1()].leftSon != vertexes[dep.component2() as Int]) { - return false - } - } - if (dep.component3() != null) { - if (vertexes[dep.component1()].rightSon != vertexes[dep.component3() as Int]) { - return false - } - } - } - return true - } - - @Test - fun `structure is correct after added to 'size 2+' tree (needn't balancing)`() { - val tree = makeTreeForNeedNotBalanceingPutTest() - tree.put(0, 'O') - val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null)) - assert(isTreeSStructureThat(tree, arrayOf(4, 1, 0, 5), expectedDependences)) - } - - private fun isSonsHeightDiffCorrect(tree: AVLTreeForTest): Boolean { - val vertexes = tree.getVertexesInDFSOrder() - val heights = tree.getHeights() - if (vertexes.size != heights.size) return false - for (vertex in vertexes) { - val expectedSonsHeightDiff = - when ((vertex.leftSon == null) to (vertex.rightSon == null)) { - true to true -> 0 - true to false -> -1 - (heights[(vertex.rightSon as AVLVertex).key] ?: return false) - false to true -> 1 + (heights[(vertex.leftSon as AVLVertex).key] ?: return false) - else -> { - val heightOfLeftSubtree = heights[(vertex.leftSon as AVLVertex).key] ?: return false - val heightOfRightSubtree = heights[(vertex.rightSon as AVLVertex).key] ?: return false - heightOfLeftSubtree - heightOfRightSubtree - } - } - if (expectedSonsHeightDiff != vertex.sonsHeightDiff) return false - } - return true - } - - @Test - fun `vertexes' sonsHeightDiff are correct after entry was added to 'size 2+' tree (needn't balancing)`() { - val tree = makeTreeForNeedNotBalanceingPutTest() - tree.put(0, 'O') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForHaveToRotateLeftPutTest(): AVLTreeForTest { - val rightSonSRightSon = AVLVertex('h', 'H', AVLVertex('f', 'F'), AVLVertex('i', 'I')) - val rightSon = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSonSRightSon, -1) - val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) - return AVLTreeForTest(root, 8L) - } - - @Test - fun `content is correct after entry was added (have to rotate left)`() { - val tree = makeTreeForHaveToRotateLeftPutTest() - tree.put('j', 'J') - val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'e' to 'E', - 'h' to 'H', - 'f' to 'F', - 'i' to 'I', - 'j' to 'J', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size increased by 1 after added (have to rotate left)`() { - val tree = makeTreeForHaveToRotateLeftPutTest() - tree.put('j', 'J') - assert(tree.size() == 9L) - } - - @Test - fun `structure is correct after added (have to rotate left)`() { - val tree = makeTreeForHaveToRotateLeftPutTest() - tree.put('j', 'J') - val expectedDependences = - listOf( - Triple(0, 1, 3), - Triple(1, 2, null), - Triple(3, 4, 7), - Triple(4, 5, 6), - Triple(7, null, 8), - ) - val expectedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after added (have to rotate left)`() { - val tree = makeTreeForHaveToRotateLeftPutTest() - tree.put('j', 'J') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForHaveToRotateRightPutTest(): AVLTreeForTest { - val leftSonSLeftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) - val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('e', 'E'), 1) - val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I', null, AVLVertex('j', 'J'), -1), 1) - return AVLTreeForTest(root, 8L) - } - - @Test - fun `content is correct after entry was added (have to rotate right)`() { - val tree = makeTreeForHaveToRotateRightPutTest() - tree.put('a', 'A') - val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'e' to 'E', - 'h' to 'H', - 'f' to 'F', - 'i' to 'I', - 'j' to 'J', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size increased by 1 after added (have to rotate right)`() { - val tree = makeTreeForHaveToRotateRightPutTest() - tree.put('a', 'A') - assert(tree.size() == 9L) - } - - @Test - fun `structure is correct after added (have to rotate right)`() { - val tree = makeTreeForHaveToRotateRightPutTest() - tree.put('a', 'A') - val expectedDependences = - listOf( - Triple(0, 1, 7), - Triple(1, 2, 4), - Triple(2, 3, null), - Triple(4, 5, 6), - Triple(7, null, 8), - ) - val expectedOrder = arrayOf('h', 'c', 'b', 'a', 'f', 'd', 'e', 'i', 'j') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after added (have to rotate right)`() { - val tree = makeTreeForHaveToRotateRightPutTest() - tree.put('a', 'A') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForHaveToChangeRootByRotateLeftPutTest(): AVLTreeForTest { - val rightSon = AVLVertex('h', 'H', AVLVertex('f', 'F'), AVLVertex('i', 'I')) - val root = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSon, -1) - return AVLTreeForTest(root, 5L) - } - - @Test - fun `content is correct after entry was added (rotateLeft changes root)`() { - val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() - tree.put('j', 'J') - val expectedContent = setOf('d' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size increased by 1 after added (rotateLeft changes root)`() { - val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() - tree.put('j', 'J') - assert(tree.size() == 6L) - } - - @Test - fun `structure is correct after added (rotateLeft changes root)`() { - val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() - tree.put('j', 'J') - val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, null, 5)) - val expectedOrder = arrayOf('h', 'e', 'd', 'f', 'i', 'j') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after added (rotateLeft changes root)`() { - val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() - tree.put('j', 'J') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForHaveToChangeRootByRotateRightPutTest(): AVLTreeForTest { - val leftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) - val root = AVLVertex('f', 'F', leftSon, AVLVertex('e', 'E'), 1) - return AVLTreeForTest(root, 5L) - } - - @Test - fun `content is correct after entry was added (rotateRight changes root)`() { - val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() - tree.put('a', 'A') - val expectedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'f' to 'F') - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size increased by 1 after added (rotateRight changes root)`() { - val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() - tree.put('a', 'A') - assert(tree.size() == 6L) - } - - @Test - fun `structure is correct after added (rotateRight changes root)`() { - val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() - tree.put('a', 'A') - val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 5)) - val expectedOrder = arrayOf('c', 'b', 'a', 'f', 'd', 'e') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after added (rotateRight changes root)`() { - val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() - tree.put('a', 'A') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForHaveToBigRotateLeftPutTest(): AVLTreeForTest { - val rightSonSRightSon = AVLVertex('i', 'I', AVLVertex('g', 'G'), AVLVertex('j', 'J')) - val rightSon = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSonSRightSon, -1) - val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) - return AVLTreeForTest(root, 8L) - } - - // (1) - add grandson's right son, (2) add grandson's left son - @Test - fun `content is correct after entry was added (have to big rotate left)(1)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('f', 'F') - val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'e' to 'E', - 'g' to 'G', - 'f' to 'F', - 'i' to 'I', - 'j' to 'J', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `content is correct after entry was added (have to big rotate left)(2)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('h', 'H') - val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'e' to 'E', - 'h' to 'H', - 'g' to 'G', - 'i' to 'I', - 'j' to 'J', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size increased by 1 after added (have to big rotate left)(1)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('f', 'F') - assert(tree.size() == 9L) - } - - @Test - fun `size increased by 1 after added (have to big rotate left)(2)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('h', 'H') - assert(tree.size() == 9L) - } - - @Test - fun `structure is correct after added (have to big rotate left)(1)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('f', 'F') - val expectedDependences = - listOf( - Triple(0, 1, 3), - Triple(1, 2, null), - Triple(3, 4, 7), - Triple(4, 5, 6), - Triple(7, null, 8), - ) - val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'f', 'i', 'j') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `structure is correct after added (have to big rotate left)(2)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('h', 'H') - val expectedDependences = - listOf( - Triple(0, 1, 3), - Triple(1, 2, null), - Triple(3, 4, 6), - Triple(4, 5, null), - Triple(6, 7, 8), - ) - val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'i', 'h', 'j') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after added (have to big rotate left)(1)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('f', 'F') - assert(isSonsHeightDiffCorrect(tree)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after added (have to big rotate left)(2)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('h', 'H') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForHaveToBigRotateRightPutTest(): AVLTreeForTest { - val leftSonSLeftSon = AVLVertex('b', 'B', AVLVertex('a', 'A'), AVLVertex('d', 'D')) - val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('g', 'G'), 1) - val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I', null, AVLVertex('j', 'J'), -1), 1) - return AVLTreeForTest(root, 8L) - } - - // (1) - add grandson's left son, (2) add grandson's right son - @Test - fun `content is correct after entry was added (have to big rotate right)(1)`() { - val tree = makeTreeForHaveToBigRotateRightPutTest() - tree.put('c', 'C') - val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'h' to 'H', - 'g' to 'G', - 'f' to 'F', - 'i' to 'I', - 'j' to 'J', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `content is correct after entry was added (have to big rotate right)(2)`() { - val tree = makeTreeForHaveToBigRotateRightPutTest() - tree.put('e', 'E') - val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'f' to 'F', - 'd' to 'D', - 'e' to 'E', - 'h' to 'H', - 'g' to 'G', - 'i' to 'I', - 'j' to 'J', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size increased by 1 after added (have to big rotate right)(1)`() { - val tree = makeTreeForHaveToBigRotateRightPutTest() - tree.put('c', 'C') - assert(tree.size() == 9L) - } - - @Test - fun `size increased by 1 after added (have to big rotate right)(2)`() { - val tree = makeTreeForHaveToBigRotateRightPutTest() - tree.put('e', 'E') - assert(tree.size() == 9L) - } - - @Test - fun `structure is correct after added (have to big rotate right)(1)`() { - val tree = makeTreeForHaveToBigRotateRightPutTest() - tree.put('c', 'C') - val expectedDependences = - listOf( - Triple(0, 1, 7), - Triple(7, null, 8), - Triple(1, 2, 5), - Triple(5, null, 6), - Triple(2, 3, 4), - ) - val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'c', 'f', 'g', 'i', 'j') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `structure is correct after added (have to big rotate right)(2)`() { - val tree = makeTreeForHaveToBigRotateRightPutTest() - tree.put('e', 'E') - val expectedDependences = - listOf( - Triple(0, 1, 7), - Triple(7, null, 8), - Triple(1, 2, 4), - Triple(2, 3, null), - Triple(4, 5, 6), - ) - val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'f', 'e', 'g', 'i', 'j') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after added (have to big rotate right)(1)`() { - val tree = makeTreeForHaveToBigRotateRightPutTest() - tree.put('c', 'C') - assert(isSonsHeightDiffCorrect(tree)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after added (have to big rotate right)(2)`() { - val tree = makeTreeForHaveToBigRotateLeftPutTest() - tree.put('e', 'E') - assert(isSonsHeightDiffCorrect(tree)) - } - - @Test - fun `tree has no changes after entry with existed key and param replaceIfExists = false was added`() { - val tree = makeSize1Tree() - tree.put('b', '-', false) - assert(tree.size() == 1L) - assert(tree.getRootT()?.value == '+') - } - - @Test - fun `content is correct after init by map`() { - val tree = AVLTreeForTest(hashMapOf('a' to 'A', 'b' to 'B')) - val expectedContent = setOf('a' to 'A', 'b' to 'B') - assert(isTreeConsistsOf(expectedContent, tree)) - } - - // remove test - - @Test - fun `delete from emptyTree returns null`() { - val tree = makeEmptyTree() - assert(tree.remove(0) == null) - } - - @Test - fun `tree is empty after deleted root of 'size 1' tree `() { - val tree = makeSize1Tree() - tree.remove('b') - assert(tree.getVertexesInDFSOrder().isEmpty()) - } - - @Test - fun `size equals 0 after deleted root of 'size 1' tree`() { - val tree = makeSize1Tree() - tree.remove('b') - assert(tree.size() == 0L) - } - - @Test - fun `remove fun return null if entry's key isn't exists(1)`() { - val tree = makeSize1Tree() - assert(tree.remove('a') == null) - } - - @Test - fun `tree has no changes after tried to delete by non existed larger key`() { - val tree = makeSize1Tree() - tree.remove('c') - assert(tree.size() == 1L) - assert(tree.getRootT()?.value == '+') - } - - @Test - fun `tree has no changes after tried to delete by non existed lesser key`() { - val tree = makeSize1Tree() - tree.remove('a') - assert(tree.size() == 1L) - assert(tree.getRootT()?.value == '+') - } - - private fun makeTreeForRemoveLeafWithoutBalanceingTest(): AVLTreeForTest { - return AVLTreeForTest(AVLVertex('r', "r", AVLVertex('n', "n"), AVLVertex('z', "z")), 3L) - } - - @Test - fun `right leaf deleted after remove with one's key was called (needn't balanceing)`() { - val tree = makeTreeForRemoveLeafWithoutBalanceingTest() - tree.remove('z') - val root = tree.getRootT() - if (root != null) { - assert(root.rightSon == null) - } else { - assert(false) - } - } - - @Test - fun `left leaf deleted after remove with one's key was called (needn't balanceing)`() { - val tree = makeTreeForRemoveLeafWithoutBalanceingTest() - tree.remove('n') - val root = tree.getRootT() - if (root != null) { - assert(root.leftSon == null) - } else { - assert(false) - } - } - - @Test - fun `remove by right leaf's key return due value (needn't balanceing)`() { - val tree = makeTreeForRemoveLeafWithoutBalanceingTest() - assert(tree.remove('z') == "z") - } - - @Test - fun `remove by left leaf's key return due value (needn't balanceing)`() { - val tree = makeTreeForRemoveLeafWithoutBalanceingTest() - assert(tree.remove('n') == "n") - } - - @Test - fun `vertex's sonsHeightDiff increased by 1 after deleted one's right leaf (needn't balanceing)`() { - val tree = makeTreeForRemoveLeafWithoutBalanceingTest() - tree.remove('z') - val root = tree.getRootT() - assert(root?.sonsHeightDiff == 1) - } - - @Test - fun `vertex's sonsHeightDiff decreased by 1 after deleted one's left son (needn't balanceing)`() { - val tree = makeTreeForRemoveLeafWithoutBalanceingTest() - tree.remove('n') - val root = tree.getRootT() - assert(root?.sonsHeightDiff == -1) - } - - @Test - fun `size decreased by 1 after deleted right leaf (needn't balanceing)`() { - val tree = makeTreeForRemoveLeafWithoutBalanceingTest() - tree.remove('z') - assert(tree.size() == 2L) - } - - @Test - fun `size decreased by 1 after deleted left leaf (needn't balanceing)`() { - val tree = makeTreeForRemoveLeafWithoutBalanceingTest() - tree.remove('n') - assert(tree.size() == 2L) - } - - private fun makeTreeForRemoveLeftSonWithOnlyLeftSonTest(): AVLTreeForTest { - val leftSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) - val root = AVLVertex('s', 5, leftSon, AVLVertex('z', 2), 1) - return AVLTreeForTest(root, 4L) - } - - @Test - fun `remove left son with only left son returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() - assert(tree.remove('q') == 9) - } - - @Test - fun `content is correct after removed left son with only left son (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() - tree.remove('q') - assert(isTreeConsistsOf(setOf('o' to 0, 's' to 5, 'z' to 2), tree)) - } - - @Test - fun `size decreased by 1 after removed left son with only left son (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() - tree.remove('q') - assert(tree.size() == 3L) - } - - @Test - fun `structure is correct after removed left son with only leftt son (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() - tree.remove('q') - assert(isTreeSStructureThat(tree, arrayOf('s', 'o', 'z'), listOf(Triple(0, 1, 2)))) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed LSon with only LSon (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() - tree.remove('q') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRemoveLeftSonWithOnlyRightSonTest(): AVLTreeForTest { - val leftSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) - val root = AVLVertex('s', 5, leftSon, AVLVertex('z', 2), 1) - return AVLTreeForTest(root, 4L) - } - - @Test - fun `remove left son with only right son returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() - assert(tree.remove('q') == 9) - } - - @Test - fun `content is correct after removed left son with only right son (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() - tree.remove('q') - assert(isTreeConsistsOf(setOf('r' to 7, 's' to 5, 'z' to 2), tree)) - } - - @Test - fun `size decreased by 1 after removed left son with only right son (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() - tree.remove('q') - assert(tree.size() == 3L) - } - - @Test - fun `structure is correct after removed left son with only right son (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() - tree.remove('q') - assert(isTreeSStructureThat(tree, arrayOf('s', 'r', 'z'), listOf(Triple(0, 1, 2)))) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed LSon with only RSon (needn't balanceing)`() { - val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() - tree.remove('q') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRemoveRightSonWithOnlyLeftSonTest(): AVLTreeForTest { - val rightSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) - val root = AVLVertex('i', 1, AVLVertex('b', 6), rightSon, -1) - return AVLTreeForTest(root, 4L) - } - - @Test - fun `remove right son with only left son returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() - assert(tree.remove('q') == 9) - } - - @Test - fun `content is correct after removed right son with only left son (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() - tree.remove('q') - assert(isTreeConsistsOf(setOf('o' to 0, 'b' to 6, 'i' to 1), tree)) - } - - @Test - fun `size decreased by 1 after removed right son with only left son (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() - tree.remove('q') - assert(tree.size() == 3L) - } - - @Test - fun `structure is correct after removed right son with only left son (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() - tree.remove('q') - assert(isTreeSStructureThat(tree, arrayOf('i', 'b', 'o'), listOf(Triple(0, 1, 2)))) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed RSon with only LSon (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() - tree.remove('q') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRemoveRightSonWithOnlyRightSonTest(): AVLTreeForTest { - val rightSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) - val root = AVLVertex('i', 1, AVLVertex('b', 6), rightSon, -1) - return AVLTreeForTest(root, 4L) - } - - @Test - fun `remove right son with only right son returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() - assert(tree.remove('q') == 9) - } - - @Test - fun `content is correct after removed right son with only right son (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() - tree.remove('q') - assert(isTreeConsistsOf(setOf('r' to 7, 'b' to 6, 'i' to 1), tree)) - } - - @Test - fun `size decreased by 1 after removed right son with only right son (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() - tree.remove('q') - assert(tree.size() == 3L) - } - - @Test - fun `structure is correct after removed right son with only right son (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() - tree.remove('q') - assert(isTreeSStructureThat(tree, arrayOf('i', 'b', 'r'), listOf(Triple(0, 1, 2)))) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed RSon with only RSon (needn't balanceing)`() { - val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() - tree.remove('q') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRemoveRootWithOnlyLeftSon(): AVLTreeForTest { - return AVLTreeForTest(AVLVertex("be", "es", (AVLVertex("and", "et")), null, 1), 2L) - } - - @Test - fun `remove root with only left son returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithOnlyLeftSon() - assert(tree.remove("be") == "es") - } - - @Test - fun `content is correct after removed root with only left son (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithOnlyLeftSon() - tree.remove("be") - assert(isTreeConsistsOf(setOf("and" to "et"), tree)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed root with only LSon (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithOnlyLeftSon() - tree.remove("and") - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRemoveRootWithOnlyRightSon(): AVLTreeForTest { - return AVLTreeForTest(AVLVertex("and", "et", null, (AVLVertex("be", "es")), -1), 2L) - } - - @Test - fun `remove root with only right son returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithOnlyRightSon() - assert(tree.remove("and") == "et") - } - - @Test - fun `content is correct after removed root with only right son (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithOnlyRightSon() - tree.remove("and") - assert(isTreeConsistsOf(setOf("be" to "es"), tree)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed root with only RSon (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithOnlyRightSon() - tree.remove("and") - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRemoveSonWithBothSons(): AVLTreeForTest { - val eVrt = AVLVertex('e', 'E', AVLVertex('c', 'C'), null, 1) - val bVrt = AVLVertex('b', 'B', AVLVertex('a', 'A'), eVrt, -1) - val leftSon = AVLVertex('f', 'F', bVrt, AVLVertex('i', 'I', null, AVLVertex('k', 'K'), -1), 1) - val qVrt = AVLVertex('q', 'Q', null, AVLVertex('s', 'S'), -1) - val wVrt = AVLVertex('w', 'W', null, AVLVertex('z', 'Z'), -1) - val root = AVLVertex('n', 'N', leftSon, AVLVertex('u', 'U', qVrt, wVrt, 0), 1) - return AVLTreeForTest(root, 13L) - } - - @Test - fun `remove left son with both sons returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - assert(tree.remove('f') == 'F') - } - - @Test - fun `content is correct after removed left son with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - tree.remove('f') - val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'e' to 'E', - 'i' to 'I', - 'z' to 'Z', - 'k' to 'K', - 'n' to 'N', - 'u' to 'U', - 'q' to 'Q', - 's' to 'S', - 'w' to 'W', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed left son with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - tree.remove('f') - assert(tree.size() == 12L) - } - - @Test - fun `structure is correct after removed left son with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - tree.remove('f') - val expectedDependences = - listOf( - Triple(0, 1, 7), - Triple(1, 2, 5), - Triple(2, 3, 4), - Triple(5, null, 6), - Triple(7, 8, 10), - Triple(10, null, 11), - ) - val expectedOrder = arrayOf('n', 'e', 'b', 'a', 'c', 'i', 'k', 'u', 'q', 's', 'w', 'z') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed LSon with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - tree.remove('f') - assert(isSonsHeightDiffCorrect(tree)) - } - - @Test - fun `remove right son with both sons returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - assert(tree.remove('u') == 'U') - } - - @Test - fun `content is correct after removed right son with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - tree.remove('u') - val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'e' to 'E', - 'i' to 'I', - 'z' to 'Z', - 'k' to 'K', - 'n' to 'N', - 'f' to 'F', - 'q' to 'Q', - 's' to 'S', - 'w' to 'W', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed right son with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - tree.remove('u') - assert(tree.size() == 12L) - } - - @Test - fun `structure is correct after removed right son with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - tree.remove('u') - val expectedDependences = - listOf( - Triple(0, 1, 8), - Triple(1, 2, 6), - Triple(2, 3, 4), - Triple(6, null, 7), - Triple(4, 5, null), - Triple(8, 9, 10), - Triple(10, null, 11), - ) - val expectedOrder = arrayOf('n', 'f', 'b', 'a', 'e', 'c', 'i', 'k', 's', 'q', 'w', 'z') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed RSon with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveSonWithBothSons() - tree.remove('u') - assert(isSonsHeightDiffCorrect(tree)) - } - - @Test - fun `remove fun return null if entry's key isn't exists(2)`() { - val tree = makeTreeForRemoveSonWithBothSons() - assert(tree.remove('x') == null) - } - - private fun makeTreeForRemoveRootWithBothSonsTest(): AVLTreeForTest { - val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), AVLVertex('e', 5), 0) - val rightSon = AVLVertex('i', 9, null, AVLVertex('k', 11), -1) - val root = AVLVertex('f', 6, leftSon, rightSon, 0) - return AVLTreeForTest(root, 6L) - } - - @Test - fun `remove root with both sons returns due value (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithBothSonsTest() - assert(tree.remove('f') == 6) - } - - @Test - fun `content is correct after removed root with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithBothSonsTest() - tree.remove('f') - val expectedContent = setOf('a' to 1, 'b' to 2, 'e' to 5, 'i' to 9, 'k' to 11) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed root with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithBothSonsTest() - tree.remove('f') - assert(tree.size() == 5L) - } - - @Test - fun `structure is correct after removed root with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithBothSonsTest() - tree.remove('f') - val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, null, 4)) - val expectedOrder = arrayOf('e', 'b', 'a', 'i', 'k') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed root with both sons (needn't balanceing)`() { - val tree = makeTreeForRemoveRootWithBothSonsTest() - tree.remove('f') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRemoveWithLeftRotate1Test(): AVLTreeForTest { - val rightSonSRightSon = AVLVertex('o', false, null, AVLVertex('p', true), -1) - val rightSon = AVLVertex('m', true, AVLVertex('l', true), rightSonSRightSon, -1) - val root = AVLVertex('k', true, AVLVertex('i', false, AVLVertex('a', false), null, 1), rightSon, -1) - return AVLTreeForTest(root, 7L) - } - - private fun makeTreeForRemoveWithLeftRotate2Test(): AVLTreeForTest { - val rightSonSRightSon = AVLVertex('o', false, AVLVertex('n', true), AVLVertex('p', true), 0) - val rightSon = AVLVertex('m', true, AVLVertex('l', true), rightSonSRightSon, -1) - val root = AVLVertex('k', true, AVLVertex('i', false, AVLVertex('a', false), null, 1), rightSon, -1) - return AVLTreeForTest(root, 8L) - } - - // new subroot initially had sonSHeightDiff == -1 in (1) and 0 in (2) - @Test - fun `returns due value after removed and rotated left(1)`() { - val tree = makeTreeForRemoveWithLeftRotate1Test() - assert(tree.remove('l') == true) - } - - @Test - fun `returns due value after removed and rotated left(2)`() { - val tree = makeTreeForRemoveWithLeftRotate2Test() - assert(tree.remove('l') == true) - } - - @Test - fun `content is correct after removed and rotated left (1)`() { - val tree = makeTreeForRemoveWithLeftRotate1Test() - tree.remove('l') - val expectedContent = - setOf( - 'k' to true, - 'i' to false, - 'm' to true, - 'o' to false, - 'p' to true, - 'a' to false, - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `content is correct after removed and rotated left (2)`() { - val tree = makeTreeForRemoveWithLeftRotate2Test() - tree.remove('l') - val expectedContent = - setOf( - 'k' to true, - 'i' to false, - 'm' to true, - 'o' to false, - 'p' to true, - 'n' to true, - 'a' to false, - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed and rotated left (1)`() { - val tree = makeTreeForRemoveWithLeftRotate1Test() - tree.remove('l') - assert(tree.size() == 6L) - } - - @Test - fun `size decreased by 1 after removed and rotated left (2)`() { - val tree = makeTreeForRemoveWithLeftRotate2Test() - tree.remove('l') - assert(tree.size() == 7L) - } - - @Test - fun `structure is correct after removed and rotated left (1)`() { - val tree = makeTreeForRemoveWithLeftRotate1Test() - tree.remove('l') - val expectedDependences = listOf(Triple(0, 1, 3), Triple(3, 4, 5), Triple(1, 2, null)) - val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'p') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `structure is correct after removed and rotated left (2)`() { - val tree = makeTreeForRemoveWithLeftRotate2Test() - tree.remove('l') - val expectedDependences = - listOf( - Triple(0, 1, 3), - Triple(3, 4, 6), - Triple(4, null, 5), - Triple(1, 2, null), - ) - val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'n', 'p') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed and rotated left (1)`() { - val tree = makeTreeForRemoveWithLeftRotate1Test() - tree.remove('l') - assert(isSonsHeightDiffCorrect(tree)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed and rotated left (2)`() { - val tree = makeTreeForRemoveWithLeftRotate2Test() - tree.remove('l') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRemoveWithRightRotate1Test(): AVLTreeForTest { - val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), null, 1) - val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) - val root = AVLVertex('k', true, leftSon, AVLVertex('m', true, null, AVLVertex('o', false), -1), 1) - return AVLTreeForTest(root, 7L) - } - - private fun makeTreeForRemoveWithRightRotate2Test(): AVLTreeForTest { - val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), AVLVertex('c', true), 0) - val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) - val root = AVLVertex('k', true, leftSon, AVLVertex('m', true, null, AVLVertex('o', false), -1), 1) - return AVLTreeForTest(root, 8L) - } - - // new subroot initially had sonSHeightDiff == 1 in (1) and 0 in (2) - @Test - fun `returns due value after removed and rotated right(1)`() { - val tree = makeTreeForRemoveWithRightRotate1Test() - assert(tree.remove('e') == false) - } - - @Test - fun `returns due value after removed and rotated right(2)`() { - val tree = makeTreeForRemoveWithRightRotate2Test() - assert(tree.remove('e') == false) - } - - @Test - fun `content is correct after removed and rotated right (1)`() { - val tree = makeTreeForRemoveWithRightRotate1Test() - tree.remove('e') - val expectedContent = - setOf( - 'k' to true, - 'b' to true, - 'm' to true, - 'o' to false, - 'd' to true, - 'a' to false, - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `content is correct after removed and rotated right (2)`() { - val tree = makeTreeForRemoveWithRightRotate2Test() - tree.remove('e') - val expectedContent = - setOf( - 'k' to true, - 'b' to true, - 'm' to true, - 'o' to false, - 'd' to true, - 'a' to false, - 'c' to true, - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed and rotated right (1)`() { - val tree = makeTreeForRemoveWithRightRotate1Test() - tree.remove('e') - assert(tree.size() == 6L) - } - - @Test - fun `size decreased by 1 after removed and rotated right (2)`() { - val tree = makeTreeForRemoveWithRightRotate2Test() - tree.remove('e') - assert(tree.size() == 7L) - } - - @Test - fun `structure is correct after removed and rotated right (1)`() { - val tree = makeTreeForRemoveWithRightRotate1Test() - tree.remove('e') - val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, null, 5)) - val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'm', 'o') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `structure is correct after removed and rotated right (2)`() { - val tree = makeTreeForRemoveWithRightRotate2Test() - tree.remove('e') - val expectedDependences = - listOf( - Triple(0, 1, 5), - Triple(1, 2, 3), - Triple(5, null, 6), - Triple(3, 4, null), - ) - val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'c', 'm', 'o') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed and rotated right (1)`() { - val tree = makeTreeForRemoveWithRightRotate1Test() - tree.remove('e') - assert(isSonsHeightDiffCorrect(tree)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed and rotated right (2)`() { - val tree = makeTreeForRemoveWithRightRotate2Test() - tree.remove('e') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRotateLeftChangesRootRemoveTest(): AVLTreeForTest { - val root = AVLVertex(1, 1, AVLVertex(0, 0), AVLVertex(3, 3, AVLVertex(2, 2), AVLVertex(5, 5)), -1) - return AVLTreeForTest(root, 5L) - } - - @Test - fun `returns due value after removed and rotated right(rotateLeft changed root)`() { - val tree = makeTreeForRotateLeftChangesRootRemoveTest() - assert(tree.remove(0) == 0) - } - - @Test - fun `content is correct after removed (rotateLeft changed root)`() { - val tree = makeTreeForRotateLeftChangesRootRemoveTest() - tree.remove(0) - val expectedContent = setOf(1 to 1, 2 to 2, 3 to 3, 5 to 5) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed (rotateLeft changed root)`() { - val tree = makeTreeForRotateLeftChangesRootRemoveTest() - tree.remove(0) - assert(tree.size() == 4L) - } - - @Test - fun `structure is correct after removed (rotateLeft changed root)`() { - val tree = makeTreeForRotateLeftChangesRootRemoveTest() - tree.remove(0) - val expectedDependences = listOf(Triple(0, 1, 3), Triple(1, null, 2)) - val expectedOrder = arrayOf(3, 1, 2, 5) - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed (rotateLeft changed root)`() { - val tree = makeTreeForRotateLeftChangesRootRemoveTest() - tree.remove(0) - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForRotateRightChangesRootRemoveTest(): AVLTreeForTest { - val root = AVLVertex(-1, 1, AVLVertex(-3, 3, AVLVertex(-5, 5), AVLVertex(-2, 2)), AVLVertex(0, 0), 1) - return AVLTreeForTest(root, 5L) - } - - @Test - fun `returns due value after removed and rotated right(rotateRight changed root)`() { - val tree = makeTreeForRotateRightChangesRootRemoveTest() - assert(tree.remove(0) == 0) - } - - @Test - fun `content is correct after removed (rotateRight changed root)`() { - val tree = makeTreeForRotateRightChangesRootRemoveTest() - tree.remove(0) - val expectedContent = setOf(-1 to 1, -2 to 2, -3 to 3, -5 to 5) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed (rotateRight changed root)`() { - val tree = makeTreeForRotateRightChangesRootRemoveTest() - tree.remove(0) - assert(tree.size() == 4L) - } - - @Test - fun `structure is correct after removed (rotateRight changed root)`() { - val tree = makeTreeForRotateRightChangesRootRemoveTest() - tree.remove(0) - val expectedDependences = listOf(Triple(0, 1, 2), Triple(2, 3, null)) - val expectedOrder = arrayOf(-3, -5, -1, -2) - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed (rotateRight changed root)`() { - val tree = makeTreeForRotateRightChangesRootRemoveTest() - tree.remove(0) - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForBigRotateLeftChangesRootRemoveTest(): AVLTreeForTest { - val rightSonSLeftSon = AVLVertex('d', 'D', AVLVertex('c', 'C'), AVLVertex('e', 'E')) - val rightSon = AVLVertex('f', 'F', rightSonSLeftSon, AVLVertex('g', 'G'), 1) - val root = AVLVertex('b', 'B', AVLVertex('a', 'A', AVLVertex(' ', ' '), null, 1), rightSon, -1) - return AVLTreeForTest(root, 8L) - } - - @Test - fun `remove returns due value(bigRotateLeft changed root)`() { - val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() - assert(tree.remove(' ') == ' ') - } - - @Test - fun `content is correct after removed (bigRotateLeft changed root)`() { - val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() - tree.remove(' ') - val expectedContent = - setOf( - 'd' to 'D', - 'c' to 'C', - 'e' to 'E', - 'f' to 'F', - 'g' to 'G', - 'b' to 'B', - 'a' to 'A', - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed (bigRotateLeft changed root)`() { - val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() - tree.remove(' ') - assert(tree.size() == 7L) - } - - @Test - fun `structure is correct after removed (bigRotateLeft changed root)`() { - val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() - tree.remove(' ') - val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, 5, 6)) - val expectedOrder = arrayOf('d', 'b', 'a', 'c', 'f', 'e', 'g') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed (bigRotateLeft changed root)`() { - val tree = makeTreeForBigRotateLeftChangesRootRemoveTest() - tree.remove(' ') - assert(isSonsHeightDiffCorrect(tree)) - } - - private fun makeTreeForBigRotateRightChangesRootRemoveTest(): AVLTreeForTest { - val leftSonSRightSon = AVLVertex('e', 5, AVLVertex('c', 3), AVLVertex('d', 4)) - val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), leftSonSRightSon, -1) - val root = AVLVertex('f', 8, leftSon, AVLVertex('i', 9, null, AVLVertex('k', 10), -1), 1) - return AVLTreeForTest(root, 8L) - } - - @Test - fun `remove returns due value(bigRotateRight changed root)`() { - val tree = makeTreeForBigRotateRightChangesRootRemoveTest() - assert(tree.remove('k') == 10) - } - - @Test - fun `content is correct after removed (bigRotateRight changed root)`() { - val tree = makeTreeForBigRotateRightChangesRootRemoveTest() - tree.remove('k') - val expectedContent = - setOf( - 'a' to 1, - 'b' to 2, - 'c' to 3, - 'd' to 4, - 'e' to 5, - 'i' to 9, - 'f' to 8, - ) - assert(isTreeConsistsOf(expectedContent, tree)) - } - - @Test - fun `size decreased by 1 after removed (bigRotateRight changed root)`() { - val tree = makeTreeForBigRotateRightChangesRootRemoveTest() - tree.remove('k') - assert(tree.size() == 7L) - } - - @Test - fun `structure is correct after removed (bigRotateRight changed root)`() { - val tree = makeTreeForBigRotateRightChangesRootRemoveTest() - tree.remove('k') - val expectedDependences = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, 5, 6)) - val expectedOrder = arrayOf('e', 'b', 'a', 'c', 'f', 'd', 'i') - assert(isTreeSStructureThat(tree, expectedOrder, expectedDependences)) - } - - @Test - fun `vertexes' sonsHeightDiff are correct after removed (bigRotateRight changed root)`() { - val tree = makeTreeForBigRotateRightChangesRootRemoveTest() - tree.remove('k') - assert(isSonsHeightDiffCorrect(tree)) - } -} diff --git a/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt b/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt new file mode 100644 index 0000000..87f6da8 --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt @@ -0,0 +1,60 @@ +package trees.avlTree + +import main.vertexes.AVLVertex + +object AuxiliaryFunctions { + fun isTreeConsistsOf( + expectedContent: Set>, + tree: AVLTreeForTest, + ): Boolean { + val vertexes = tree.getVertexesInDFSOrder() + val pairsFromVertexes = (Array(vertexes.size) { i -> (vertexes[i].key to vertexes[i].value) }).toSet() + return pairsFromVertexes == expectedContent + } + + fun isTreeSStructureThat( + tree: AVLTreeForTest, + order: Array, + deps: List>, + ): Boolean { + // Triple consists of indexes in order of (1)vertex, one's (2)leftSon and (3)RightSon + val vertexes = tree.getVertexesInDFSOrder() + if (vertexes.size != order.size) return false + for (i in order.indices) + if (order[i] != vertexes[i].key) return false + for (dep in deps) { + if (dep.component2() != null) { + if (vertexes[dep.component1()].leftSon != vertexes[dep.component2() as Int]) { + return false + } + } + if (dep.component3() != null) { + if (vertexes[dep.component1()].rightSon != vertexes[dep.component3() as Int]) { + return false + } + } + } + return true + } + + fun isSonsHeightDiffCorrect(tree: AVLTreeForTest): Boolean { + val vertexes = tree.getVertexesInDFSOrder() + val heights = tree.getHeights() + if (vertexes.size != heights.size) return false + for (vertex in vertexes) { + val expectedSonsHeightDiff = + when ((vertex.leftSon == null) to (vertex.rightSon == null)) { + true to true -> 0 + true to false -> -1 - (heights[(vertex.rightSon as AVLVertex).key] ?: return false) + false to true -> 1 + (heights[(vertex.leftSon as AVLVertex).key] ?: return false) + else -> { + val heightOfLeftSubtree = heights[(vertex.leftSon as AVLVertex).key] ?: return false + val heightOfRightSubtree = heights[(vertex.rightSon as AVLVertex).key] ?: return false + heightOfLeftSubtree - heightOfRightSubtree + } + } + if (expectedSonsHeightDiff != vertex.sonsHeightDiff) return false + } + return true + } +} diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt new file mode 100644 index 0000000..7412eb9 --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt @@ -0,0 +1,222 @@ +package trees.avlTree.putTest + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class HaveToDoBigRotation { + private fun makeTreeForHaveToDoBigLeftRotationPutTest(): AVLTreeForTest { + val rightSonSRightSon = AVLVertex('i', 'I', AVLVertex('g', 'G'), AVLVertex('j', 'J')) + val rightSon = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSonSRightSon, -1) + val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) + return AVLTreeForTest(root, 8L) + } + + // (1) - add grandson's right son, (2) add grandson's left son + @Test + fun `content is correct after entry was added (big left rotation) (1)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('f', 'F') + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'g' to 'G', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `content is correct after entry was added (big left rotation) (2)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('h', 'H') + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'g' to 'G', + 'i' to 'I', + 'j' to 'J', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size increased by 1 after entry was added (big left rotation) (1)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('f', 'F') + assert(tree.size() == 9L) + } + + @Test + fun `size increased by 1 after entry was added (big left rotation) (2)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('h', 'H') + assert(tree.size() == 9L) + } + + @Test + fun `structure is correct after entry was added (big left rotation) (1)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('f', 'F') + val expectedDependencies = + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 7), + Triple(4, 5, 6), + Triple(7, null, 8), + ) + val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'f', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `structure is correct after entry was added (big left rotation) (2)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('h', 'H') + val expectedDependencies = + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 6), + Triple(4, 5, null), + Triple(6, 7, 8), + ) + val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'i', 'h', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after entry was added (big left rotation) (1)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('f', 'F') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `sonsHeightDiff values are correct after entry was added (big left rotation) (2)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('h', 'H') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToDoBigRightRotationPutTest(): AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', 'B', AVLVertex('a', 'A'), AVLVertex('d', 'D')) + val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('g', 'G'), 1) + val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I', null, AVLVertex('j', 'J'), -1), 1) + return AVLTreeForTest(root, 8L) + } + + // (1) - add grandson's left son, (2) add grandson's right son + @Test + fun `content is correct after entry was added (big right rotation) (1)`() { + val tree = makeTreeForHaveToDoBigRightRotationPutTest() + tree.put('c', 'C') + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'h' to 'H', + 'g' to 'G', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `content is correct after entry was added (big right rotation) (2)`() { + val tree = makeTreeForHaveToDoBigRightRotationPutTest() + tree.put('e', 'E') + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'f' to 'F', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'g' to 'G', + 'i' to 'I', + 'j' to 'J', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size increased by 1 after entry was added (big right rotation) (1)`() { + val tree = makeTreeForHaveToDoBigRightRotationPutTest() + tree.put('c', 'C') + assert(tree.size() == 9L) + } + + @Test + fun `size increased by 1 after entry was added (big right rotation) (2)`() { + val tree = makeTreeForHaveToDoBigRightRotationPutTest() + tree.put('e', 'E') + assert(tree.size() == 9L) + } + + @Test + fun `structure is correct after entry was added (big right rotation) (1)`() { + val tree = makeTreeForHaveToDoBigRightRotationPutTest() + tree.put('c', 'C') + val expectedDependencies = + listOf( + Triple(0, 1, 7), + Triple(7, null, 8), + Triple(1, 2, 5), + Triple(5, null, 6), + Triple(2, 3, 4), + ) + val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'c', 'f', 'g', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `structure is correct after entry was added (big right rotation) (2)`() { + val tree = makeTreeForHaveToDoBigRightRotationPutTest() + tree.put('e', 'E') + val expectedDependencies = + listOf( + Triple(0, 1, 7), + Triple(7, null, 8), + Triple(1, 2, 4), + Triple(2, 3, null), + Triple(4, 5, 6), + ) + val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'f', 'e', 'g', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after entry was added (big right rotation) (1)`() { + val tree = makeTreeForHaveToDoBigRightRotationPutTest() + tree.put('c', 'C') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `sonsHeightDiff values are correct after entry was added (big right rotation) (2)`() { + val tree = makeTreeForHaveToDoBigLeftRotationPutTest() + tree.put('e', 'E') + assert(isSonsHeightDiffCorrect(tree)) + } +} diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt new file mode 100644 index 0000000..122ffca --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt @@ -0,0 +1,102 @@ +package trees.avlTree.putTest + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class HaveToRotateLeft { + private fun makeTreeForHaveToRotateLeftPutTest(): AVLTreeForTest { + val rightSonSRightSon = AVLVertex('h', 'H', AVLVertex('f', 'F'), AVLVertex('i', 'I')) + val rightSon = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSonSRightSon, -1) + val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) + return AVLTreeForTest(root, 8L) + } + @Test + fun `content is correct after entry was added`() { + val tree = makeTreeForHaveToRotateLeftPutTest() + tree.put('j', 'J') + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size increased by 1 after entry was added`() { + val tree = makeTreeForHaveToRotateLeftPutTest() + tree.put('j', 'J') + assert(tree.size() == 9L) + } + + @Test + fun `structure is correct after entry was added`() { + val tree = makeTreeForHaveToRotateLeftPutTest() + tree.put('j', 'J') + val expectedDependencies = + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 7), + Triple(4, 5, 6), + Triple(7, null, 8), + ) + val expectedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after entry was added`() { + val tree = makeTreeForHaveToRotateLeftPutTest() + tree.put('j', 'J') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToChangeRootByRotateLeftPutTest(): AVLTreeForTest { + val rightSon = AVLVertex('h', 'H', AVLVertex('f', 'F'), AVLVertex('i', 'I')) + val root = AVLVertex('e', 'E', AVLVertex('d', 'D'), rightSon, -1) + return AVLTreeForTest(root, 5L) + } + + @Test + fun `content is correct after entry was added (rotateLeft changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() + tree.put('j', 'J') + val expectedContent = setOf('d' to 'D', 'e' to 'E', 'h' to 'H', 'f' to 'F', 'i' to 'I', 'j' to 'J') + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size increased by 1 after entry was added (rotateLeft changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() + tree.put('j', 'J') + assert(tree.size() == 6L) + } + + @Test + fun `structure is correct after entry was added (rotateLeft changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() + tree.put('j', 'J') + val expectedDependencies = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, null, 5)) + val expectedOrder = arrayOf('h', 'e', 'd', 'f', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after entry was added (rotateLeft changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateLeftPutTest() + tree.put('j', 'J') + assert(isSonsHeightDiffCorrect(tree)) + } +} diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt new file mode 100644 index 0000000..553c9fe --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt @@ -0,0 +1,102 @@ +package trees.avlTree.putTest + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest +class HaveToRotateRight { + private fun makeTreeForHaveToRotateRightPutTest(): AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) + val leftSon = AVLVertex('f', 'F', leftSonSLeftSon, AVLVertex('e', 'E'), 1) + val root = AVLVertex('h', 'H', leftSon, AVLVertex('i', 'I', null, AVLVertex('j', 'J'), -1), 1) + return AVLTreeForTest(root, 8L) + } + + @Test + fun `content is correct after entry was added `() { + val tree = makeTreeForHaveToRotateRightPutTest() + tree.put('a', 'A') + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size increased by 1 after entry was added`() { + val tree = makeTreeForHaveToRotateRightPutTest() + tree.put('a', 'A') + assert(tree.size() == 9L) + } + + @Test + fun `structure is correct after entry was added`() { + val tree = makeTreeForHaveToRotateRightPutTest() + tree.put('a', 'A') + val expectedDependencies = + listOf( + Triple(0, 1, 7), + Triple(1, 2, 4), + Triple(2, 3, null), + Triple(4, 5, 6), + Triple(7, null, 8), + ) + val expectedOrder = arrayOf('h', 'c', 'b', 'a', 'f', 'd', 'e', 'i', 'j') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after entry was added`() { + val tree = makeTreeForHaveToRotateRightPutTest() + tree.put('a', 'A') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForHaveToChangeRootByRotateRightPutTest(): AVLTreeForTest { + val leftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) + val root = AVLVertex('f', 'F', leftSon, AVLVertex('e', 'E'), 1) + return AVLTreeForTest(root, 5L) + } + + @Test + fun `content is correct after entry was added (rotateRight changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() + tree.put('a', 'A') + val expectedContent = setOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'd' to 'D', 'e' to 'E', 'f' to 'F') + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size increased by 1 after entry was added (rotateRight changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() + tree.put('a', 'A') + assert(tree.size() == 6L) + } + + @Test + fun `structure is correct after entry was added (rotateRight changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() + tree.put('a', 'A') + val expectedDependencies = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, 4, 5)) + val expectedOrder = arrayOf('c', 'b', 'a', 'f', 'd', 'e') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after entry was added (rotateRight changes root)`() { + val tree = makeTreeForHaveToChangeRootByRotateRightPutTest() + tree.put('a', 'A') + assert(isSonsHeightDiffCorrect(tree)) + } +} diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt b/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt new file mode 100644 index 0000000..2323fd2 --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt @@ -0,0 +1,27 @@ +package trees.avlTree.putTest + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class Other { + private fun makeSize1Tree(): AVLTreeForTest { + return AVLTreeForTest(AVLVertex('b', '+'), 1L) + } + + @Test + fun `tree has no changes after entry with existed key and param replaceIfExists = false was added`() { + val tree = makeSize1Tree() + tree.put('b', '-', false) + assert(tree.size() == 1L) + assert(tree.getRootT()?.value == '+') + } + + @Test + fun `content is correct after init by map`() { + val tree = AVLTreeForTest(hashMapOf('a' to 'A', 'b' to 'B')) + val expectedContent = setOf('a' to 'A', 'b' to 'B') + assert(isTreeConsistsOf(expectedContent, tree)) + } +} \ No newline at end of file diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt b/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt new file mode 100644 index 0000000..352eea4 --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt @@ -0,0 +1,113 @@ +package trees.avlTree.putTest + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class WithoutBalancing { + private fun makeEmptyTree(): AVLTreeForTest { + return AVLTreeForTest() + } + + @Test + fun `entry became root after it was added to empty tree`() { + val tree = makeEmptyTree() + tree.put(0, '0') + val root = tree.getRootT() + assert((root?.key to root?.value) == (0 to '0')) + } + + @Test + fun `size equals 1 after entry was added to empty tree`() { + val tree = makeEmptyTree() + tree.put(0, '0') + assert(tree.size() == 1L) + } + + private fun makeSize1Tree(): AVLTreeForTest { + return AVLTreeForTest(AVLVertex('b', '+'), 1L) // init tree by root and size (don't use put) + } + + @Test + fun `entry with larger key became right son after it was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('c', '+') + val root = tree.getRootT() + assert((root?.rightSon?.key to root?.rightSon?.value) == ('c' to '+')) + } + + @Test + fun `entry with lesser key became left son after it was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('a', '-') + val root = tree.getRootT() + assert((root?.leftSon?.key to root?.leftSon?.value) == ('a' to '-')) + } + + @Test + fun `root's sonsHeightDiff decreased by 1 after entry with larger key was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('c', '+') + val root = tree.getRootT() + assert(root?.sonsHeightDiff == -1) + } + + @Test + fun `root's sonsHeightDiff increased by 1 after entry with lesser key was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('a', '-') + val root = tree.getRootT() + assert(root?.sonsHeightDiff == 1) + } + + @Test + fun `size equals 2 after entry with larger key was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('c', '+') + assert(tree.size() == 2L) + } + + @Test + fun `size equals 2 after entry with lesser key was added to size 1 tree`() { + val tree = makeSize1Tree() + tree.put('a', '-') + assert(tree.size() == 2L) + } + + private fun makeTreeForNeedNotBalancingPutTest(): AVLTreeForTest { + return AVLTreeForTest(AVLVertex(4, 'A', AVLVertex(1, 'I'), AVLVertex(5, 'S')), 3L) + } + + @Test + fun `content is correct after entry was added`() { + val tree = makeTreeForNeedNotBalancingPutTest() + tree.put(0, 'O') + assert(isTreeConsistsOf(setOf(0 to 'O', 1 to 'I', 5 to 'S', 4 to 'A'), tree)) + } + + @Test + fun `size increased by 1 after entry was added to 'size 2+' tree`() { + val tree = makeTreeForNeedNotBalancingPutTest() + tree.put(0, 'O') + assert(tree.size() == 4L) + } + + @Test + fun `structure is correct after entry was added to 'size 2+' tree`() { + val tree = makeTreeForNeedNotBalancingPutTest() + tree.put(0, 'O') + val expectedDependencies = listOf(Triple(0, 1, 3), Triple(1, 2, null)) + assert(isTreeSStructureThat(tree, arrayOf(4, 1, 0, 5), expectedDependencies)) + } + + @Test + fun `vertexes' sonsHeightDiff are correct after entry was added to 'size 2+' tree`() { + val tree = makeTreeForNeedNotBalancingPutTest() + tree.put(0, 'O') + assert(isSonsHeightDiffCorrect(tree)) + } +} + diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt new file mode 100644 index 0000000..99d6788 --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt @@ -0,0 +1,116 @@ +package trees.avlTree.removeTest + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class HaveToDoBigRotation { + private fun makeTreeForBigLeftRotationChangesRootRemoveTest(): AVLTreeForTest { + val rightSonSLeftSon = AVLVertex('d', 'D', AVLVertex('c', 'C'), AVLVertex('e', 'E')) + val rightSon = AVLVertex('f', 'F', rightSonSLeftSon, AVLVertex('g', 'G'), 1) + val root = AVLVertex('b', 'B', AVLVertex('a', 'A', AVLVertex(' ', ' '), null, 1), rightSon, -1) + return AVLTreeForTest(root, 8L) + } + + @Test + fun `remove returns due value after deletion (bigRotateLeft changes root)`() { + val tree = makeTreeForBigLeftRotationChangesRootRemoveTest() + assert(tree.remove(' ') == ' ') + } + + @Test + fun `content is correct after deletion (bigRotateLeft changes root)`() { + val tree = makeTreeForBigLeftRotationChangesRootRemoveTest() + tree.remove(' ') + val expectedContent = + setOf( + 'd' to 'D', + 'c' to 'C', + 'e' to 'E', + 'f' to 'F', + 'g' to 'G', + 'b' to 'B', + 'a' to 'A', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after deletion (bigRotateLeft changes root)`() { + val tree = makeTreeForBigLeftRotationChangesRootRemoveTest() + tree.remove(' ') + assert(tree.size() == 7L) + } + + @Test + fun `structure is correct after deletion (bigRotateLeft changes root)`() { + val tree = makeTreeForBigLeftRotationChangesRootRemoveTest() + tree.remove(' ') + val expectedDependencies = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, 5, 6)) + val expectedOrder = arrayOf('d', 'b', 'a', 'c', 'f', 'e', 'g') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after deletion (bigRotateLeft changes root)`() { + val tree = makeTreeForBigLeftRotationChangesRootRemoveTest() + tree.remove(' ') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForBigRightRotationChangesRootRemoveTest(): AVLTreeForTest { + val leftSonSRightSon = AVLVertex('e', 5, AVLVertex('c', 3), AVLVertex('d', 4)) + val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), leftSonSRightSon, -1) + val root = AVLVertex('f', 8, leftSon, AVLVertex('i', 9, null, AVLVertex('k', 10), -1), 1) + return AVLTreeForTest(root, 8L) + } + + @Test + fun `remove returns due value after deletion (bigRotateRight changes root)`() { + val tree = makeTreeForBigRightRotationChangesRootRemoveTest() + assert(tree.remove('k') == 10) + } + + @Test + fun `content is correct after deletion (bigRotateRight changes root)`() { + val tree = makeTreeForBigRightRotationChangesRootRemoveTest() + tree.remove('k') + val expectedContent = + setOf( + 'a' to 1, + 'b' to 2, + 'c' to 3, + 'd' to 4, + 'e' to 5, + 'i' to 9, + 'f' to 8, + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after deletion (bigRotateRight changes root)`() { + val tree = makeTreeForBigRightRotationChangesRootRemoveTest() + tree.remove('k') + assert(tree.size() == 7L) + } + + @Test + fun `structure is correct after deletion (bigRotateRight changes root)`() { + val tree = makeTreeForBigRightRotationChangesRootRemoveTest() + tree.remove('k') + val expectedDependencies = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, 5, 6)) + val expectedOrder = arrayOf('e', 'b', 'a', 'c', 'f', 'd', 'i') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after deletion (bigRotateRight changes root)`() { + val tree = makeTreeForBigRightRotationChangesRootRemoveTest() + tree.remove('k') + assert(isSonsHeightDiffCorrect(tree)) + } +} diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt new file mode 100644 index 0000000..a401fb9 --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt @@ -0,0 +1,165 @@ +package trees.avlTree.removeTest + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class HaveToRotateLeft { + private fun makeTreeForRemoveWithLeftRotation1Test(): AVLTreeForTest { + val rightSonSRightSon = AVLVertex('o', false, null, AVLVertex('p', true), -1) + val rightSon = AVLVertex('m', true, AVLVertex('l', true), rightSonSRightSon, -1) + val root = AVLVertex('k', true, AVLVertex('i', false, AVLVertex('a', false), null, 1), rightSon, -1) + return AVLTreeForTest(root, 7L) + } + + private fun makeTreeForRemoveWithLeftRotation2Test(): AVLTreeForTest { + val rightSonSRightSon = AVLVertex('o', false, AVLVertex('n', true), AVLVertex('p', true), 0) + val rightSon = AVLVertex('m', true, AVLVertex('l', true), rightSonSRightSon, -1) + val root = AVLVertex('k', true, AVLVertex('i', false, AVLVertex('a', false), null, 1), rightSon, -1) + return AVLTreeForTest(root, 8L) + } + + // new subtree's root initially had sonSHeightDiff == -1 in (1) and 0 in (2) + @Test + fun `returns due value after deletion (1)`() { + val tree = makeTreeForRemoveWithLeftRotation1Test() + assert(tree.remove('l') == true) + } + + @Test + fun `returns due value after deletion (2)`() { + val tree = makeTreeForRemoveWithLeftRotation2Test() + assert(tree.remove('l') == true) + } + + @Test + fun `content is correct after deletion (1)`() { + val tree = makeTreeForRemoveWithLeftRotation1Test() + tree.remove('l') + val expectedContent = + setOf( + 'k' to true, + 'i' to false, + 'm' to true, + 'o' to false, + 'p' to true, + 'a' to false, + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `content is correct after deletion (2)`() { + val tree = makeTreeForRemoveWithLeftRotation2Test() + tree.remove('l') + val expectedContent = + setOf( + 'k' to true, + 'i' to false, + 'm' to true, + 'o' to false, + 'p' to true, + 'n' to true, + 'a' to false, + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after deletion (1)`() { + val tree = makeTreeForRemoveWithLeftRotation1Test() + tree.remove('l') + assert(tree.size() == 6L) + } + + @Test + fun `size decreased by 1 after deletion (2)`() { + val tree = makeTreeForRemoveWithLeftRotation2Test() + tree.remove('l') + assert(tree.size() == 7L) + } + + @Test + fun `structure is correct after deletion (1)`() { + val tree = makeTreeForRemoveWithLeftRotation1Test() + tree.remove('l') + val expectedDependencies = listOf(Triple(0, 1, 3), Triple(3, 4, 5), Triple(1, 2, null)) + val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'p') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `structure is correct after deletion (2)`() { + val tree = makeTreeForRemoveWithLeftRotation2Test() + tree.remove('l') + val expectedDependencies = + listOf( + Triple(0, 1, 3), + Triple(3, 4, 6), + Triple(4, null, 5), + Triple(1, 2, null), + ) + val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'n', 'p') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after deletion (1)`() { + val tree = makeTreeForRemoveWithLeftRotation1Test() + tree.remove('l') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `sonsHeightDiff values are correct after deletion (2)`() { + val tree = makeTreeForRemoveWithLeftRotation2Test() + tree.remove('l') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForLeftRotationChangesRootRemoveTest(): AVLTreeForTest { + val root = AVLVertex(1, 1, AVLVertex(0, 0), AVLVertex(3, 3, AVLVertex(2, 2), AVLVertex(5, 5)), -1) + return AVLTreeForTest(root, 5L) + } + + @Test + fun `returns due value after deletion (rotateLeft changes root)`() { + val tree = makeTreeForLeftRotationChangesRootRemoveTest() + assert(tree.remove(0) == 0) + } + + @Test + fun `content is correct after deletion (rotateLeft changes root)`() { + val tree = makeTreeForLeftRotationChangesRootRemoveTest() + tree.remove(0) + val expectedContent = setOf(1 to 1, 2 to 2, 3 to 3, 5 to 5) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after deletion (rotateLeft changes root)`() { + val tree = makeTreeForLeftRotationChangesRootRemoveTest() + tree.remove(0) + assert(tree.size() == 4L) + } + + @Test + fun `structure is correct after deletion (rotateLeft changes root)`() { + val tree = makeTreeForLeftRotationChangesRootRemoveTest() + tree.remove(0) + val expectedDependencies = listOf(Triple(0, 1, 3), Triple(1, null, 2)) + val expectedOrder = arrayOf(3, 1, 2, 5) + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after deletion (rotateLeft changes root)`() { + val tree = makeTreeForLeftRotationChangesRootRemoveTest() + tree.remove(0) + assert(isSonsHeightDiffCorrect(tree)) + } + +} \ No newline at end of file diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt new file mode 100644 index 0000000..c0fc939 --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt @@ -0,0 +1,166 @@ +package trees.avlTree.removeTest + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class HaveToRotateRight { + private fun makeTreeForRemoveWithRightRotation1Test(): AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), null, 1) + val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) + val root = AVLVertex('k', true, leftSon, AVLVertex('m', true, null, AVLVertex('o', false), -1), 1) + return AVLTreeForTest(root, 7L) + } + + private fun makeTreeForRemoveWithRightRotation2Test(): AVLTreeForTest { + val leftSonSLeftSon = AVLVertex('b', true, AVLVertex('a', false), AVLVertex('c', true), 0) + val leftSon = AVLVertex('d', true, leftSonSLeftSon, AVLVertex('e', false), 1) + val root = AVLVertex('k', true, leftSon, AVLVertex('m', true, null, AVLVertex('o', false), -1), 1) + return AVLTreeForTest(root, 8L) + } + + // new subtree's root initially had sonSHeightDiff == 1 in (1) and 0 in (2) + @Test + fun `returns due value after deletion (1)`() { + val tree = makeTreeForRemoveWithRightRotation1Test() + assert(tree.remove('e') == false) + } + + @Test + fun `returns due value after deletion (2)`() { + val tree = makeTreeForRemoveWithRightRotation2Test() + assert(tree.remove('e') == false) + } + + @Test + fun `content is correct after deletion (1)`() { + val tree = makeTreeForRemoveWithRightRotation1Test() + tree.remove('e') + val expectedContent = + setOf( + 'k' to true, + 'b' to true, + 'm' to true, + 'o' to false, + 'd' to true, + 'a' to false, + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `content is correct after deletion (2)`() { + val tree = makeTreeForRemoveWithRightRotation2Test() + tree.remove('e') + val expectedContent = + setOf( + 'k' to true, + 'b' to true, + 'm' to true, + 'o' to false, + 'd' to true, + 'a' to false, + 'c' to true, + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after deletion (1)`() { + val tree = makeTreeForRemoveWithRightRotation1Test() + tree.remove('e') + assert(tree.size() == 6L) + } + + @Test + fun `size decreased by 1 after deletion (2)`() { + val tree = makeTreeForRemoveWithRightRotation2Test() + tree.remove('e') + assert(tree.size() == 7L) + } + + @Test + fun `structure is correct after deletion (1)`() { + val tree = makeTreeForRemoveWithRightRotation1Test() + tree.remove('e') + val expectedDependencies = listOf(Triple(0, 1, 4), Triple(1, 2, 3), Triple(4, null, 5)) + val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'm', 'o') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `structure is correct after deletion (2)`() { + val tree = makeTreeForRemoveWithRightRotation2Test() + tree.remove('e') + val expectedDependencies = + listOf( + Triple(0, 1, 5), + Triple(1, 2, 3), + Triple(5, null, 6), + Triple(3, 4, null), + ) + val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'c', 'm', 'o') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after deletion (1)`() { + val tree = makeTreeForRemoveWithRightRotation1Test() + tree.remove('e') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `sonsHeightDiff values are correct after deletion (2)`() { + val tree = makeTreeForRemoveWithRightRotation2Test() + tree.remove('e') + assert(isSonsHeightDiffCorrect(tree)) + } + + + + private fun makeTreeForRightRotationChangesRootRemoveTest(): AVLTreeForTest { + val root = AVLVertex(-1, 1, AVLVertex(-3, 3, AVLVertex(-5, 5), AVLVertex(-2, 2)), AVLVertex(0, 0), 1) + return AVLTreeForTest(root, 5L) + } + + @Test + fun `returns due value after deletion (rotateRight changes root)`() { + val tree = makeTreeForRightRotationChangesRootRemoveTest() + assert(tree.remove(0) == 0) + } + + @Test + fun `content is correct after deletion (rotateRight changes root)`() { + val tree = makeTreeForRightRotationChangesRootRemoveTest() + tree.remove(0) + val expectedContent = setOf(-1 to 1, -2 to 2, -3 to 3, -5 to 5) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after deletion (rotateRight changes root)`() { + val tree = makeTreeForRightRotationChangesRootRemoveTest() + tree.remove(0) + assert(tree.size() == 4L) + } + + @Test + fun `structure is correct after deletion (rotateRight changes root)`() { + val tree = makeTreeForRightRotationChangesRootRemoveTest() + tree.remove(0) + val expectedDependencies = listOf(Triple(0, 1, 2), Triple(2, 3, null)) + val expectedOrder = arrayOf(-3, -5, -1, -2) + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after deletion (rotateRight changes root)`() { + val tree = makeTreeForRightRotationChangesRootRemoveTest() + tree.remove(0) + assert(isSonsHeightDiffCorrect(tree)) + } +} \ No newline at end of file diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt new file mode 100644 index 0000000..6d73b6f --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt @@ -0,0 +1,338 @@ +package trees.avlTree.removeTest.withoutBalancing + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class Other { + private fun makeEmptyTree(): AVLTreeForTest { + return AVLTreeForTest() + } + + @Test + fun `delete from emptyTree returns null`() { + val tree = makeEmptyTree() + assert(tree.remove(0) == null) + } + + private fun makeSize1Tree(): AVLTreeForTest { + return AVLTreeForTest(AVLVertex('b', '+'), 1L) // init tree by root and size (don't use put) + } + + @Test + fun `tree is empty after root of 'size 1' tree was deleted `() { + val tree = makeSize1Tree() + tree.remove('b') + assert(tree.getVertexesInDFSOrder().isEmpty()) + } + + @Test + fun `size equals 0 after root of 'size 1' tree was deleted`() { + val tree = makeSize1Tree() + tree.remove('b') + assert(tree.size() == 0L) + } + + @Test + fun `remove fun return null if entry's key isn't exists(1)`() { + val tree = makeSize1Tree() + assert(tree.remove('a') == null) + } + + @Test + fun `tree has no changes after deletion by non existed larger key`() { + val tree = makeSize1Tree() + tree.remove('c') + assert(tree.size() == 1L) + assert(tree.getRootT()?.value == '+') + } + + @Test + fun `tree has no changes after deletion by non existed lesser key`() { + val tree = makeSize1Tree() + tree.remove('a') + assert(tree.size() == 1L) + assert(tree.getRootT()?.value == '+') + } + + private fun makeTreeForRemoveLeafWithoutBalancingTest(): AVLTreeForTest { + return AVLTreeForTest(AVLVertex('r', "r", AVLVertex('n', "n"), AVLVertex('z', "z")), 3L) + } + + @Test + fun `right leaf deleted after remove with one's key was called`() { + val tree = makeTreeForRemoveLeafWithoutBalancingTest() + tree.remove('z') + val root = tree.getRootT() + if (root != null) { + assert(root.rightSon == null) + } else { + assert(false) + } + } + + @Test + fun `left leaf deleted after remove with one's key was called`() { + val tree = makeTreeForRemoveLeafWithoutBalancingTest() + tree.remove('n') + val root = tree.getRootT() + if (root != null) { + assert(root.leftSon == null) + } else { + assert(false) + } + } + + @Test + fun `remove by right leaf's key return due value`() { + val tree = makeTreeForRemoveLeafWithoutBalancingTest() + assert(tree.remove('z') == "z") + } + + @Test + fun `remove by left leaf's key return due value`() { + val tree = makeTreeForRemoveLeafWithoutBalancingTest() + assert(tree.remove('n') == "n") + } + + @Test + fun `vertex's sonsHeightDiff increased by 1 after one's right leaf was deleted`() { + val tree = makeTreeForRemoveLeafWithoutBalancingTest() + tree.remove('z') + val root = tree.getRootT() + assert(root?.sonsHeightDiff == 1) + } + + @Test + fun `vertex's sonsHeightDiff decreased by 1 after one's left leaf was deleted`() { + val tree = makeTreeForRemoveLeafWithoutBalancingTest() + tree.remove('n') + val root = tree.getRootT() + assert(root?.sonsHeightDiff == -1) + } + + @Test + fun `size decreased by 1 after right leaf was deleted`() { + val tree = makeTreeForRemoveLeafWithoutBalancingTest() + tree.remove('z') + assert(tree.size() == 2L) + } + + @Test + fun `size decreased by 1 after left leaf was deleted`() { + val tree = makeTreeForRemoveLeafWithoutBalancingTest() + tree.remove('n') + assert(tree.size() == 2L) + } + + private fun makeTreeForRemoveLeftSonWithOnlyLeftSonTest(): AVLTreeForTest { + val leftSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) + val root = AVLVertex('s', 5, leftSon, AVLVertex('z', 2), 1) + return AVLTreeForTest(root, 4L) + } + + @Test + fun `remove be key of left son with only left son returns due value`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + assert(tree.remove('q') == 9) + } + + @Test + fun `content is correct after removed left son with only left son`() { + val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isTreeConsistsOf(setOf('o' to 0, 's' to 5, 'z' to 2), tree)) + } + + @Test + fun `size decreased by 1 after left son with only left son was deleted`() { + val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() + tree.remove('q') + assert(tree.size() == 3L) + } + + @Test + fun `structure is correct after left son with only left son was deleted`() { + val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isTreeSStructureThat(tree, arrayOf('s', 'o', 'z'), listOf(Triple(0, 1, 2)))) + } + + @Test + fun `sonsHeightDiff values are correct after LSon with only LSon was deleted`() { + val tree = makeTreeForRemoveLeftSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveLeftSonWithOnlyRightSonTest(): AVLTreeForTest { + val leftSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) + val root = AVLVertex('s', 5, leftSon, AVLVertex('z', 2), 1) + return AVLTreeForTest(root, 4L) + } + + @Test + fun `remove by key of left son with only right son returns due value`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + assert(tree.remove('q') == 9) + } + + @Test + fun `content is correct after left son with only right son was deleted`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + tree.remove('q') + assert(isTreeConsistsOf(setOf('r' to 7, 's' to 5, 'z' to 2), tree)) + } + + @Test + fun `size decreased by 1 after left son with only right son was deleted`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + tree.remove('q') + assert(tree.size() == 3L) + } + + @Test + fun `structure is correct after left son with only right son was deleted`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + tree.remove('q') + assert(isTreeSStructureThat(tree, arrayOf('s', 'r', 'z'), listOf(Triple(0, 1, 2)))) + } + + @Test + fun `sonsHeightDiff values are correct after LSon with only RSon was deleted`() { + val tree = makeTreeForRemoveLeftSonWithOnlyRightSonTest() + tree.remove('q') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveRightSonWithOnlyLeftSonTest(): AVLTreeForTest { + val rightSon = AVLVertex('q', 9, AVLVertex('o', 0), null, 1) + val root = AVLVertex('i', 1, AVLVertex('b', 6), rightSon, -1) + return AVLTreeForTest(root, 4L) + } + + @Test + fun `remove by key of right son with only left son returns due value`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + assert(tree.remove('q') == 9) + } + + @Test + fun `content is correct after right son with only left son was deleted`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isTreeConsistsOf(setOf('o' to 0, 'b' to 6, 'i' to 1), tree)) + } + + @Test + fun `size decreased by 1 after right son with only left son was deleted`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + tree.remove('q') + assert(tree.size() == 3L) + } + + @Test + fun `structure is correct after right son with only left son was deleted`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isTreeSStructureThat(tree, arrayOf('i', 'b', 'o'), listOf(Triple(0, 1, 2)))) + } + + @Test + fun `sonsHeightDiff values are correct after RSon with only LSon was deleted`() { + val tree = makeTreeForRemoveRightSonWithOnlyLeftSonTest() + tree.remove('q') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveRightSonWithOnlyRightSonTest(): AVLTreeForTest { + val rightSon = AVLVertex('q', 9, null, AVLVertex('r', 7), -1) + val root = AVLVertex('i', 1, AVLVertex('b', 6), rightSon, -1) + return AVLTreeForTest(root, 4L) + } + + @Test + fun `remove by key of right son with only right son returns due value`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + assert(tree.remove('q') == 9) + } + + @Test + fun `content is correct after right son with only right son was deleted`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + tree.remove('q') + assert(isTreeConsistsOf(setOf('r' to 7, 'b' to 6, 'i' to 1), tree)) + } + + @Test + fun `size decreased by 1 after right son with only right son was deleted`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + tree.remove('q') + assert(tree.size() == 3L) + } + + @Test + fun `structure is correct after right son with only right son was deleted`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + tree.remove('q') + assert(isTreeSStructureThat(tree, arrayOf('i', 'b', 'r'), listOf(Triple(0, 1, 2)))) + } + + @Test + fun `sonsHeightDiff values are correct after RSon with only RSon was deleted`() { + val tree = makeTreeForRemoveRightSonWithOnlyRightSonTest() + tree.remove('q') + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveRootWithOnlyLeftSon(): AVLTreeForTest { + return AVLTreeForTest(AVLVertex("be", "es", (AVLVertex("and", "et")), null, 1), 2L) + } + + @Test + fun `remove by key of root with only left son returns due value`() { + val tree = makeTreeForRemoveRootWithOnlyLeftSon() + assert(tree.remove("be") == "es") + } + + @Test + fun `content is correct after root with only left son was deleted`() { + val tree = makeTreeForRemoveRootWithOnlyLeftSon() + tree.remove("be") + assert(isTreeConsistsOf(setOf("and" to "et"), tree)) + } + + @Test + fun `sonsHeightDiff values are correct after root with only LSon was deleted`() { + val tree = makeTreeForRemoveRootWithOnlyLeftSon() + tree.remove("and") + assert(isSonsHeightDiffCorrect(tree)) + } + + private fun makeTreeForRemoveRootWithOnlyRightSon(): AVLTreeForTest { + return AVLTreeForTest(AVLVertex("and", "et", null, (AVLVertex("be", "es")), -1), 2L) + } + + @Test + fun `remove by key of root with only right son returns due value`() { + val tree = makeTreeForRemoveRootWithOnlyRightSon() + assert(tree.remove("and") == "et") + } + + @Test + fun `content is correct after root with only right son was deleted`() { + val tree = makeTreeForRemoveRootWithOnlyRightSon() + tree.remove("and") + assert(isTreeConsistsOf(setOf("be" to "es"), tree)) + } + + @Test + fun `sonsHeightDiff values are correct after root with only RSon was deleted`() { + val tree = makeTreeForRemoveRootWithOnlyRightSon() + tree.remove("and") + assert(isSonsHeightDiffCorrect(tree)) + } +} diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt new file mode 100644 index 0000000..51f2a02 --- /dev/null +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt @@ -0,0 +1,190 @@ +package trees.avlTree.removeTest.withoutBalancing + +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import main.vertexes.AVLVertex +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest + +class VertexHadTwoSons { + + private fun makeTreeForRemoveSonWithBothSons(): AVLTreeForTest { + val eVrt = AVLVertex('e', 'E', AVLVertex('c', 'C'), null, 1) + val bVrt = AVLVertex('b', 'B', AVLVertex('a', 'A'), eVrt, -1) + val leftSon = AVLVertex('f', 'F', bVrt, AVLVertex('i', 'I', null, AVLVertex('k', 'K'), -1), 1) + val qVrt = AVLVertex('q', 'Q', null, AVLVertex('s', 'S'), -1) + val wVrt = AVLVertex('w', 'W', null, AVLVertex('z', 'Z'), -1) + val root = AVLVertex('n', 'N', leftSon, AVLVertex('u', 'U', qVrt, wVrt, 0), 1) + return AVLTreeForTest(root, 13L) + } + + @Test + fun `remove by key of left son with both sons returns due value`() { + val tree = makeTreeForRemoveSonWithBothSons() + assert(tree.remove('f') == 'F') + } + + @Test + fun `content is correct after left son with both sons was deleted`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('f') + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'e' to 'E', + 'i' to 'I', + 'z' to 'Z', + 'k' to 'K', + 'n' to 'N', + 'u' to 'U', + 'q' to 'Q', + 's' to 'S', + 'w' to 'W', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after left son with both sons was deleted`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('f') + assert(tree.size() == 12L) + } + + @Test + fun `structure is correct after left son with both sons was deleted`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('f') + val expectedDependencies = + listOf( + Triple(0, 1, 7), + Triple(1, 2, 5), + Triple(2, 3, 4), + Triple(5, null, 6), + Triple(7, 8, 10), + Triple(10, null, 11), + ) + val expectedOrder = arrayOf('n', 'e', 'b', 'a', 'c', 'i', 'k', 'u', 'q', 's', 'w', 'z') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after LSon with both sons was deleted`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('f') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `remove by key of right son with both sons returns due value`() { + val tree = makeTreeForRemoveSonWithBothSons() + assert(tree.remove('u') == 'U') + } + + @Test + fun `content is correct after right son with both sons was deleted`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('u') + val expectedContent = + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'e' to 'E', + 'i' to 'I', + 'z' to 'Z', + 'k' to 'K', + 'n' to 'N', + 'f' to 'F', + 'q' to 'Q', + 's' to 'S', + 'w' to 'W', + ) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after right son with both sons was deleted`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('u') + assert(tree.size() == 12L) + } + + @Test + fun `structure is correct after right son with both sons was deleted`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('u') + val expectedDependencies = + listOf( + Triple(0, 1, 8), + Triple(1, 2, 6), + Triple(2, 3, 4), + Triple(6, null, 7), + Triple(4, 5, null), + Triple(8, 9, 10), + Triple(10, null, 11), + ) + val expectedOrder = arrayOf('n', 'f', 'b', 'a', 'e', 'c', 'i', 'k', 's', 'q', 'w', 'z') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after RSon with both sons was deleted`() { + val tree = makeTreeForRemoveSonWithBothSons() + tree.remove('u') + assert(isSonsHeightDiffCorrect(tree)) + } + + @Test + fun `remove fun return null if entry's key isn't exists(2)`() { + val tree = makeTreeForRemoveSonWithBothSons() + assert(tree.remove('x') == null) + } + + private fun makeTreeForRemoveRootWithBothSonsTest(): AVLTreeForTest { + val leftSon = AVLVertex('b', 2, AVLVertex('a', 1), AVLVertex('e', 5), 0) + val rightSon = AVLVertex('i', 9, null, AVLVertex('k', 11), -1) + val root = AVLVertex('f', 6, leftSon, rightSon, 0) + return AVLTreeForTest(root, 6L) + } + + @Test + fun `remove by key of root with both sons returns due value`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + assert(tree.remove('f') == 6) + } + + @Test + fun `content is correct after root with both sons was deleted`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + tree.remove('f') + val expectedContent = setOf('a' to 1, 'b' to 2, 'e' to 5, 'i' to 9, 'k' to 11) + assert(isTreeConsistsOf(expectedContent, tree)) + } + + @Test + fun `size decreased by 1 after root with both sons was deleted`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + tree.remove('f') + assert(tree.size() == 5L) + } + + @Test + fun `structure is correct after root with both sons was deleted`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + tree.remove('f') + val expectedDependencies = listOf(Triple(0, 1, 3), Triple(1, 2, null), Triple(3, null, 4)) + val expectedOrder = arrayOf('e', 'b', 'a', 'i', 'k') + assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) + } + + @Test + fun `sonsHeightDiff values are correct after root with both sons was deleted`() { + val tree = makeTreeForRemoveRootWithBothSonsTest() + tree.remove('f') + assert(isSonsHeightDiffCorrect(tree)) + } +} From 8e2c218c7b99a7eed654f4cb7384c33984fc664c Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 2 Apr 2024 01:49:11 +0300 Subject: [PATCH 193/227] feat : add AbstractTreeTest --- lib/src/test/kotlin/AbstractTreeTest.kt | 242 ++++++++++++++++++++++++ lib/src/test/kotlin/TestTree.kt | 31 +++ 2 files changed, 273 insertions(+) create mode 100644 lib/src/test/kotlin/AbstractTreeTest.kt create mode 100644 lib/src/test/kotlin/TestTree.kt diff --git a/lib/src/test/kotlin/AbstractTreeTest.kt b/lib/src/test/kotlin/AbstractTreeTest.kt new file mode 100644 index 0000000..a88ddad --- /dev/null +++ b/lib/src/test/kotlin/AbstractTreeTest.kt @@ -0,0 +1,242 @@ +import main.vertexes.SimpleBSTVertex +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.* +import java.util.Comparator + +class AbstractTreeTest { + + private fun makeEmptyTree() : TestTree { + return TestTree() + } + + @Test + fun `isEmpty() returns true if tree is empty `() { + val tree = makeEmptyTree() + assert(tree.isEmpty()) + } + + @Test + fun `size() returns 0 if tree is empty`() { + val tree = makeEmptyTree() + assert(tree.size() == 0L) + } + + @Test + fun `get() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.get(intArrayOf(0))) + } + + @Test + fun `getMax() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.getMax()) + } + + @Test + fun `getMin() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.getMin()) + } + + @Test + fun `getMaxKeyPair() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.getMaxKeyPair()) + } + + @Test + fun `getMinKeyPair() returns null if tree is empty`() { + val tree = makeEmptyTree() + assertNull(tree.getMinKeyPair()) + } + + private fun makeTreeWithBothRootSSons() : TestTree { + val leftSon = SimpleBSTVertex('1', "!", SimpleBSTVertex('0', ")"), null) + val rightSon = SimpleBSTVertex('4', "$", SimpleBSTVertex('3', "#"), null) + return TestTree(SimpleBSTVertex('2', "@", leftSon, rightSon), 5L) + } + + @Test + fun `isEmpty() returns false if tree is not empty `() { + val tree = makeTreeWithBothRootSSons() + assertFalse(tree.isEmpty()) + } + + @Test + fun `size() returns not 0 if tree is not empty`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.size() != 0L) + } + + @Test + fun `get() returns null when tree doesn'n contains given key`() { + val tree = makeTreeWithBothRootSSons() + assertNull(tree.get('z')) + } + + @Test + fun `getPair() returns null when tree doesn'n contains given key`() { + val tree = makeTreeWithBothRootSSons() + assertNull(tree.getPair('z')) + } + + @Test + fun `get() returns correct value when tree contains given key in left subtree`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.get('1') == "!") + } + + @Test + fun `getPair() returns correct value when tree contains given key in left subtree`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getPair('1') == ('1' to "!")) + } + + @Test + fun `get() returns correct value when tree contains given key in right subtree`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.get('4') == "$") + } + + @Test + fun `get() returns correct value when root's key was given`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.get('2') == "@") + } + + @Test + fun `get() returns correct value when leaf's key was given`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.get('3') == "#") + } + + @Test + fun `getMin() returns correct value when root has two sons`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getMin() == ")") + } + + @Test + fun `getMax() returns correct value when root has two sons`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getMax() == "$") + } + + @Test + fun `getMinKeyPair() returns correct value when root has two sons`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getMinKeyPair() == ('0' to ")")) + } + + @Test + fun `getMaxKeyPair() returns correct value when root has two sons`() { + val tree = makeTreeWithBothRootSSons() + assert(tree.getMaxKeyPair() == ('4' to "$")) + } + + private fun makeTreeWithOnlyLeftRootSSon() : TestTree { + val leftSon = SimpleBSTVertex('1', "!", SimpleBSTVertex('0', ")"), SimpleBSTVertex('2', "@")) + return TestTree(SimpleBSTVertex('3', "#", leftSon, null), 4L) + } + + @Test + fun `getMax() returns correct value when root has only left son`() { + val tree = makeTreeWithOnlyLeftRootSSon() + assert(tree.getMax() == "#") + } + + private fun makeTreeWithOnlyRightRootSSon() : TestTree { + val rightSon = SimpleBSTVertex('6', "^", SimpleBSTVertex('5', "%"), SimpleBSTVertex('8', "*")) + return TestTree(SimpleBSTVertex('3', "#", null, rightSon), 4L) + } + + @Test + fun `getMin() returns correct value when root has only right son`() { + val tree = makeTreeWithOnlyRightRootSSon() + assert(tree.getMin() == "#") + } + + @Test + fun `removeAndReturnPair() returns null when remove() returned null`() { + val tree = TestTree(removeShouldReturns = null) + assertNull(tree.removeAndReturnPair(1)) + } + + @Test + fun `removeAndReturnPair() returns (given key) to (value that remove() returned) pair`() { + val tree = TestTree(removeShouldReturns = '1') + assert (tree.removeAndReturnPair(3) == (3 to '1')) + } + + @Test + fun `putAll() do correct put() call for each map element (1)`() { + val tree = TestTree() + val map = hashMapOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'a' to 'A') + tree.putAll(map) + for (pair in map) + assertNotNull(tree.putWasCalledWithParams.remove(Triple(pair.component1(), pair.component2(), true))) + } + + @Test + fun `putAll() do correct put() call for each map element (2)`() { + val tree = TestTree() + val map = hashMapOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'a' to 'A') + tree.putAll(map, false) + for (pair in map) + assertNotNull(tree.putWasCalledWithParams.remove(Triple(pair.component1(), pair.component2(), false))) + } + + @Test + fun `compareKeys return 1 when key1 larger than key2 (keys are comparable)`() { + val tree = TestTree() + assert (tree.compareKeysT(18, 14) == 1) + } + + @Test + fun `compareKeys return 0 when key1 equals key2 (keys are comparable)`() { + val tree = TestTree() + assert (tree.compareKeysT(18, 18) == 0) + } + + @Test + fun `compareKeys return -1 when key1 lesser than key2 (keys are comparable)`() { + val tree = TestTree() + assert (tree.compareKeysT(14, 18) == -1) + } + + class cmp : Comparator { + override fun compare(o1 : IntArray, o2 : IntArray) : Int { + return o1.sum() - o2.sum() + } + } + + + @Test + fun `compareKeys return 1 when key1 larger than key2 (comparator was given)`() { + val tree = TestTree(cmp()) + assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(-1)) == 1) + } + + @Test + fun `compareKeys return 0 when key1 equals key2 (comparator was given)`() { + val tree = TestTree(cmp()) + assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(0)) == 0) + } + + @Test + fun `compareKeys return -1 when key1 lesser than key2 (comparator was given)`() { + val tree = TestTree(cmp()) + assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1)) == -1) + } + + + @Test + fun `compareKeys fall when keys type doesn't implement compareble && comparator wasn't given`() { + var didItFall = false + val tree = TestTree() + try {tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1))} + catch (e : Exception) {didItFall = true} + assert(didItFall) + } +} diff --git a/lib/src/test/kotlin/TestTree.kt b/lib/src/test/kotlin/TestTree.kt new file mode 100644 index 0000000..e19a65f --- /dev/null +++ b/lib/src/test/kotlin/TestTree.kt @@ -0,0 +1,31 @@ +import main.trees.AbstractBinarySearchTree +import main.vertexes.SimpleBSTVertex + +class TestTree : AbstractBinarySearchTree> { + + var removeShouldReturns : V? = null + var getShouldReturns : V? = null + val putWasCalledWithParams : MutableList> = mutableListOf() + + override fun put(key: K, value: V, replaceIfExists : Boolean) { + putWasCalledWithParams.add(Triple(key, value, replaceIfExists)) + } + + override fun remove(key: K) : V? {return removeShouldReturns} + + fun compareKeysT(firstKey: K, secondKey: K): Int { + return super.compareKeys(firstKey, secondKey) + } + constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : + super(comparator) { + this.root = root + this.size = size + } + + constructor (removeShouldReturns : V?) : super() {this.removeShouldReturns = removeShouldReturns} + + constructor (comparator: Comparator? = null) : super(comparator) + + constructor (map: Map, replaceIfExists: Boolean = true, + comparator: Comparator? = null) : super(map, replaceIfExists, comparator) +} From 02bd44f95c0fe3d9ead29b75ea537d1fb88cbf44 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 6 Apr 2024 20:05:27 +0300 Subject: [PATCH 194/227] feat(AbstractTreeTest) : add tests for isNotEmpty() method, fix typos --- .../trees/abstractTree/AbstractTreeTest.kt | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt b/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt index 5aded42..be7f784 100644 --- a/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt +++ b/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt @@ -18,6 +18,11 @@ class AbstractTreeTest { assert(tree.isEmpty()) } + @Test + fun `isNotEmpty() returns false if tree is empty `() { + val tree = makeEmptyTree() + assertFalse(tree.isNotEmpty()) + } @Test fun `size() returns 0 if tree is empty`() { val tree = makeEmptyTree() @@ -66,6 +71,12 @@ class AbstractTreeTest { assertFalse(tree.isEmpty()) } + @Test + fun `isNotEmpty() returns true if tree is not empty `() { + val tree = makeTreeWithBothRootSSons() + assert(tree.isNotEmpty()) + } + @Test fun `size() returns not 0 if tree is not empty`() { val tree = makeTreeWithBothRootSSons() @@ -73,13 +84,13 @@ class AbstractTreeTest { } @Test - fun `get() returns null when tree doesn'n contains given key`() { + fun `get() returns null when tree doesn't contains given key`() { val tree = makeTreeWithBothRootSSons() assertNull(tree.get('z')) } @Test - fun `getPair() returns null when tree doesn'n contains given key`() { + fun `getPair() returns null when tree doesn't contains given key`() { val tree = makeTreeWithBothRootSSons() assertNull(tree.getPair('z')) } @@ -210,8 +221,8 @@ class AbstractTreeTest { class CMP : Comparator { override fun compare( - o1: IntArray, - o2: IntArray, + o1: IntArray, + o2: IntArray, ): Int { return o1.sum() - o2.sum() } @@ -236,7 +247,7 @@ class AbstractTreeTest { } @Test - fun `compareKeys fall when keys type doesn't implement compareble && comparator wasn't given`() { + fun `compareKeys fall when keys type doesn't implement comparable && comparator wasn't given`() { var didItFall = false val tree = TestTree() try { From 0395609594b76e89061d380b954e62806902807d Mon Sep 17 00:00:00 2001 From: Nikita Shchutskii <144726123+Szczucki@users.noreply.github.com> Date: Sun, 7 Apr 2024 12:19:56 +0300 Subject: [PATCH 195/227] fix comparator * fix: edit 'when' expressions in AbstractTree compareKeys() * fix : some style improvements in AbstractTree compareKeys() * fix(AbstractTree) : add exception message in compareKeys() --- lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index 82daf23..a3f7820 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -233,7 +233,8 @@ abstract class AbstractBinarySearchTree> { else -> 1 } } else { - val comparableKey = firstKey as Comparable + val comparableKey = firstKey as? Comparable ?: + throw Exception("Key's type is incomparable and comparator wasn't given") when (comparableKey.compareTo(secondKey)) { in Int.MIN_VALUE..-1 -> -1 0 -> 0 From 8bfcb74aa1b1b68b7dc711b228f5fd61304923d9 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:04:24 +0300 Subject: [PATCH 196/227] feat: add test coverage --- .github/workflows/ci.yml | 2 ++ .github/workflows/coverage.yml | 45 ++++++++++++++++++++++++++++++++++ .github/workflows/ktlint.yml | 2 ++ 3 files changed, 49 insertions(+) create mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25f9bf2..d0342fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,10 +5,12 @@ on: branches: - main - develop + - fixes-after-1st-review push: branches: - main - develop + - fixes-after-1st-review workflow_dispatch: jobs: diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..dfa67a9 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,45 @@ +name: Jacoco coverage + +on: + pull_request: + branches: + - main + - develop + - fixes-after-1st-review + push: + branches: + - main + - develop + - fixes-after-1st-review + workflow_dispatch: + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Java JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + cache: gradle + distribution: "temurin" + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v3 + - name: Run Coverage + run: | + chmod +x gradlew + ./gradlew testCoverage + - name: Add coverage to PR + id: jacoco + uses: madrapps/jacoco-report@v1.6.1 + with: + paths: | + ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, + ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 40 + min-coverage-changed-files: 60 + pass-emoji: 💪 + fail-emoji: 🤡 \ No newline at end of file diff --git a/.github/workflows/ktlint.yml b/.github/workflows/ktlint.yml index 8fcfbd4..f58f9f6 100644 --- a/.github/workflows/ktlint.yml +++ b/.github/workflows/ktlint.yml @@ -5,10 +5,12 @@ on: branches: - main - develop + - fixes-after-1st-review push: branches: - main - develop + - fixes-after-1st-review workflow_dispatch: jobs: From 947e0683852dbb8aac766dd18f25f83c26eba0d0 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:08:41 +0300 Subject: [PATCH 197/227] fix: delete extra code --- .github/workflows/coverage.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index dfa67a9..0004a55 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -28,9 +28,7 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 - name: Run Coverage - run: | - chmod +x gradlew - ./gradlew testCoverage + run: ./gradlew testCoverage - name: Add coverage to PR id: jacoco uses: madrapps/jacoco-report@v1.6.1 From 34e90e1c2124f77df67a2e485d065672059d4430 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:16:23 +0300 Subject: [PATCH 198/227] fix: change name of reports --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0004a55..0877d56 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -28,7 +28,7 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 - name: Run Coverage - run: ./gradlew testCoverage + run: ./gradlew jacocoTestReport - name: Add coverage to PR id: jacoco uses: madrapps/jacoco-report@v1.6.1 From e2183d49991129d7acfba105f2e2ffbf163b99bb Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:22:46 +0300 Subject: [PATCH 199/227] fix: add permissions --- .github/workflows/coverage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0877d56..00d7878 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -16,6 +16,8 @@ on: jobs: coverage: runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - name: Checkout repository uses: actions/checkout@v4 From 99e16c97e1ae53d393bc7d3f9d943be4a31c9b68 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:39:18 +0300 Subject: [PATCH 200/227] feat: add emoji on tests --- .github/workflows/coverage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 00d7878..7b79dae 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -41,5 +41,5 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 40 min-coverage-changed-files: 60 - pass-emoji: 💪 - fail-emoji: 🤡 \ No newline at end of file + pass-emoji: ':partying_face:' + fail-emoji: ':clown_face:' \ No newline at end of file From f9a3bea849ca8d36cd963d6637adab1ad2e9f2f9 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 01:50:25 +0300 Subject: [PATCH 201/227] feat: add test report --- .github/workflows/ci.yml | 4 ++++ .github/workflows/coverage.yml | 15 ++++++++++++--- lib/build.gradle.kts | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0342fa..c2df060 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,15 +19,19 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up Java JDK uses: actions/setup-java@v4 with: java-version: 17 cache: gradle distribution: "temurin" + - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 + - name: Build with Gradle run: ./gradlew build + - name: Run tests run: ./gradlew test diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7b79dae..36663ab 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -21,16 +21,25 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up Java JDK uses: actions/setup-java@v4 with: java-version: 17 - cache: gradle distribution: "temurin" + - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 + - name: Run Coverage run: ./gradlew jacocoTestReport + + - name: Generate JaCoCo Badge + uses: cicirello/jacoco-badge-generator@v2 + with: + generate-branches-badge: true + jacoco-csv-file: build/reports/jacoco/test/jacocoTestReport.csv + - name: Add coverage to PR id: jacoco uses: madrapps/jacoco-report@v1.6.1 @@ -41,5 +50,5 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 40 min-coverage-changed-files: 60 - pass-emoji: ':partying_face:' - fail-emoji: ':clown_face:' \ No newline at end of file + pass-emoji: '🥳' + fail-emoji: '🤡' \ No newline at end of file diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index dcb7919..aa9fc85 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -48,7 +48,7 @@ tasks.named("test") { tasks.named("jacocoTestReport") { dependsOn(tasks.test) reports { - csv.required = false + csv.required = true xml.required = false html.outputLocation = layout.buildDirectory.dir("jacocoHtml") } From 537f81ee0a85980d02b53c983ece810c73673a4c Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:06:08 +0300 Subject: [PATCH 202/227] fix: change path to csv --- .github/workflows/coverage.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 36663ab..d55eb74 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -34,11 +34,11 @@ jobs: - name: Run Coverage run: ./gradlew jacocoTestReport - - name: Generate JaCoCo Badge + - name: Generate JaCoCo Report uses: cicirello/jacoco-badge-generator@v2 with: generate-branches-badge: true - jacoco-csv-file: build/reports/jacoco/test/jacocoTestReport.csv + jacoco-csv-file: lib/build/reports/jacoco/test/jacocoTestReport.csv - name: Add coverage to PR id: jacoco @@ -50,5 +50,4 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 40 min-coverage-changed-files: 60 - pass-emoji: '🥳' - fail-emoji: '🤡' \ No newline at end of file + \ No newline at end of file From c2a47827105a2c549dd38d72dbb8c2a96c4dda83 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:11:19 +0300 Subject: [PATCH 203/227] feat: add emoji) --- .github/workflows/coverage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index d55eb74..bb43dfa 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -49,5 +49,5 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 40 - min-coverage-changed-files: 60 - \ No newline at end of file + pass-emoji: '🥳' + fail-emoji: '🤡' From 859e3eb2ee41e1ac0a51446b7e2803b0d9ef62a5 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:21:25 +0300 Subject: [PATCH 204/227] feat: add title of report --- .github/workflows/coverage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bb43dfa..0718b07 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,6 +48,8 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} + title: '# :lobster: Coverage Report' + update-comment: true min-coverage-overall: 40 pass-emoji: '🥳' fail-emoji: '🤡' From 0509db7f6dd0242108ddc3f3600cd28b982fadf5 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:26:03 +0300 Subject: [PATCH 205/227] feat: add skip case --- .github/workflows/coverage.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0718b07..b46c41b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,8 +48,9 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} - title: '# :lobster: Coverage Report' + title: '# 🇷🇺 Coverage Report' update-comment: true + skip-if-no-changes: true min-coverage-overall: 40 pass-emoji: '🥳' fail-emoji: '🤡' From fd564620e1586cb068960f3f275df6ebfc930f55 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:31:32 +0300 Subject: [PATCH 206/227] test: comment some tests to see changes in report --- .github/workflows/coverage.yml | 2 +- .../kotlin/trees/rbTree/RBSearchTreeTest.kt | 390 +++++++++--------- 2 files changed, 196 insertions(+), 196 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b46c41b..50383f3 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,7 +48,7 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} - title: '# 🇷🇺 Coverage Report' + title: '# 5⃣2⃣ Coverage Report' update-comment: true skip-if-no-changes: true min-coverage-overall: 40 diff --git a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt index 3fdde9c..77258d6 100644 --- a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt @@ -178,201 +178,201 @@ class RBSearchTreeTest { ) } - @Test - fun `balance after remove - brother is right and black, brother's rightSon - red`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(3, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "chka") - rbTree.put(11, "Slim") - rbTree.put(13, "Shady") - rbTree.remove(9) - expectedResult = - listOf( - Pair(7, "hi"), - Pair(12, "chka"), - Pair(13, "Shady"), - Pair(10, "name"), - Pair(11, "Slim"), - Pair(4, "my"), - Pair(5, "chka"), - Pair(3, "is"), - ) - } - - @Test - fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(3, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "Slim") - rbTree.put(11, "Shady") - rbTree.remove(9) - expectedResult = - listOf( - Pair(7, "hi"), - Pair(11, "Shady"), - Pair(12, "Slim"), - Pair(10, "name"), - Pair(4, "my"), - Pair(5, "chka"), - Pair(3, "is"), - ) - } - - @Test - fun `balance after remove - brother is right and black, both sons - black`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(9, "is") - rbTree.put(12, "Slim") - rbTree.put(11, "Shady") - rbTree.remove(11) - - // now vertexes with keys 9 and 12 are black - rbTree.remove(9) - - expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) - } - - @Test - fun `balance after remove - right brother is red`() { - rbTree.put(60, "sixty") - rbTree.put(33, "thirty-three") - rbTree.put(84, "eighty-four") - rbTree.put(15, "fifteen") - rbTree.put(51, "fifty-one") - rbTree.put(65, "sixty-five") - rbTree.put(96, "ninety-six") - rbTree.put(34, "thirty-four") - rbTree.put(52, "Alblack") - rbTree.put(94, "ninety-four") - rbTree.put(97, "ninety-seven") - rbTree.put(95, "ninety-five") - - // now vertex with key 96 is red, with key 65 - black - rbTree.remove(65) - - expectedResult = - listOf( - Pair(60, "sixty"), - Pair(96, "ninety-six"), - Pair(97, "ninety-seven"), - Pair(94, "ninety-four"), - Pair(95, "ninety-five"), - Pair(84, "eighty-four"), - Pair(33, "thirty-three"), - Pair(51, "fifty-one"), - Pair(52, "Alblack"), - Pair(34, "thirty-four"), - Pair(15, "fifteen"), - ) - } - - @Test - fun `balance after remove - brother is left and black, brother's rightSon - red`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "chka") - rbTree.put(1, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(5) - expectedResult = - listOf( - Pair(7, "hi"), - Pair(10, "name"), - Pair(12, "chka"), - Pair(9, "chka"), - Pair(2, "is"), - Pair(4, "my"), - Pair(3, "Shady"), - Pair(1, "Slim"), - ) - } - - @Test - fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "chka") - rbTree.put(9, "chka") - rbTree.put(12, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(5) - expectedResult = - listOf( - Pair(7, "hi"), - Pair(10, "name"), - Pair(12, "Slim"), - Pair(9, "chka"), - Pair(3, "Shady"), - Pair(4, "my"), - Pair(2, "is"), - ) - } - - @Test - fun `balance after remove - brother is left and black, both sons - black`() { - rbTree.put(7, "hi") - rbTree.put(4, "my") - rbTree.put(10, "name") - rbTree.put(2, "is") - rbTree.put(5, "Slim") - rbTree.put(3, "Shady") - rbTree.remove(3) - - // now vertexes with keys 2 and 5 are black - rbTree.remove(5) - - expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) - } - - @Test - fun `balance after remove - left brother is red`() { - rbTree.put(60, "sixty") - rbTree.put(33, "thirty-three") - rbTree.put(84, "eighty-four") - rbTree.put(15, "fifteen") - rbTree.put(51, "fifty-one") - rbTree.put(65, "sixty-five") - rbTree.put(96, "ninety-six") - rbTree.put(5, "five") - rbTree.put(27, "twenty-seven") - rbTree.put(61, "sixty-one") - rbTree.put(69, "sixty-nine") - rbTree.put(17, "seventeen") - - // now vertex with key 15 is red, with key 51 - black - rbTree.remove(51) - - expectedResult = - listOf( - Pair(60, "sixty"), - Pair(84, "eighty-four"), - Pair(96, "ninety-six"), - Pair(65, "sixty-five"), - Pair(69, "sixty-nine"), - Pair(61, "sixty-one"), - Pair(15, "fifteen"), - Pair(27, "twenty-seven"), - Pair(33, "thirty-three"), - Pair(17, "seventeen"), - Pair(5, "five"), - ) - } +// @Test +// fun `balance after remove - brother is right and black, brother's rightSon - red`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(3, "is") +// rbTree.put(5, "chka") +// rbTree.put(9, "chka") +// rbTree.put(12, "chka") +// rbTree.put(11, "Slim") +// rbTree.put(13, "Shady") +// rbTree.remove(9) +// expectedResult = +// listOf( +// Pair(7, "hi"), +// Pair(12, "chka"), +// Pair(13, "Shady"), +// Pair(10, "name"), +// Pair(11, "Slim"), +// Pair(4, "my"), +// Pair(5, "chka"), +// Pair(3, "is"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(3, "is") +// rbTree.put(5, "chka") +// rbTree.put(9, "chka") +// rbTree.put(12, "Slim") +// rbTree.put(11, "Shady") +// rbTree.remove(9) +// expectedResult = +// listOf( +// Pair(7, "hi"), +// Pair(11, "Shady"), +// Pair(12, "Slim"), +// Pair(10, "name"), +// Pair(4, "my"), +// Pair(5, "chka"), +// Pair(3, "is"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is right and black, both sons - black`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(9, "is") +// rbTree.put(12, "Slim") +// rbTree.put(11, "Shady") +// rbTree.remove(11) +// +// // now vertexes with keys 9 and 12 are black +// rbTree.remove(9) +// +// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) +// } +// +// @Test +// fun `balance after remove - right brother is red`() { +// rbTree.put(60, "sixty") +// rbTree.put(33, "thirty-three") +// rbTree.put(84, "eighty-four") +// rbTree.put(15, "fifteen") +// rbTree.put(51, "fifty-one") +// rbTree.put(65, "sixty-five") +// rbTree.put(96, "ninety-six") +// rbTree.put(34, "thirty-four") +// rbTree.put(52, "Alblack") +// rbTree.put(94, "ninety-four") +// rbTree.put(97, "ninety-seven") +// rbTree.put(95, "ninety-five") +// +// // now vertex with key 96 is red, with key 65 - black +// rbTree.remove(65) +// +// expectedResult = +// listOf( +// Pair(60, "sixty"), +// Pair(96, "ninety-six"), +// Pair(97, "ninety-seven"), +// Pair(94, "ninety-four"), +// Pair(95, "ninety-five"), +// Pair(84, "eighty-four"), +// Pair(33, "thirty-three"), +// Pair(51, "fifty-one"), +// Pair(52, "Alblack"), +// Pair(34, "thirty-four"), +// Pair(15, "fifteen"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is left and black, brother's rightSon - red`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(2, "is") +// rbTree.put(5, "chka") +// rbTree.put(9, "chka") +// rbTree.put(12, "chka") +// rbTree.put(1, "Slim") +// rbTree.put(3, "Shady") +// rbTree.remove(5) +// expectedResult = +// listOf( +// Pair(7, "hi"), +// Pair(10, "name"), +// Pair(12, "chka"), +// Pair(9, "chka"), +// Pair(2, "is"), +// Pair(4, "my"), +// Pair(3, "Shady"), +// Pair(1, "Slim"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(2, "is") +// rbTree.put(5, "chka") +// rbTree.put(9, "chka") +// rbTree.put(12, "Slim") +// rbTree.put(3, "Shady") +// rbTree.remove(5) +// expectedResult = +// listOf( +// Pair(7, "hi"), +// Pair(10, "name"), +// Pair(12, "Slim"), +// Pair(9, "chka"), +// Pair(3, "Shady"), +// Pair(4, "my"), +// Pair(2, "is"), +// ) +// } +// +// @Test +// fun `balance after remove - brother is left and black, both sons - black`() { +// rbTree.put(7, "hi") +// rbTree.put(4, "my") +// rbTree.put(10, "name") +// rbTree.put(2, "is") +// rbTree.put(5, "Slim") +// rbTree.put(3, "Shady") +// rbTree.remove(3) +// +// // now vertexes with keys 2 and 5 are black +// rbTree.remove(5) +// +// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) +// } +// +// @Test +// fun `balance after remove - left brother is red`() { +// rbTree.put(60, "sixty") +// rbTree.put(33, "thirty-three") +// rbTree.put(84, "eighty-four") +// rbTree.put(15, "fifteen") +// rbTree.put(51, "fifty-one") +// rbTree.put(65, "sixty-five") +// rbTree.put(96, "ninety-six") +// rbTree.put(5, "five") +// rbTree.put(27, "twenty-seven") +// rbTree.put(61, "sixty-one") +// rbTree.put(69, "sixty-nine") +// rbTree.put(17, "seventeen") +// +// // now vertex with key 15 is red, with key 51 - black +// rbTree.remove(51) +// +// expectedResult = +// listOf( +// Pair(60, "sixty"), +// Pair(84, "eighty-four"), +// Pair(96, "ninety-six"), +// Pair(65, "sixty-five"), +// Pair(69, "sixty-nine"), +// Pair(61, "sixty-one"), +// Pair(15, "fifteen"), +// Pair(27, "twenty-seven"), +// Pair(33, "thirty-three"), +// Pair(17, "seventeen"), +// Pair(5, "five"), +// ) +// } @Test fun `test secondary constructor`() { From 13f5d746fa03635de70966fa8b6c300244f15c15 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:36:46 +0300 Subject: [PATCH 207/227] test: comment some rbtree code to see changes in jacoco report --- .github/workflows/coverage.yml | 1 + lib/src/main/kotlin/trees/RBSearchTree.kt | 154 +++---- .../kotlin/trees/rbTree/RBSearchTreeTest.kt | 390 +++++++++--------- 3 files changed, 273 insertions(+), 272 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 50383f3..4a4fa5b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -52,5 +52,6 @@ jobs: update-comment: true skip-if-no-changes: true min-coverage-overall: 40 + min-coverage-changed-files: 60 pass-emoji: '🥳' fail-emoji: '🤡' diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index dfaaa7e..45bc2a1 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -61,7 +61,7 @@ class RBSearchTree : AbstractBinarySearchTree> { if (vertex == root && size == 0L) { root = null } else if (needToBalance(vertex)) { - balanceAfterRemove(vertex) +// balanceAfterRemove(vertex) } return value @@ -125,82 +125,82 @@ class RBSearchTree : AbstractBinarySearchTree> { * rotate left. We move conflict on level below, then we look at the previous cases * @param vertex The child vertex of the removed vertex or null if the removed vertex had no children. */ - private fun balanceAfterRemove(vertex: RBVertex?) { - var currentVertex = vertex - while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { - var brother: RBVertex? - if (currentVertex == currentVertex?.parent?.leftSon) { - brother = currentVertex?.parent?.rightSon - - if (brother?.isRed == true) { - brother.isRed = false - currentVertex?.parent?.isRed = true - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateLeft(vertexForRotate) } - brother = currentVertex?.parent?.rightSon - } - - if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null) - ) { - brother?.isRed = true - currentVertex = currentVertex?.parent - if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null - } else { - if (brother.rightSon?.isRed == false || brother.rightSon == null) { - brother.leftSon?.isRed = false - brother.isRed = true - rotateRight(brother) - brother = currentVertex?.parent?.rightSon - } - - val parentColor = currentVertex?.parent?.isRed - parentColor?.let { brother?.isRed = parentColor } - currentVertex?.parent?.isRed = false - brother?.rightSon?.isRed = false - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateLeft(vertexForRotate) } - if (currentVertex == vertex) currentVertex?.parent?.leftSon = null - currentVertex = root - } - } else { - brother = currentVertex?.parent?.leftSon - - if (brother?.isRed == true) { - brother.isRed = false - currentVertex?.parent?.isRed = true - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateRight(vertexForRotate) } - brother = currentVertex?.parent?.leftSon - } - - if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null) - ) { - brother?.isRed = true - currentVertex = currentVertex?.parent - if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null - } else { - if (brother.leftSon?.isRed == false || brother.leftSon == null) { - brother.rightSon?.isRed = false - brother.isRed = true - rotateLeft(brother) - brother = currentVertex?.parent?.leftSon - } - - val parentColor = currentVertex?.parent?.isRed - parentColor?.let { brother?.isRed = parentColor } - currentVertex?.parent?.isRed = false - brother?.leftSon?.isRed = false - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateRight(vertexForRotate) } - if (currentVertex == vertex) currentVertex?.parent?.rightSon = null - currentVertex = root - } - } - } - currentVertex?.isRed = false - } +// private fun balanceAfterRemove(vertex: RBVertex?) { +// var currentVertex = vertex +// while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { +// var brother: RBVertex? +// if (currentVertex == currentVertex?.parent?.leftSon) { +// brother = currentVertex?.parent?.rightSon +// +// if (brother?.isRed == true) { +// brother.isRed = false +// currentVertex?.parent?.isRed = true +// val vertexForRotate = currentVertex?.parent +// vertexForRotate?.let { rotateLeft(vertexForRotate) } +// brother = currentVertex?.parent?.rightSon +// } +// +// if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && +// (brother?.rightSon?.isRed == false || brother?.rightSon == null) +// ) { +// brother?.isRed = true +// currentVertex = currentVertex?.parent +// if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null +// } else { +// if (brother.rightSon?.isRed == false || brother.rightSon == null) { +// brother.leftSon?.isRed = false +// brother.isRed = true +// rotateRight(brother) +// brother = currentVertex?.parent?.rightSon +// } +// +// val parentColor = currentVertex?.parent?.isRed +// parentColor?.let { brother?.isRed = parentColor } +// currentVertex?.parent?.isRed = false +// brother?.rightSon?.isRed = false +// val vertexForRotate = currentVertex?.parent +// vertexForRotate?.let { rotateLeft(vertexForRotate) } +// if (currentVertex == vertex) currentVertex?.parent?.leftSon = null +// currentVertex = root +// } +// } else { +// brother = currentVertex?.parent?.leftSon +// +// if (brother?.isRed == true) { +// brother.isRed = false +// currentVertex?.parent?.isRed = true +// val vertexForRotate = currentVertex?.parent +// vertexForRotate?.let { rotateRight(vertexForRotate) } +// brother = currentVertex?.parent?.leftSon +// } +// +// if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && +// (brother?.rightSon?.isRed == false || brother?.rightSon == null) +// ) { +// brother?.isRed = true +// currentVertex = currentVertex?.parent +// if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null +// } else { +// if (brother.leftSon?.isRed == false || brother.leftSon == null) { +// brother.rightSon?.isRed = false +// brother.isRed = true +// rotateLeft(brother) +// brother = currentVertex?.parent?.leftSon +// } +// +// val parentColor = currentVertex?.parent?.isRed +// parentColor?.let { brother?.isRed = parentColor } +// currentVertex?.parent?.isRed = false +// brother?.leftSon?.isRed = false +// val vertexForRotate = currentVertex?.parent +// vertexForRotate?.let { rotateRight(vertexForRotate) } +// if (currentVertex == vertex) currentVertex?.parent?.rightSon = null +// currentVertex = root +// } +// } +// } +// currentVertex?.isRed = false +// } /** * Finds a vertex by corresponding key. If such vertex doesn't exist returns null. diff --git a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt index 77258d6..3fdde9c 100644 --- a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt @@ -178,201 +178,201 @@ class RBSearchTreeTest { ) } -// @Test -// fun `balance after remove - brother is right and black, brother's rightSon - red`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(3, "is") -// rbTree.put(5, "chka") -// rbTree.put(9, "chka") -// rbTree.put(12, "chka") -// rbTree.put(11, "Slim") -// rbTree.put(13, "Shady") -// rbTree.remove(9) -// expectedResult = -// listOf( -// Pair(7, "hi"), -// Pair(12, "chka"), -// Pair(13, "Shady"), -// Pair(10, "name"), -// Pair(11, "Slim"), -// Pair(4, "my"), -// Pair(5, "chka"), -// Pair(3, "is"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(3, "is") -// rbTree.put(5, "chka") -// rbTree.put(9, "chka") -// rbTree.put(12, "Slim") -// rbTree.put(11, "Shady") -// rbTree.remove(9) -// expectedResult = -// listOf( -// Pair(7, "hi"), -// Pair(11, "Shady"), -// Pair(12, "Slim"), -// Pair(10, "name"), -// Pair(4, "my"), -// Pair(5, "chka"), -// Pair(3, "is"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is right and black, both sons - black`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(9, "is") -// rbTree.put(12, "Slim") -// rbTree.put(11, "Shady") -// rbTree.remove(11) -// -// // now vertexes with keys 9 and 12 are black -// rbTree.remove(9) -// -// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) -// } -// -// @Test -// fun `balance after remove - right brother is red`() { -// rbTree.put(60, "sixty") -// rbTree.put(33, "thirty-three") -// rbTree.put(84, "eighty-four") -// rbTree.put(15, "fifteen") -// rbTree.put(51, "fifty-one") -// rbTree.put(65, "sixty-five") -// rbTree.put(96, "ninety-six") -// rbTree.put(34, "thirty-four") -// rbTree.put(52, "Alblack") -// rbTree.put(94, "ninety-four") -// rbTree.put(97, "ninety-seven") -// rbTree.put(95, "ninety-five") -// -// // now vertex with key 96 is red, with key 65 - black -// rbTree.remove(65) -// -// expectedResult = -// listOf( -// Pair(60, "sixty"), -// Pair(96, "ninety-six"), -// Pair(97, "ninety-seven"), -// Pair(94, "ninety-four"), -// Pair(95, "ninety-five"), -// Pair(84, "eighty-four"), -// Pair(33, "thirty-three"), -// Pair(51, "fifty-one"), -// Pair(52, "Alblack"), -// Pair(34, "thirty-four"), -// Pair(15, "fifteen"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is left and black, brother's rightSon - red`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(2, "is") -// rbTree.put(5, "chka") -// rbTree.put(9, "chka") -// rbTree.put(12, "chka") -// rbTree.put(1, "Slim") -// rbTree.put(3, "Shady") -// rbTree.remove(5) -// expectedResult = -// listOf( -// Pair(7, "hi"), -// Pair(10, "name"), -// Pair(12, "chka"), -// Pair(9, "chka"), -// Pair(2, "is"), -// Pair(4, "my"), -// Pair(3, "Shady"), -// Pair(1, "Slim"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(2, "is") -// rbTree.put(5, "chka") -// rbTree.put(9, "chka") -// rbTree.put(12, "Slim") -// rbTree.put(3, "Shady") -// rbTree.remove(5) -// expectedResult = -// listOf( -// Pair(7, "hi"), -// Pair(10, "name"), -// Pair(12, "Slim"), -// Pair(9, "chka"), -// Pair(3, "Shady"), -// Pair(4, "my"), -// Pair(2, "is"), -// ) -// } -// -// @Test -// fun `balance after remove - brother is left and black, both sons - black`() { -// rbTree.put(7, "hi") -// rbTree.put(4, "my") -// rbTree.put(10, "name") -// rbTree.put(2, "is") -// rbTree.put(5, "Slim") -// rbTree.put(3, "Shady") -// rbTree.remove(3) -// -// // now vertexes with keys 2 and 5 are black -// rbTree.remove(5) -// -// expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) -// } -// -// @Test -// fun `balance after remove - left brother is red`() { -// rbTree.put(60, "sixty") -// rbTree.put(33, "thirty-three") -// rbTree.put(84, "eighty-four") -// rbTree.put(15, "fifteen") -// rbTree.put(51, "fifty-one") -// rbTree.put(65, "sixty-five") -// rbTree.put(96, "ninety-six") -// rbTree.put(5, "five") -// rbTree.put(27, "twenty-seven") -// rbTree.put(61, "sixty-one") -// rbTree.put(69, "sixty-nine") -// rbTree.put(17, "seventeen") -// -// // now vertex with key 15 is red, with key 51 - black -// rbTree.remove(51) -// -// expectedResult = -// listOf( -// Pair(60, "sixty"), -// Pair(84, "eighty-four"), -// Pair(96, "ninety-six"), -// Pair(65, "sixty-five"), -// Pair(69, "sixty-nine"), -// Pair(61, "sixty-one"), -// Pair(15, "fifteen"), -// Pair(27, "twenty-seven"), -// Pair(33, "thirty-three"), -// Pair(17, "seventeen"), -// Pair(5, "five"), -// ) -// } + @Test + fun `balance after remove - brother is right and black, brother's rightSon - red`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(3, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "chka") + rbTree.put(11, "Slim") + rbTree.put(13, "Shady") + rbTree.remove(9) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(12, "chka"), + Pair(13, "Shady"), + Pair(10, "name"), + Pair(11, "Slim"), + Pair(4, "my"), + Pair(5, "chka"), + Pair(3, "is"), + ) + } + + @Test + fun `balance after remove - brother is right and black, brother's leftSon - red (rightSon - black)`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(3, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "Slim") + rbTree.put(11, "Shady") + rbTree.remove(9) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(11, "Shady"), + Pair(12, "Slim"), + Pair(10, "name"), + Pair(4, "my"), + Pair(5, "chka"), + Pair(3, "is"), + ) + } + + @Test + fun `balance after remove - brother is right and black, both sons - black`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(9, "is") + rbTree.put(12, "Slim") + rbTree.put(11, "Shady") + rbTree.remove(11) + + // now vertexes with keys 9 and 12 are black + rbTree.remove(9) + + expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(12, "Slim"), Pair(4, "my")) + } + + @Test + fun `balance after remove - right brother is red`() { + rbTree.put(60, "sixty") + rbTree.put(33, "thirty-three") + rbTree.put(84, "eighty-four") + rbTree.put(15, "fifteen") + rbTree.put(51, "fifty-one") + rbTree.put(65, "sixty-five") + rbTree.put(96, "ninety-six") + rbTree.put(34, "thirty-four") + rbTree.put(52, "Alblack") + rbTree.put(94, "ninety-four") + rbTree.put(97, "ninety-seven") + rbTree.put(95, "ninety-five") + + // now vertex with key 96 is red, with key 65 - black + rbTree.remove(65) + + expectedResult = + listOf( + Pair(60, "sixty"), + Pair(96, "ninety-six"), + Pair(97, "ninety-seven"), + Pair(94, "ninety-four"), + Pair(95, "ninety-five"), + Pair(84, "eighty-four"), + Pair(33, "thirty-three"), + Pair(51, "fifty-one"), + Pair(52, "Alblack"), + Pair(34, "thirty-four"), + Pair(15, "fifteen"), + ) + } + + @Test + fun `balance after remove - brother is left and black, brother's rightSon - red`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "chka") + rbTree.put(1, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(5) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(10, "name"), + Pair(12, "chka"), + Pair(9, "chka"), + Pair(2, "is"), + Pair(4, "my"), + Pair(3, "Shady"), + Pair(1, "Slim"), + ) + } + + @Test + fun `balance after remove - brother is left and black, brother's rightSon - red (leftSon - black)`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "chka") + rbTree.put(9, "chka") + rbTree.put(12, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(5) + expectedResult = + listOf( + Pair(7, "hi"), + Pair(10, "name"), + Pair(12, "Slim"), + Pair(9, "chka"), + Pair(3, "Shady"), + Pair(4, "my"), + Pair(2, "is"), + ) + } + + @Test + fun `balance after remove - brother is left and black, both sons - black`() { + rbTree.put(7, "hi") + rbTree.put(4, "my") + rbTree.put(10, "name") + rbTree.put(2, "is") + rbTree.put(5, "Slim") + rbTree.put(3, "Shady") + rbTree.remove(3) + + // now vertexes with keys 2 and 5 are black + rbTree.remove(5) + + expectedResult = listOf(Pair(7, "hi"), Pair(10, "name"), Pair(4, "my"), Pair(2, "is")) + } + + @Test + fun `balance after remove - left brother is red`() { + rbTree.put(60, "sixty") + rbTree.put(33, "thirty-three") + rbTree.put(84, "eighty-four") + rbTree.put(15, "fifteen") + rbTree.put(51, "fifty-one") + rbTree.put(65, "sixty-five") + rbTree.put(96, "ninety-six") + rbTree.put(5, "five") + rbTree.put(27, "twenty-seven") + rbTree.put(61, "sixty-one") + rbTree.put(69, "sixty-nine") + rbTree.put(17, "seventeen") + + // now vertex with key 15 is red, with key 51 - black + rbTree.remove(51) + + expectedResult = + listOf( + Pair(60, "sixty"), + Pair(84, "eighty-four"), + Pair(96, "ninety-six"), + Pair(65, "sixty-five"), + Pair(69, "sixty-nine"), + Pair(61, "sixty-one"), + Pair(15, "fifteen"), + Pair(27, "twenty-seven"), + Pair(33, "thirty-three"), + Pair(17, "seventeen"), + Pair(5, "five"), + ) + } @Test fun `test secondary constructor`() { From 514e8fe62ed77dd47ae842753ac7eb2efe98d142 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:42:53 +0300 Subject: [PATCH 208/227] feat: finally add tests reports --- .github/workflows/coverage.yml | 1 - lib/src/main/kotlin/trees/RBSearchTree.kt | 154 +++++++++++----------- 2 files changed, 77 insertions(+), 78 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4a4fa5b..08e66a4 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -50,7 +50,6 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} title: '# 5⃣2⃣ Coverage Report' update-comment: true - skip-if-no-changes: true min-coverage-overall: 40 min-coverage-changed-files: 60 pass-emoji: '🥳' diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 45bc2a1..dfaaa7e 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -61,7 +61,7 @@ class RBSearchTree : AbstractBinarySearchTree> { if (vertex == root && size == 0L) { root = null } else if (needToBalance(vertex)) { -// balanceAfterRemove(vertex) + balanceAfterRemove(vertex) } return value @@ -125,82 +125,82 @@ class RBSearchTree : AbstractBinarySearchTree> { * rotate left. We move conflict on level below, then we look at the previous cases * @param vertex The child vertex of the removed vertex or null if the removed vertex had no children. */ -// private fun balanceAfterRemove(vertex: RBVertex?) { -// var currentVertex = vertex -// while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { -// var brother: RBVertex? -// if (currentVertex == currentVertex?.parent?.leftSon) { -// brother = currentVertex?.parent?.rightSon -// -// if (brother?.isRed == true) { -// brother.isRed = false -// currentVertex?.parent?.isRed = true -// val vertexForRotate = currentVertex?.parent -// vertexForRotate?.let { rotateLeft(vertexForRotate) } -// brother = currentVertex?.parent?.rightSon -// } -// -// if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && -// (brother?.rightSon?.isRed == false || brother?.rightSon == null) -// ) { -// brother?.isRed = true -// currentVertex = currentVertex?.parent -// if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null -// } else { -// if (brother.rightSon?.isRed == false || brother.rightSon == null) { -// brother.leftSon?.isRed = false -// brother.isRed = true -// rotateRight(brother) -// brother = currentVertex?.parent?.rightSon -// } -// -// val parentColor = currentVertex?.parent?.isRed -// parentColor?.let { brother?.isRed = parentColor } -// currentVertex?.parent?.isRed = false -// brother?.rightSon?.isRed = false -// val vertexForRotate = currentVertex?.parent -// vertexForRotate?.let { rotateLeft(vertexForRotate) } -// if (currentVertex == vertex) currentVertex?.parent?.leftSon = null -// currentVertex = root -// } -// } else { -// brother = currentVertex?.parent?.leftSon -// -// if (brother?.isRed == true) { -// brother.isRed = false -// currentVertex?.parent?.isRed = true -// val vertexForRotate = currentVertex?.parent -// vertexForRotate?.let { rotateRight(vertexForRotate) } -// brother = currentVertex?.parent?.leftSon -// } -// -// if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && -// (brother?.rightSon?.isRed == false || brother?.rightSon == null) -// ) { -// brother?.isRed = true -// currentVertex = currentVertex?.parent -// if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null -// } else { -// if (brother.leftSon?.isRed == false || brother.leftSon == null) { -// brother.rightSon?.isRed = false -// brother.isRed = true -// rotateLeft(brother) -// brother = currentVertex?.parent?.leftSon -// } -// -// val parentColor = currentVertex?.parent?.isRed -// parentColor?.let { brother?.isRed = parentColor } -// currentVertex?.parent?.isRed = false -// brother?.leftSon?.isRed = false -// val vertexForRotate = currentVertex?.parent -// vertexForRotate?.let { rotateRight(vertexForRotate) } -// if (currentVertex == vertex) currentVertex?.parent?.rightSon = null -// currentVertex = root -// } -// } -// } -// currentVertex?.isRed = false -// } + private fun balanceAfterRemove(vertex: RBVertex?) { + var currentVertex = vertex + while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { + var brother: RBVertex? + if (currentVertex == currentVertex?.parent?.leftSon) { + brother = currentVertex?.parent?.rightSon + + if (brother?.isRed == true) { + brother.isRed = false + currentVertex?.parent?.isRed = true + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateLeft(vertexForRotate) } + brother = currentVertex?.parent?.rightSon + } + + if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && + (brother?.rightSon?.isRed == false || brother?.rightSon == null) + ) { + brother?.isRed = true + currentVertex = currentVertex?.parent + if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null + } else { + if (brother.rightSon?.isRed == false || brother.rightSon == null) { + brother.leftSon?.isRed = false + brother.isRed = true + rotateRight(brother) + brother = currentVertex?.parent?.rightSon + } + + val parentColor = currentVertex?.parent?.isRed + parentColor?.let { brother?.isRed = parentColor } + currentVertex?.parent?.isRed = false + brother?.rightSon?.isRed = false + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateLeft(vertexForRotate) } + if (currentVertex == vertex) currentVertex?.parent?.leftSon = null + currentVertex = root + } + } else { + brother = currentVertex?.parent?.leftSon + + if (brother?.isRed == true) { + brother.isRed = false + currentVertex?.parent?.isRed = true + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateRight(vertexForRotate) } + brother = currentVertex?.parent?.leftSon + } + + if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && + (brother?.rightSon?.isRed == false || brother?.rightSon == null) + ) { + brother?.isRed = true + currentVertex = currentVertex?.parent + if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null + } else { + if (brother.leftSon?.isRed == false || brother.leftSon == null) { + brother.rightSon?.isRed = false + brother.isRed = true + rotateLeft(brother) + brother = currentVertex?.parent?.leftSon + } + + val parentColor = currentVertex?.parent?.isRed + parentColor?.let { brother?.isRed = parentColor } + currentVertex?.parent?.isRed = false + brother?.leftSon?.isRed = false + val vertexForRotate = currentVertex?.parent + vertexForRotate?.let { rotateRight(vertexForRotate) } + if (currentVertex == vertex) currentVertex?.parent?.rightSon = null + currentVertex = root + } + } + } + currentVertex?.isRed = false + } /** * Finds a vertex by corresponding key. If such vertex doesn't exist returns null. From 3696fc01de4ddf073939b847fb0aaeabc7b3c31c Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 02:49:09 +0300 Subject: [PATCH 209/227] chore: change emoji --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 08e66a4..bcd858c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,7 +48,7 @@ jobs: ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} - title: '# 5⃣2⃣ Coverage Report' + title: '# 🇷🇺 Coverage Report' update-comment: true min-coverage-overall: 40 min-coverage-changed-files: 60 From 4a8d87b53a724075837275505ade663e3fc5e794 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 7 Apr 2024 15:23:11 +0300 Subject: [PATCH 210/227] feat: add Dokka plugin and dependence in build.gradle.kts --- lib/build.gradle.kts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index aa9fc85..841fe22 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -14,6 +14,9 @@ plugins { // Code coverage plugin jacoco + + // Documentation generation + id("org.jetbrains.dokka") version "1.9.20" } repositories { @@ -31,6 +34,8 @@ dependencies { testImplementation(libs.junit.jupiter.engine) testRuntimeOnly("org.junit.platform:junit-platform-launcher") + + compileOnly("org.jetbrains.dokka:dokka-core:1.9.20") } // Apply a specific Java toolchain to ease working on different environments. @@ -53,3 +58,11 @@ tasks.named("jacocoTestReport") { html.outputLocation = layout.buildDirectory.dir("jacocoHtml") } } + +tasks.dokkaHtml { + outputDirectory.set(layout.buildDirectory.dir("documentation/html")) +} + +tasks.dokkaGfm { + outputDirectory.set(layout.buildDirectory.dir("documentation/markdown")) +} From af0c6ef354adeb3910174f8c6235aa3df961b673 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 7 Apr 2024 15:27:10 +0300 Subject: [PATCH 211/227] feat: add custom Gradle tasks for javadoc.jar building --- lib/build.gradle.kts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 841fe22..c3a616f 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -66,3 +66,15 @@ tasks.dokkaHtml { tasks.dokkaGfm { outputDirectory.set(layout.buildDirectory.dir("documentation/markdown")) } + +tasks.register("dokkaHtmlJar") { + dependsOn(tasks.dokkaHtml) + from(tasks.dokkaHtml.flatMap { it.outputDirectory }) + archiveClassifier.set("html-docs") +} + +tasks.register("dokkaJavadocJar") { + dependsOn(tasks.dokkaJavadoc) + from(tasks.dokkaJavadoc.flatMap { it.outputDirectory }) + archiveClassifier.set("javadoc") +} From 1ef17dbaaba1b8002181eecea5b7160560bc48b2 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 7 Apr 2024 16:38:15 +0300 Subject: [PATCH 212/227] fix(AVL, RB): correct typos --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 10 +++++----- lib/src/main/kotlin/trees/RBSearchTree.kt | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index bc87ba8..a323a02 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -64,8 +64,8 @@ open class AVLSearchTree : AbstractBinarySearchTree> replaceIfExists: Boolean, vertex: AVLVertex, ): AVLVertex? { - fun putRecShort(vrtx: AVLVertex): AVLVertex? { - return putRec(key, value, replaceIfExists, vrtx) + fun putRecShort(vertex: AVLVertex): AVLVertex? { + return putRec(key, value, replaceIfExists, vertex) } val nextCallReturned: AVLVertex? @@ -158,7 +158,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> A, /** - * Probably need some tree changes, but not nulling + * Probably need some tree changes, but not null */ B, @@ -295,7 +295,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> /** * Prepares the largest lower vertex to replace the specified vertex. - * @param vertex the vertex to be replaced + * @param subtreeSInitiallyRoot the vertex to be replaced * @return the substitute vertex prepared to replace the specified vertex */ private fun replaceSubtreeSRootByLargestInItsLeftSubtree (subtreeSInitiallyRoot: AVLVertex): AVLVertex { @@ -425,7 +425,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> * Performs a big right rotation of the subtree. * @param curVertex the current vertex to rotate around (the subtree's root) * @param leftSon the left son vertex of the subtree's root - * @return the new root root of the subtree after rotation + * @return the new root of the subtree after rotation */ private fun bigRotateRight( curVertex: AVLVertex, diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index dfaaa7e..e36fecd 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -38,18 +38,19 @@ class RBSearchTree : AbstractBinarySearchTree> { * * 4 cases we need to look at: * - * 1) remove red vertex with 0 children -> just remove vetrex + * 1) remove red vertex with 0 children -> just remove vertex * * 2) remove red or black vertex with 2 children -> * find min vertex on the right subtree and swap it's key and value with * key and value of vertex that we need to remove. * Now we can work with vertex which has 1 or 0 children * - * 3) remove black vetrex with 1 child -> child can be only red + * 3) remove black vertex with 1 child -> child can be only red, * so we just swap child's key and value with key and value that we need to remove * and look at case 1) * * 4) remove black vertex with 0 children -> just remove vertex + * * @param key the key of the vertex to be removed * @return the value associated with the removed vertex, or null if the key is not found */ From 523bf1077da03ee4432a3486d82f5b1aa195a409 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 7 Apr 2024 16:46:09 +0300 Subject: [PATCH 213/227] refactor(test): rename class for tests to SimpleBSTForTest --- .../simpleBSTree/{SimpleBSTreeTest.kt => SimpleBSTForTest.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/src/test/kotlin/trees/simpleBSTree/{SimpleBSTreeTest.kt => SimpleBSTForTest.kt} (100%) diff --git a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt similarity index 100% rename from lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTreeTest.kt rename to lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt From 5a19f8a6c9f4b8fe1ef7039096dbaf25fb33e7b4 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 7 Apr 2024 16:47:57 +0300 Subject: [PATCH 214/227] refactor: rename packages and imports --- lib/src/main/kotlin/iterator/TreeIterator.kt | 10 +++++----- lib/src/main/kotlin/trees/AVLSearchTree.kt | 6 +++--- .../main/kotlin/trees/AbstractBinarySearchTree.kt | 13 +++---------- lib/src/main/kotlin/trees/RBSearchTree.kt | 4 ++-- lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt | 8 ++++---- lib/src/main/kotlin/vertexes/AVLVertex.kt | 2 +- lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt | 2 +- lib/src/main/kotlin/vertexes/RBVertex.kt | 2 +- lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt | 2 +- lib/src/test/kotlin/AbstractTreeTest.kt | 5 ++--- lib/src/test/kotlin/TestTree.kt | 8 ++++---- lib/src/test/kotlin/iterator/IteratorTests.kt | 4 ++-- lib/src/test/kotlin/iterator/TestIterator.kt | 7 +++---- .../kotlin/trees/abstractTree/AbstractTreeTest.kt | 7 ++----- lib/src/test/kotlin/trees/abstractTree/TestTree.kt | 4 ++-- lib/src/test/kotlin/trees/avlTree/AVLTreeForTest.kt | 6 ++---- .../test/kotlin/trees/avlTree/AuxiliaryFunctions.kt | 2 +- .../trees/avlTree/putTest/HaveToDoBigRotation.kt | 8 ++++---- .../trees/avlTree/putTest/HaveToRotateLeft.kt | 8 ++++---- .../trees/avlTree/putTest/HaveToRotateRight.kt | 9 +++++---- lib/src/test/kotlin/trees/avlTree/putTest/Other.kt | 4 ++-- .../trees/avlTree/putTest/WithoutBalancing.kt | 8 ++++---- .../trees/avlTree/removeTest/HaveToDoBigRotation.kt | 2 +- .../trees/avlTree/removeTest/HaveToRotateLeft.kt | 2 +- .../trees/avlTree/removeTest/HaveToRotateRight.kt | 2 +- .../avlTree/removeTest/withoutBalancing/Other.kt | 2 +- .../removeTest/withoutBalancing/VertexHadTwoSons.kt | 2 +- .../test/kotlin/trees/rbTree/RBSearchTreeTest.kt | 2 +- .../kotlin/trees/simpleBSTree/SimpleBSTForTest.kt | 8 +------- .../test/kotlin/trees/simpleBSTree/TestSimpleBST.kt | 4 ++-- 30 files changed, 67 insertions(+), 86 deletions(-) diff --git a/lib/src/main/kotlin/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt index f58f3bf..a64b2f8 100644 --- a/lib/src/main/kotlin/iterator/TreeIterator.kt +++ b/lib/src/main/kotlin/iterator/TreeIterator.kt @@ -1,7 +1,7 @@ -package main.iterator +package iterator -import main.vertexes.InterfaceBSTVertex -import java.util.LinkedList +import vertexes.InterfaceBSTVertex +import java.util.Stack /** * Iterator iterates over the vertices of the tree, visiting each vertex in the order of a depth-first traversal. @@ -13,7 +13,7 @@ import java.util.LinkedList open class TreeIterator>( vertex: N?, ) : Iterator> { - protected val stack = LinkedList() + protected val stack = Stack() init { // Initialize the iterator with the given vertex by adding it to the stack @@ -35,7 +35,7 @@ open class TreeIterator>( * @return the next element in the iteration as a Pair containing the key and value of the vertex */ override fun next(): Pair { - val nextVertex: N = stack.removeLast() + val nextVertex: N = stack.pop() nextVertex.leftSon?.let { stack.add(it) } nextVertex.rightSon?.let { stack.add(it) } return Pair(nextVertex.key, nextVertex.value) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index a323a02..da4ffc9 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -1,6 +1,6 @@ -package main.trees +package trees -import main.vertexes.AVLVertex +import vertexes.AVLVertex /** * An implementation of a binary search tree that automatically balances itself using AVL rotations. @@ -230,7 +230,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> else -> { val valueOfVertex = vertex.value Triple( - RemovalStage.B, + RemovalStage.B, replaceSubtreeSRootByLargestInItsLeftSubtree(vertex), valueOfVertex, ) diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index a3f7820..ccdb2e9 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -1,7 +1,7 @@ -package main.trees +package trees -import main.iterator.TreeIterator -import main.vertexes.InterfaceBSTVertex +import iterator.TreeIterator +import vertexes.InterfaceBSTVertex /** * An abstract class representing a binary search tree. @@ -120,13 +120,6 @@ abstract class AbstractBinarySearchTree> { return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) } - /** - * Associates the specified value with the specified key in this tree. - * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. - * @param key the key with which the specified value is to be associated - * @param value the value to be associated with the specified key - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it - */ abstract fun put( key: K, value: V, diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index e36fecd..8964228 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -1,6 +1,6 @@ -package main.trees +package trees -import main.vertexes.RBVertex +import vertexes.RBVertex /** * Red-Black Tree implementation. It extends AbstractBinarySearchTree and uses RBVertex as vertices. diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index 3d0e85a..1eb4007 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -1,6 +1,6 @@ -package main.trees +package trees -import main.vertexes.SimpleBSTVertex +import vertexes.SimpleBSTVertex /** * This class represents a simple implementation of a binary search tree. @@ -18,8 +18,8 @@ import main.vertexes.SimpleBSTVertex * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not * find any matching key-value pair the get operation will fail. * - * @param K The type of keys in the tree. - * @param V The type of values in the tree. + * @param K key type + * @param V value type * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. * @property size The number of elements in the tree. * @property root The root vertex of the tree. diff --git a/lib/src/main/kotlin/vertexes/AVLVertex.kt b/lib/src/main/kotlin/vertexes/AVLVertex.kt index 64f0a9a..c1a794b 100644 --- a/lib/src/main/kotlin/vertexes/AVLVertex.kt +++ b/lib/src/main/kotlin/vertexes/AVLVertex.kt @@ -1,4 +1,4 @@ -package main.vertexes +package vertexes /** * Represents a vertex in an AVL tree. diff --git a/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt b/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt index 41b7e85..3ed7395 100644 --- a/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt +++ b/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt @@ -1,4 +1,4 @@ -package main.vertexes +package vertexes /** * Represents a generic vertex in a Binary Search Tree (BST). diff --git a/lib/src/main/kotlin/vertexes/RBVertex.kt b/lib/src/main/kotlin/vertexes/RBVertex.kt index 4a4e06c..e9a38be 100644 --- a/lib/src/main/kotlin/vertexes/RBVertex.kt +++ b/lib/src/main/kotlin/vertexes/RBVertex.kt @@ -1,4 +1,4 @@ -package main.vertexes +package vertexes /** * Represents a vertex in a Red-Black Tree. diff --git a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt index 59dc7b9..9d2eff5 100644 --- a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt +++ b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt @@ -1,4 +1,4 @@ -package main.vertexes +package vertexes /** * Represents a simple vertex in a Binary Search Tree. diff --git a/lib/src/test/kotlin/AbstractTreeTest.kt b/lib/src/test/kotlin/AbstractTreeTest.kt index a88ddad..8410621 100644 --- a/lib/src/test/kotlin/AbstractTreeTest.kt +++ b/lib/src/test/kotlin/AbstractTreeTest.kt @@ -1,7 +1,6 @@ -import main.vertexes.SimpleBSTVertex -import org.junit.jupiter.api.Test import org.junit.jupiter.api.Assertions.* -import java.util.Comparator +import org.junit.jupiter.api.Test +import vertexes.SimpleBSTVertex class AbstractTreeTest { diff --git a/lib/src/test/kotlin/TestTree.kt b/lib/src/test/kotlin/TestTree.kt index e19a65f..cbaa74a 100644 --- a/lib/src/test/kotlin/TestTree.kt +++ b/lib/src/test/kotlin/TestTree.kt @@ -1,7 +1,7 @@ -import main.trees.AbstractBinarySearchTree -import main.vertexes.SimpleBSTVertex +import trees.AbstractBinarySearchTree +import vertexes.SimpleBSTVertex -class TestTree : AbstractBinarySearchTree> { +class TestTree : AbstractBinarySearchTree> { var removeShouldReturns : V? = null var getShouldReturns : V? = null @@ -16,7 +16,7 @@ class TestTree : AbstractBinarySearchTree> { fun compareKeysT(firstKey: K, secondKey: K): Int { return super.compareKeys(firstKey, secondKey) } - constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : + constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : super(comparator) { this.root = root this.size = size diff --git a/lib/src/test/kotlin/iterator/IteratorTests.kt b/lib/src/test/kotlin/iterator/IteratorTests.kt index fb46e01..508d05b 100644 --- a/lib/src/test/kotlin/iterator/IteratorTests.kt +++ b/lib/src/test/kotlin/iterator/IteratorTests.kt @@ -1,8 +1,8 @@ package iterator -import main.trees.AVLSearchTree -import main.vertexes.SimpleBSTVertex import org.junit.jupiter.api.Assertions.assertEquals +import trees.AVLSearchTree +import vertexes.SimpleBSTVertex import kotlin.test.Test class IteratorTests { diff --git a/lib/src/test/kotlin/iterator/TestIterator.kt b/lib/src/test/kotlin/iterator/TestIterator.kt index 9f9b9ac..d42d08d 100644 --- a/lib/src/test/kotlin/iterator/TestIterator.kt +++ b/lib/src/test/kotlin/iterator/TestIterator.kt @@ -1,11 +1,10 @@ package iterator -import main.iterator.TreeIterator -import main.vertexes.InterfaceBSTVertex -import java.util.LinkedList +import vertexes.InterfaceBSTVertex +import java.util.Stack internal class TestIterator>(vertex: N?) : TreeIterator(vertex) { - fun getTreeStack(): LinkedList { + fun getTreeStack(): Stack { return stack } } diff --git a/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt b/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt index be7f784..177c166 100644 --- a/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt +++ b/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt @@ -1,11 +1,8 @@ package trees.abstractTree -import main.vertexes.SimpleBSTVertex -import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Assertions.assertNotNull -import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test -import java.util.Comparator +import vertexes.SimpleBSTVertex class AbstractTreeTest { private fun makeEmptyTree(): TestTree { diff --git a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt index 74963f8..c74b3c0 100644 --- a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt +++ b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt @@ -1,7 +1,7 @@ package trees.abstractTree -import main.trees.AbstractBinarySearchTree -import main.vertexes.SimpleBSTVertex +import trees.AbstractBinarySearchTree +import vertexes.SimpleBSTVertex class TestTree : AbstractBinarySearchTree> { var removeShouldReturns: V? = null diff --git a/lib/src/test/kotlin/trees/avlTree/AVLTreeForTest.kt b/lib/src/test/kotlin/trees/avlTree/AVLTreeForTest.kt index c12b9be..7266073 100644 --- a/lib/src/test/kotlin/trees/avlTree/AVLTreeForTest.kt +++ b/lib/src/test/kotlin/trees/avlTree/AVLTreeForTest.kt @@ -1,9 +1,7 @@ package trees.avlTree -import main.trees.AVLSearchTree -import main.vertexes.AVLVertex -import kotlin.collections.mutableListOf -import kotlin.collections.mutableMapOf +import trees.AVLSearchTree +import vertexes.AVLVertex import kotlin.math.max class AVLTreeForTest : AVLSearchTree { diff --git a/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt b/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt index 87f6da8..3584853 100644 --- a/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt +++ b/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt @@ -1,6 +1,6 @@ package trees.avlTree -import main.vertexes.AVLVertex +import vertexes.AVLVertex object AuxiliaryFunctions { fun isTreeConsistsOf( diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt index 7412eb9..e133fcf 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt @@ -1,11 +1,11 @@ package trees.avlTree.putTest -import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf -import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import vertexes.AVLVertex class HaveToDoBigRotation { private fun makeTreeForHaveToDoBigLeftRotationPutTest(): AVLTreeForTest { diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt index 122ffca..f29c7d4 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt @@ -1,11 +1,11 @@ package trees.avlTree.putTest -import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf -import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import vertexes.AVLVertex class HaveToRotateLeft { private fun makeTreeForHaveToRotateLeftPutTest(): AVLTreeForTest { diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt index 553c9fe..fadb7f4 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt @@ -1,11 +1,12 @@ package trees.avlTree.putTest -import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf -import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import vertexes.AVLVertex + class HaveToRotateRight { private fun makeTreeForHaveToRotateRightPutTest(): AVLTreeForTest { val leftSonSLeftSon = AVLVertex('c', 'C', AVLVertex('b', 'B'), AVLVertex('d', 'D')) diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt b/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt index 2323fd2..0a7bb63 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt @@ -1,9 +1,9 @@ package trees.avlTree.putTest -import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf -import main.vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import vertexes.AVLVertex class Other { private fun makeSize1Tree(): AVLTreeForTest { diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt b/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt index 352eea4..5787a46 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt @@ -1,11 +1,11 @@ package trees.avlTree.putTest -import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf -import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect +import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf +import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat +import vertexes.AVLVertex class WithoutBalancing { private fun makeEmptyTree(): AVLTreeForTest { diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt index 99d6788..0738668 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt @@ -3,7 +3,7 @@ package trees.avlTree.removeTest import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex +import vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt index a401fb9..9931ebd 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt @@ -3,7 +3,7 @@ package trees.avlTree.removeTest import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex +import vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt index c0fc939..e4db51e 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt @@ -3,7 +3,7 @@ package trees.avlTree.removeTest import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex +import vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt index 6d73b6f..0e714f6 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt @@ -3,7 +3,7 @@ package trees.avlTree.removeTest.withoutBalancing import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex +import vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt index 51f2a02..3e3516f 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt @@ -3,7 +3,7 @@ package trees.avlTree.removeTest.withoutBalancing import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect -import main.vertexes.AVLVertex +import vertexes.AVLVertex import org.junit.jupiter.api.Test import trees.avlTree.AVLTreeForTest diff --git a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt index 3fdde9c..cd3b5a0 100644 --- a/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt +++ b/lib/src/test/kotlin/trees/rbTree/RBSearchTreeTest.kt @@ -1,9 +1,9 @@ package trees.rbTree -import main.trees.RBSearchTree import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import trees.RBSearchTree import kotlin.test.assertEquals class RBSearchTreeTest { diff --git a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt index 47a9e24..afd94d4 100644 --- a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt +++ b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt @@ -4,7 +4,7 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import kotlin.test.assertEquals -class SimpleBSTreeTest { +class SimpleBSTForTest { private lateinit var tree: TestSimpleBST @BeforeEach @@ -173,8 +173,6 @@ class SimpleBSTreeTest { // 5 // ^ // 0 null -// ^ -// null null val returned = tree.remove(5) assertEquals("zero", tree.getTreeRoot()?.value) @@ -189,8 +187,6 @@ class SimpleBSTreeTest { // 5 // ^ // null 6 -// ^ -// null null val returned = tree.remove(5) assertEquals("six", tree.getTreeRoot()?.value) @@ -205,8 +201,6 @@ class SimpleBSTreeTest { // 5 // ^ // 0 null -// ^ -// null null val returned = tree.remove(0) assertEquals("five", tree.getTreeRoot()?.value) diff --git a/lib/src/test/kotlin/trees/simpleBSTree/TestSimpleBST.kt b/lib/src/test/kotlin/trees/simpleBSTree/TestSimpleBST.kt index b80da47..249accb 100644 --- a/lib/src/test/kotlin/trees/simpleBSTree/TestSimpleBST.kt +++ b/lib/src/test/kotlin/trees/simpleBSTree/TestSimpleBST.kt @@ -1,7 +1,7 @@ package trees.simpleBSTree -import main.trees.SimpleBinarySearchTree -import main.vertexes.SimpleBSTVertex +import trees.SimpleBinarySearchTree +import vertexes.SimpleBSTVertex class TestSimpleBST : SimpleBinarySearchTree { fun getTreeRoot(): SimpleBSTVertex? { From 383ec97fd8b1bffa8c897a2164429afe91fa062f Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 7 Apr 2024 19:19:55 +0300 Subject: [PATCH 215/227] docs(AbstractTree): supplement documentation --- .../kotlin/trees/AbstractBinarySearchTree.kt | 172 ++++++++++-------- 1 file changed, 98 insertions(+), 74 deletions(-) diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index ccdb2e9..4b297c5 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -6,78 +6,68 @@ import vertexes.InterfaceBSTVertex /** * An abstract class representing a binary search tree. * - * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that - * is incomparable with the keys in the tree, the behavior is as follows: + * If the tree has an incomparable key type and comparator is `null`, if the tree + * is non-empty, when trying to call the search, insert and delete methods, the tree + * will remain unchanged, the operation throws an exception with the message "Key's + * type is incomparable and comparator was not given". * - * **Put**: If an attempt is made to insert a key-value pair with a key that is incomparable with the existing - * keys in the tree, the insertion operation will fail and the tree will remain unchanged. - * - * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys - * in the tree, the removal operation will fail and the tree will remain unchanged. - * - * **Get**: When searching for a key that is incomparable with the keys in the tree, the search operation will not - * find any matching key-value pair. - * - * @param K The type of keys. - * @param V The type of values. - * @param N The type of vertices implementing the [InterfaceBSTVertex] interface. - * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. - * @property size The number of elements in the tree. - * @property root The root vertex of the tree. + * @param K key type + * @param V value type + * @param N vertex type implementing the [InterfaceBSTVertex] interface + * @property comparator used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. + * @property size number of tree vertices + * @property root */ abstract class AbstractBinarySearchTree> { - /** Comparator used for comparing keys. */ - protected var comparator: Comparator? = null - /** The number of elements in the tree. */ + protected var comparator: Comparator? = null protected var size: Long = 0L - - /** The root vertex of the tree. */ protected var root: N? = null /** - * Returns an iterator over the elements in this tree in proper sequence. - * @return an iterator over the elements in this tree in proper sequence + * Returns an iterator over the elements of this tree in a certain sequence */ operator fun iterator(): Iterator> { return TreeIterator(root) } /** - * Returns the number of key-value pairs in this tree. - * @return the number of key-value pairs in this tree + * Returns the number of key-value pairs in this tree */ fun size(): Long { return size } /** - * Returns true if this tree contains no key-value pairs. - * @return true if this tree contains no key-value pairs + * Returns `true` if this tree contains no key-value pairs, and `false` otherwise */ fun isEmpty(): Boolean { return size == 0L } + /** + * Returns `true` if this tree contains at least one key-value pair, and `false` otherwise + */ fun isNotEmpty(): Boolean { return size != 0L } /** - * Returns the value associated with the specified key in this tree. - * If the key is not found, returns null. - * @param key the key whose associated value is to be returned - * @return the value associated with the specified key, or null if the key is not found + * Returns the value associated with the specified key in this tree + * + * @param key `K` type + * @return If the key exists - corresponding value + * If the key does not exist - `null` */ fun get(key: K): V? { return getRec(key) } /** - * Returns a Pair containing the specified key-value mapping, if found. - * If the key is not found, returns null. - * @param key the key whose associated value is to be returned - * @return a Pair containing the specified key-value mapping, or null if the key is not found + * Returns a pair containing the specified key-value mapping + * + * @param key `K` type + * @return If the key exists - pair. If the key does not exist - `null`. */ fun getPair(key: K): Pair? { val value = get(key) @@ -85,8 +75,9 @@ abstract class AbstractBinarySearchTree> { } /** - * Returns the minimum value in the tree, or null if the tree is empty. - * @return the minimum value in the tree, or null if the tree is empty + * Returns the minimum key in the tree + * + * @return If the tree is not empty - minimum key, and `null` otherwise */ fun getMin(): V? { val minKeyNode = getMinKeyNodeRec() @@ -94,8 +85,9 @@ abstract class AbstractBinarySearchTree> { } /** - * Returns the maximum value in the tree, or null if the tree is empty. - * @return the maximum value in the tree, or null if the tree is empty + * Returns the maximum key in the tree + * + * @return If the tree is not empty - maximum key, and `null` otherwise */ fun getMax(): V? { val maxKeyNode = getMaxKeyNodeRec() @@ -103,8 +95,9 @@ abstract class AbstractBinarySearchTree> { } /** - * Returns a Pair containing the minimum key-value mapping in the tree, or null if the tree is empty. - * @return a Pair containing the minimum key-value mapping in the tree, or null if the tree is empty + * Returns key-value pair with the minimum key in the tree + * + * @return If the tree is not empty - pair with minimum key, and `null` otherwise */ fun getMinKeyPair(): Pair? { val minKeyNode = getMinKeyNodeRec() @@ -112,14 +105,24 @@ abstract class AbstractBinarySearchTree> { } /** - * Returns a Pair containing the maximum key-value mapping in the tree, or null if the tree is empty. - * @return a Pair containing the maximum key-value mapping in the tree, or null if the tree is empty + * Returns key-value pair with the maximum key in the tree + * + * @return If the tree is not empty - pair with maximum key, and `null` otherwise */ fun getMaxKeyPair(): Pair? { val maxKeyNode = getMaxKeyNodeRec() return if (maxKeyNode == null) null else Pair(maxKeyNode.key, maxKeyNode.value) } + /** + * Puts a new vertex of a certain type into the tree with a given key and value + * + * @param key `K` type + * @param value `V` type, associated with this key + * @param replaceIfExists `Boolean` type, + * + * If `true` - replaces the value if the key already exists. If `false` - ignores it. + */ abstract fun put( key: K, value: V, @@ -127,10 +130,13 @@ abstract class AbstractBinarySearchTree> { ) /** - * Put all pairs from the specified map to this tree. - * If parameter replaceIfExists is true and a key already exists, the value is replaced; otherwise, the value is ignored. - * @param map the map whose mappings are to be added to this tree - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * Puts all key-value pairs from the specified map to this tree + * + * @param map `Map` type + * @param replaceIfExists `Boolean` type. + * If `true` - replaces the value if the key already exists. If `false` - ignores it. + * Supplied only if a [comparator] is present. If [comparator] is `null`, the value is replaced + * by the last value from the key-value pair in the map, where the key is the one already existing in the tree. */ fun putAll( map: Map, @@ -140,16 +146,18 @@ abstract class AbstractBinarySearchTree> { } /** - * Removes the mapping for a key from this tree if it is present. - * @param key the key whose mapping is to be removed from the tree - * @return the previous value associated with key, or null if there was no mapping for key + * Deletes a vertex by the entered key and returns the value stored in it + * + * @param key `K` type + * @return If a vertex with this key exists in the tree - the value stored in this vertex, otherwise `null` */ abstract fun remove(key: K): V? /** - * Removes the mapping for a key from this tree if it is present, and returns it as a Pair. - * @param key the key whose mapping is to be removed from the tree - * @return a Pair containing the removed key-value mapping, or null if the key was not found + * Deletes a vertex by the entered key and returns it as a key-value pair + * + * @param key `K` type + * @return If a vertex with such a key exists in the tree - the key-value pair corresponding to this vertex, otherwise `null` */ fun removeAndReturnPair(key: K): Pair? { val value = remove(key) @@ -157,10 +165,11 @@ abstract class AbstractBinarySearchTree> { } /** - * Recursively searches for the value associated with the specified key. - * @param key the key to search for - * @param vertex the current vertex being examined - * @return the value associated with the specified key, or null if not found + * Recursively searches for the value associated with the entered key + * + * @param key `K` type + * @param vertex `N?` type, `root` by default; current vertex being examined + * @return If a vertex with this key exists in the tree - the value stored in this vertex, otherwise `null` */ private fun getRec( key: K, @@ -175,9 +184,10 @@ abstract class AbstractBinarySearchTree> { } /** - * Recursively finds the vertex with the minimum key in the tree. - * @param vertex the current vertex being examined - * @return the vertex with the minimum key in the tree, or null if the tree is empty + * Recursively searches for the value associated with the minimum key in the tree + * + * @param vertex `N?` type, `root` by default; current vertex being examined + * @return If the tree is not empty - the vertex with the minimum key in the tree, otherwise `null` */ protected fun getMinKeyNodeRec(vertex: N? = root): N? { if (vertex == null) { @@ -192,9 +202,10 @@ abstract class AbstractBinarySearchTree> { } /** - * Recursively finds the vertex with the maximum key in the tree. - * @param vertex the current vertex being examined - * @return the vertex with the maximum key in the tree, or null if the tree is empty + * Recursively searches for the value associated with the maximum key in the tree + * + * @param vertex `N?` type, `root` by default; current vertex being examined + * @return If the tree is not empty - the vertex with the maximum key in the tree, otherwise `null` */ protected fun getMaxKeyNodeRec(vertex: N? = root): N? { if (vertex == null) { @@ -209,10 +220,17 @@ abstract class AbstractBinarySearchTree> { } /** - * Compares two keys. - * @param firstKey the first key to compare - * @param secondKey the second key to compare - * @return -1 if the first key is less than the second key, 0 if they are equal, or 1 if the first key is greater than the second key + * Compares two keys + * + * Comparing with a comparator if it is not `null`, or without one if the comparator is null and + * the keys are of comparable type + * + * @param firstKey `K` type + * @param secondKey `K` type + * @return + * -1 if the first key is less than the second key; + * 0 if they are equal; + * 1 if the first key is greater than the second key. */ protected fun compareKeys( firstKey: K, @@ -237,18 +255,24 @@ abstract class AbstractBinarySearchTree> { } /** - * Constructs a new binary search tree with the specified comparator. - * @param comparator the comparator to use for comparing keys, or null to use natural ordering + * Constructs a new binary search tree with the specified comparator + * + * @param comparator `Comparator?` type, `null `by default; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. */ constructor(comparator: Comparator? = null) { this.comparator = comparator } /** - * Constructs a new binary search tree and initializes it with the mappings from the specified map. - * @param map the map whose mappings are to be added to this tree - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it - * @param comparator the comparator to use for comparing keys, or null to use natural ordering + * Constructs a new binary search tree and puts all key-value pairs from the specified map to this tree + * + * @param map `Map` type + * @param replaceIfExists `Boolean` type. + * If `true` - replaces the value if the key already exists. If `false` - ignores it. + * Supplied only if a [comparator] is present. If comparator is `null`, the value is replaced + * by the last value from the key-value pair in the map, where the key is the one already existing in the tree. + * + * @param comparator `Comparator?` type, `null `by default; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) { this.comparator = comparator From f1231a8b0fbf472ca7f530b0d04cc602f28c778b Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Sun, 7 Apr 2024 23:58:18 +0300 Subject: [PATCH 216/227] docs(vertexes): remove obvious parameter descriptions --- lib/src/main/kotlin/vertexes/AVLVertex.kt | 30 +++++++++-------- .../kotlin/vertexes/InterfaceBSTVertex.kt | 17 +++++----- lib/src/main/kotlin/vertexes/RBVertex.kt | 32 +++++++++---------- .../main/kotlin/vertexes/SimpleBSTVertex.kt | 26 ++++++++------- 4 files changed, 55 insertions(+), 50 deletions(-) diff --git a/lib/src/main/kotlin/vertexes/AVLVertex.kt b/lib/src/main/kotlin/vertexes/AVLVertex.kt index c1a794b..05c298a 100644 --- a/lib/src/main/kotlin/vertexes/AVLVertex.kt +++ b/lib/src/main/kotlin/vertexes/AVLVertex.kt @@ -1,14 +1,15 @@ package vertexes /** - * Represents a vertex in an AVL tree. - * @param K Type of keys. - * @param V Type of values. - * @property key The key associated with this vertex. - * @property value The value associated with this vertex. - * @property leftSon The left child vertex of this vertex, of type [AVLVertex]. - * @property rightSon The right child vertex of this vertex, of type [AVLVertex]. - * @property sonsHeightDiff The difference in height between the left and right subtrees. + * Represents a vertex in an AVL tree + * + * @param K key type + * @param V value type + * @property key + * @property value + * @property leftSon `AVLVertex?` type, + * @property rightSon `AVLVertex?` type + * @property sonsHeightDiff 'Int' type, difference in height between the left and right subtrees */ class AVLVertex( @@ -24,12 +25,13 @@ class AVLVertex( var sonsHeightDiff: Int = 0 /** - * Constructs a vertex with the specified key and value. - * @param key The key associated with this vertex. - * @param value The value associated with this vertex. - * @param leftSon The left child vertex of this vertex. - * @param rightSon The right child vertex of this vertex. - * @param sonsHeightDiff The difference in height between the left and right subtrees. + * Constructs vertex for AVL tree with the specified key and value + * + * @param key `K` type + * @param value `V` type + * @param leftSon `AVLVertex?` type + * @param rightSon `AVLVertex?` type + * @param sonsHeightDiff 'Int' type, 0 by default; difference in height between the left and right subtrees */ constructor( key: K, diff --git a/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt b/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt index 3ed7395..bce3946 100644 --- a/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt +++ b/lib/src/main/kotlin/vertexes/InterfaceBSTVertex.kt @@ -1,14 +1,15 @@ package vertexes /** - * Represents a generic vertex in a Binary Search Tree (BST). - * @param K Type of keys. - * @param V Type of values. - * @param N Type of the child vertices. - * @property key The key associated with this vertex. - * @property value The value associated with this vertex. - * @property leftSon The left child vertex of this vertex, of type N. - * @property rightSon The right child vertex of this vertex, of type N. + * Represents a generic vertex in a binary search tree + * + * @param K key type + * @param V value type + * @param N child vertices type + * @property key + * @property value + * @property leftSon `N?` type + * @property rightSon `N?` type */ interface InterfaceBSTVertex { var key: K diff --git a/lib/src/main/kotlin/vertexes/RBVertex.kt b/lib/src/main/kotlin/vertexes/RBVertex.kt index e9a38be..7467002 100644 --- a/lib/src/main/kotlin/vertexes/RBVertex.kt +++ b/lib/src/main/kotlin/vertexes/RBVertex.kt @@ -1,15 +1,15 @@ package vertexes /** - * Represents a vertex in a Red-Black Tree. - * @param K Type of keys. - * @param V Type of values. - * @property key The key associated with this vertex. - * @property value The value associated with this vertex. - * @property isRed A boolean indicating whether this vertex is red. - * @property parent The parent vertex of this vertex. - * @property leftSon The left child vertex of this vertex. - * @property rightSon The right child vertex of this vertex. + * Represents a vertex in a Red-Black tree + * + * @param K key type + * @param V value type + * @property key + * @property value + * @property leftSon `RBVertex?` type, `null` by default + * @property rightSon `RBVertex?` type, `null` by default + * @property parent `RBVertex?` type, `null` by default */ class RBVertex( override var key: K, @@ -21,13 +21,13 @@ class RBVertex( override var rightSon: RBVertex? = null /** - * Creates a new RBVertex with the specified parameters. - * @param key The key associated with this vertex. - * @param value The value associated with this vertex. - * @param leftSon The left child vertex of this vertex. - * @param rightSon The right child vertex of this vertex. - * @param isRed A boolean indicating whether this vertex is red. - * @param parent The parent vertex of this vertex. + * Constructs a new RBVertex with the specified parameters + * + * @param key `K` type + * @param value `V` type + * @param leftSon `RBVertex?` type + * @param rightSon `RBVertex?` type + * @param parent `RBVertex?` type */ constructor( key: K, diff --git a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt index 9d2eff5..2107434 100644 --- a/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt +++ b/lib/src/main/kotlin/vertexes/SimpleBSTVertex.kt @@ -1,13 +1,14 @@ package vertexes /** - * Represents a simple vertex in a Binary Search Tree. - * @param K Type of keys. - * @param V Type of values. - * @property key The key associated with this vertex. - * @property value The value associated with this vertex. - * @property leftSon The left child vertex of this vertex, of type SimpleBSTVertex. - * @property rightSon The right child vertex of this vertex, of type SimpleBSTVertex. + * Represents a simple vertex in a binary search tree + * + * @param K key type + * @param V value type + * @property key + * @property value + * @property leftSon `SimpleBSTVertex?` type, `null` by default + * @property rightSon `SimpleBSTVertex?` type, `null` by default */ class SimpleBSTVertex( override var key: K, @@ -17,11 +18,12 @@ class SimpleBSTVertex( override var rightSon: SimpleBSTVertex? = null /** - * Constructs a simple vertex with the specified key and value. - * @param key The key associated with this vertex. - * @param value The value associated with this vertex. - * @param leftSon The left child vertex of this vertex. - * @param rightSon The right child vertex of this vertex. + * Constructs a simple vertex with the specified key and value + * + * @param key `K` type + * @param value `V` type + * @param leftSon `SimpleBSTVertex?` type + * @param rightSon `SimpleBSTVertex?` type */ constructor( key: K, From b1b848ee398da34c544e6e7b17359d2b63855a3d Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 8 Apr 2024 00:34:40 +0300 Subject: [PATCH 217/227] docs(AVL): change the class description and add types of function parameters --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 128 +++++++++++---------- 1 file changed, 67 insertions(+), 61 deletions(-) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index da4ffc9..3e68906 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -4,34 +4,27 @@ import vertexes.AVLVertex /** * An implementation of a binary search tree that automatically balances itself using AVL rotations. - * It extends AbstractBinarySearchTree and uses AVLVertex as vertices. - * This class extends AbstractBinarySearchTree and provides methods to put, remove for key-value pairs. * - * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that - * is incomparable with the keys in the tree, the behavior is as follows: + * It extends [AbstractBinarySearchTree] and uses [AVLVertex] as vertices. * - * **Put**: If an attempt is made to put a key-value pair with a key that is incomparable with the existing - * keys in the tree, the insertion operation will fail and the tree will remain unchanged. + * If the tree has an incomparable key type and comparator is `null`, if the tree + * is non-empty, when trying to call the search, insert and delete methods, the tree + * will remain unchanged, the operation throws an exception with the message "Key's + * type is incomparable and comparator was not given". * - * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys - * in the tree, the removal operation will fail and the tree will remain unchanged. - * - * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not - * find any matching key-value pair the get operation will fail. - * - * @param K the type of keys in the tree - * @param V the type of values associated with the keys - * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. - * @property size The number of elements in the tree. - * @property root The root vertex of the tree. + * @param K key type + * @param V value type + * @property comparator `Comparator?` type; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. + * @property size `Long` type; number of key-value pairs in this tree + * @property root `AVLVertex?` type, `null` by default */ open class AVLSearchTree : AbstractBinarySearchTree> { /** - * Associates the specified value with the specified key in this tree. - * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. - * @param key the key with which the specified value is to be associated - * @param value the value to be associated with the specified key - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * Puts a new vertex of a certain type into the tree with a given key and value + * + * @param key `K` type + * @param value `V` type, associated with this key + * @param replaceIfExists `Boolean` type; If `true` - replaces the value if the key already exists. If `false` - ignores it. */ override fun put( key: K, @@ -50,13 +43,13 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Associates the specified value with the specified key in this tree. - * If replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. - * @param key the key with which the specified value is to be associated - * @param value the value to be associated with the specified key - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it - * @param vertex the current vertex in the recursion - * @return the root vertex of the tree after the operation + * Associates the specified value with the specified key in this tree + * + * @param key `K` type + * @param value `V` type + * @param replaceIfExists `Boolean` type; If `true` - replaces the value if the key already exists. If `false` - ignores it. + * @param vertex `AVLVertex` type; current vertex in the recursion + * @return root vertex of the tree after the operation */ private fun putRec( key: K, @@ -126,9 +119,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Removes the mapping for a key from this tree if it is present. - * @param key the key whose mapping is to be removed from the tree - * @return the previous value associated with key, or null if there was no mapping for key + * Removes the mapping for a key from this tree if it is present + * + * @param key `K` type + * @return the previous value associated with key, or `null` if there was no mapping for key */ override fun remove(key: K): V? { if (isNotEmpty()) { @@ -158,19 +152,20 @@ open class AVLSearchTree : AbstractBinarySearchTree> A, /** - * Probably need some tree changes, but not null + * Probably need some tree changes, but not make the son of the vertex `null` */ B, /** - * Need to null due "Son" property of (if exists) the parent of removed vertex + b + * Need to `null` due "Son" property of (if exists) the parent of removed vertex + b */ C, } /** - * Recursively removes a key-value pair from the subtree rooted at the given vertex. - * @param key the key to remove + * Recursively removes a key-value pair from the subtree rooted at the given vertex + * + * @param key `K` type * @param vertex the root of the subtree to remove from * @return Triple that consists of: * @@ -182,7 +177,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> * * if RemovalStage == c : the removed vertex; * - * 3) a value of the removed vertex (or null if key not exists). */ + * 3) a value of the removed vertex (or `null` if key not exists). */ private fun removeRec( key: K, vertex: AVLVertex, @@ -196,7 +191,7 @@ open class AVLSearchTree : AbstractBinarySearchTree> * if RemovalStage == b : the root of the changed subtree; * if RemovalStage == c : the removed vertex; * - * 3) a value of the removed vertex (or null if key not exists). + * 3) a value of the removed vertex (or `null` if key not exists). */ val nextCallReturned: Triple?, V?> when (compareKeys(key, vertex.key)) { @@ -294,8 +289,9 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Prepares the largest lower vertex to replace the specified vertex. - * @param subtreeSInitiallyRoot the vertex to be replaced + * Prepares the largest lower vertex to replace the specified vertex + * + * @param subtreeSInitiallyRoot `AVLVertex` type; the vertex to be replaced * @return the substitute vertex prepared to replace the specified vertex */ private fun replaceSubtreeSRootByLargestInItsLeftSubtree (subtreeSInitiallyRoot: AVLVertex): AVLVertex { @@ -308,9 +304,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Balances the subtree. - * @param curVertex the root vertex of subtree to be balanced - * @return the root vertex of the subtree after balancing + * Balances the subtree + * + * @param curVertex `AVLVertex` type; the root vertex of subtree to be balanced + * @return root vertex of the subtree after balancing */ private fun balance(curVertex: AVLVertex): AVLVertex { var (rightSon, leftSon) = List?>(2) { null } @@ -377,9 +374,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Performs a single left rotation of the subtree. - * @param curVertex the current vertex to rotate around (the subtree's root) - * @param rightSon the right son of the subtree's root + * Performs a single left rotation of the subtree + * + * @param curVertex `AVLVertex` type; the current vertex to rotate around (the subtree's root) + * @param rightSon `AVLVertex` type; the right son of the subtree's root * @return the new root of the subtree after rotation */ private fun rotateLeft( @@ -392,9 +390,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Performs a single right rotation of the subtree. - * @param curVertex the current vertex to rotate around (the subtree's root) - * @param leftSon the left son of the subtree's root + * Performs a single right rotation of the subtree + * + * @param curVertex `AVLVertex` type; the current vertex to rotate around (the subtree's root) + * @param leftSon `AVLVertex` type; the left son of the subtree's root * @return the new root of the subtree after rotation */ private fun rotateRight( @@ -407,9 +406,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Performs a big left rotation of the subtree. - * @param curVertex the current vertex to rotate around (the subtree's root) - * @param rightSon the right son of the subtree's root + * Performs a big left rotation of the subtree + * + * @param curVertex `AVLVertex` type; the current vertex to rotate around (the subtree's root) + * @param rightSon `AVLVertex` type; the right son of the subtree's root * @return the new root of the subtree after rotation */ private fun bigRotateLeft( @@ -422,9 +422,10 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Performs a big right rotation of the subtree. - * @param curVertex the current vertex to rotate around (the subtree's root) - * @param leftSon the left son vertex of the subtree's root + * Performs a big right rotation of the subtree + * + * @param curVertex `AVLVertex` type; the current vertex to rotate around (the subtree's root) + * @param leftSon `AVLVertex` type; the left son vertex of the subtree's root * @return the new root of the subtree after rotation */ private fun bigRotateRight( @@ -437,16 +438,21 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Constructs a new binary search tree with the specified comparator. - * @param comparator the comparator to use for comparing keys, or null to use natural ordering + * Constructs a new binary search tree with the specified comparator + * + * @param comparator `Comparator?` type, `null `by default; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. */ constructor (comparator: Comparator? = null) : super(comparator) /** - * Constructs a new binary search tree and initializes it with the mappings from the specified map. - * @param map the map whose mappings are to be added to this tree - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it - * @param comparator the comparator to use for comparing keys, or null to use natural ordering + * Constructs a new binary search tree and puts all key-value pairs from the specified map to this tree + * + * @param map `Map` type + * @param replaceIfExists `Boolean` type. + * If `true` - replaces the value if the key already exists. If `false` - ignores it. + * Supplied only if a [comparator] is present. If comparator is `null`, the value is replaced + * by the last value from the key-value pair in the map, where the key is the one already existing in the tree. + * @param comparator `Comparator?` type, `null `by default; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( map, From d329d487d9bdb7fe7c2c91aa767293a12750d3c6 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 8 Apr 2024 00:57:12 +0300 Subject: [PATCH 218/227] docs(RB, BST, AbstractTree): add function parameter types --- .../kotlin/trees/AbstractBinarySearchTree.kt | 6 +- lib/src/main/kotlin/trees/RBSearchTree.kt | 104 ++++++++++-------- .../kotlin/trees/SimpleBinarySearchTree.kt | 72 ++++++------ 3 files changed, 100 insertions(+), 82 deletions(-) diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index 4b297c5..fc06e5b 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -14,9 +14,9 @@ import vertexes.InterfaceBSTVertex * @param K key type * @param V value type * @param N vertex type implementing the [InterfaceBSTVertex] interface - * @property comparator used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. - * @property size number of tree vertices - * @property root + * @property comparator `Comparator?` type; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. + * @property size `Long` type; number of key-value pairs in this tree + * @property root `N?` type, `null` by default */ abstract class AbstractBinarySearchTree> { diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 8964228..15b4dde 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -3,33 +3,28 @@ package trees import vertexes.RBVertex /** - * Red-Black Tree implementation. It extends AbstractBinarySearchTree and uses RBVertex as vertices. + * Red-Black Tree implementation. + * + * It extends [AbstractBinarySearchTree] and uses [RBVertex] as vertices. * Red-Black Tree is a balanced binary search tree, where each vertex is colored either red or black. * This implementation ensures the following properties: * * - Every vertex is either red or black. * - The root is black. - * - Every leaf (NIL) is black. + * - Every leaf is black. * - If a vertex is red, then both its children are black. - * - Every simple path from a vertex to a descendant leaf (NIL) has the same number of black vertexes. - * - * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that - * is incomparable with the keys in the tree, the behavior is as follows: - * - * **Put**: If an attempt is made to put a key-value pair with a key that is incomparable with the existing - * keys in the tree, the insertion operation will fail and the tree will remain unchanged. + * - Every simple path from a vertex to a descendant leaf has the same number of black vertexes. * - * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys - * in the tree, the removal operation will fail and the tree will remain unchanged. + * If the tree has an incomparable key type and comparator is `null`, if the tree + * is non-empty, when trying to call the search, insert and delete methods, the tree + * will remain unchanged, the operation throws an exception with the message "Key's + * type is incomparable and comparator was not given". * - * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not - * find any matching key-value pair the get operation will fail. - * - * @param K the type of keys in the tree - * @param V the type of values associated with the keys - * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. - * @property size The number of elements in the tree. - * @property root The root vertex of the tree. + * @param K key type + * @param V value type + * @property comparator `Comparator?` type; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. + * @property size `Long` type; number of key-value pairs in this tree + * @property root `RBVertex?` type, `null` by default */ class RBSearchTree : AbstractBinarySearchTree> { /** @@ -51,8 +46,8 @@ class RBSearchTree : AbstractBinarySearchTree> { * * 4) remove black vertex with 0 children -> just remove vertex * - * @param key the key of the vertex to be removed - * @return the value associated with the removed vertex, or null if the key is not found + * @param key `K` type + * @return value associated with the removed vertex, or `null` if the key is not found */ override fun remove(key: K): V? { val vertex: RBVertex = getVertex(key) ?: return null @@ -70,7 +65,8 @@ class RBSearchTree : AbstractBinarySearchTree> { /** * Determines whether balancing is required after removing a vertex from the Red-Black Search Tree. - * @param vertex The vertex to be checked for balancing. + * + * @param vertex `RBVertex` type; The vertex to be checked for balancing. * @return true if further balancing is required, false otherwise. */ private fun needToBalance(vertex: RBVertex): Boolean { @@ -108,6 +104,7 @@ class RBSearchTree : AbstractBinarySearchTree> { /** * We need to balance tree after removal black vertex with 0 children. + * * In this fun we need to look at vertex's parent and brother: * 1) brother is black and brother's rightSon is red -> we paint * brother in parent's color, parent and brother's rightSon in black @@ -124,7 +121,8 @@ class RBSearchTree : AbstractBinarySearchTree> { * * 4) brother is red -> make brother black, parent red and * rotate left. We move conflict on level below, then we look at the previous cases - * @param vertex The child vertex of the removed vertex or null if the removed vertex had no children. + * + * @param vertex `RBVertex` type; The child vertex of the removed vertex or `null` if the removed vertex had no children. */ private fun balanceAfterRemove(vertex: RBVertex?) { var currentVertex = vertex @@ -204,9 +202,10 @@ class RBSearchTree : AbstractBinarySearchTree> { } /** - * Finds a vertex by corresponding key. If such vertex doesn't exist returns null. - * @param key The key to search for. - * @return The vertex with the corresponding key, or null if such vertex doesn't exist. + * Finds a vertex by corresponding key. If such vertex doesn't exist returns `null` + * + * @param key 'K` type + * @return vertex with the corresponding key, or `null` if such vertex doesn't exist */ private fun getVertex(key: K): RBVertex? { var currentVertex: RBVertex? = root @@ -228,10 +227,10 @@ class RBSearchTree : AbstractBinarySearchTree> { /** * Finds free place and inserts newVertex, colors it in red. - * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. - * @param key the key with which the specified value is to be associated - * @param value the value to be associated with the specified key - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * + * @param key 'K` type + * @param value `V` type + * @param replaceIfExists `Boolean` type; If `true` - replaces the value if the key already exists. If `false` - ignores it. */ override fun put( key: K, @@ -281,6 +280,7 @@ class RBSearchTree : AbstractBinarySearchTree> { /** * Balances the tree after inserting a new vertex. + * * We need to balance tree in two cases: * 1) when newVertex is root, so our root is red * 2) when parent of our newVertex is red(because newVertex is also red) @@ -291,7 +291,8 @@ class RBSearchTree : AbstractBinarySearchTree> { * launch algorithm to grandfather because now it's color changed to red * if uncle is black we also make newVertex's parent black, grandparent red * and rotate it right - * @param vertex The newly inserted vertex. + * + * @param vertex `RBVertex` type; The newly inserted vertex. */ private fun balanceAfterPut(vertex: RBVertex) { var currentVertex = vertex @@ -343,8 +344,9 @@ class RBSearchTree : AbstractBinarySearchTree> { } /** - * Counts the number of children of the given vertex. - * @param vertex The vertex whose children count is to be determined. + * Counts the number of children of the given vertex + * + * @param vertex `RBVertex` type; The vertex whose children count is to be determined. * @return The number of children of the given vertex. */ private fun countChildren(vertex: RBVertex): Int { @@ -355,16 +357,18 @@ class RBSearchTree : AbstractBinarySearchTree> { } /** - * Retrieves the child vertex of the given vertex. - * @param vertex The vertex whose child is to be retrieved. + * Retrieves the child vertex of the given vertex + * + * @param vertex `RBVertex` type; vertex The vertex whose child is to be retrieved. * @return The child vertex of the given vertex. */ private fun getChild(vertex: RBVertex) = if (vertex.leftSon != null) vertex.leftSon else vertex.rightSon /** - * Replaces the old vertex with the new vertex in the tree structure. - * @param oldVertex The old vertex to be replaced. - * @param newVertex The new vertex that replaces the old vertex. + * Replaces the old vertex with the new vertex in the tree structure + * + * @param oldVertex `RBVertex` type; The old vertex to be replaced. + * @param newVertex `RBVertex` type; The new vertex that replaces the old vertex. */ private fun replaceVertexBy( oldVertex: RBVertex, @@ -382,8 +386,10 @@ class RBSearchTree : AbstractBinarySearchTree> { /** * Performs a left rotation on the given vertex. + * * Suppose that vertex has a rightSon. Swap parent and rightSon, rightSon's leftSon becomes parent's rightSon. - * @param vertex The vertex on which the left rotation is to be performed. + * + * @param vertex `RBVertex` type; The vertex on which the left rotation is to be performed. */ private fun rotateLeft(vertex: RBVertex) { val rightVertex: RBVertex? = vertex.rightSon @@ -401,8 +407,9 @@ class RBSearchTree : AbstractBinarySearchTree> { /** * Performs a right rotation on the given vertex. + * * Suppose that vertex has a leftSon. Swap parent and leftSon, leftSon's rightSon becomes parent's leftSon. - * @param vertex The vertex on which the right rotation is to be performed. + * @param vertex `RBVertex` type; The vertex on which the right rotation is to be performed. */ private fun rotateRight(vertex: RBVertex) { val leftVertex: RBVertex? = vertex.leftSon @@ -419,16 +426,21 @@ class RBSearchTree : AbstractBinarySearchTree> { } /** - * Constructs a new binary search tree with the specified comparator. - * @param comparator the comparator to use for comparing keys, or null to use natural ordering + * Constructs a new binary search tree with the specified comparator + * + * @param comparator `Comparator?` type, `null `by default; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. */ constructor(comparator: Comparator? = null) : super(comparator) /** - * Constructs a new binary search tree and initializes it with the mappings from the specified map. - * @param map the map whose mappings are to be added to this tree - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it - * @param comparator the comparator to use for comparing keys, or null to use natural ordering + * Constructs a new binary search tree and puts all key-value pairs from the specified map to this tree + * + * @param map `Map` type + * @param replaceIfExists `Boolean` type. + * If `true` - replaces the value if the key already exists. If `false` - ignores it. + * Supplied only if a [comparator] is present. If comparator is `null`, the value is replaced + * by the last value from the key-value pair in the map, where the key is the one already existing in the tree. + * @param comparator `Comparator?` type, `null `by default; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( map, diff --git a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt index 1eb4007..b821a80 100644 --- a/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/SimpleBinarySearchTree.kt @@ -3,34 +3,30 @@ package trees import vertexes.SimpleBSTVertex /** - * This class represents a simple implementation of a binary search tree. - * It extends AbstractBinarySearchTree and uses SimpleBSTVertex as vertices. + * Simple implementation of a binary search tree. * - * When attempting to perform insertion, removal, or search operations on a non-empty binary search tree with a key that - * is incomparable with the keys in the tree, the behavior is as follows: + * It extends [AbstractBinarySearchTree] and uses [SimpleBSTVertex] as vertices. * - * **Put**: If an attempt is made to put a key-value pair with a key that is incomparable with the existing - * keys in the tree, the insertion operation will fail and the tree will remain unchanged. - * - * **Remove**: If an attempt is made to remove a key-value pair with a key that is incomparable with the existing keys - * in the tree, the removal operation will fail and the tree will remain unchanged. - * - * **Get**: When getting for a key that is incomparable with the keys in the tree, the search operation will not - * find any matching key-value pair the get operation will fail. + * If the tree has an incomparable key type and comparator is `null`, if the tree + * is non-empty, when trying to call the search, insert and delete methods, the tree + * will remain unchanged, the operation throws an exception with the message "Key's + * type is incomparable and comparator was not given". * * @param K key type * @param V value type - * @property comparator The comparator used to order the keys. If null, keys are expected to be comparable. - * @property size The number of elements in the tree. - * @property root The root vertex of the tree. + * @property comparator `Comparator?` type; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. + * @property size `Long` type; number of key-value pairs in this tree + * @property root `SimpleBSTVertex?` type, `null` by default */ open class SimpleBinarySearchTree : AbstractBinarySearchTree> { /** - * Associates the specified value with the specified key in this tree. - * If parameter replaceIfExists is true and the key already exists, the value is replaced; otherwise, the value is ignored. - * @param key the key with which the specified value is to be associated - * @param value the value to be associated with the specified key - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it + * Puts a new vertex of a certain type into the tree with a given key and value + * + * @param key `K` type + * @param value `V` type + * @param replaceIfExists `Boolean` type, + * + * If `true` - replaces the value if the key already exists. If `false` - ignores it. */ override fun put( key: K, @@ -42,10 +38,12 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree?` type, `root` by default; The current vertex in the recursion. */ private fun putRec( key: K, @@ -82,7 +80,8 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree : AbstractBinarySearchTree?` type, `root` by default; The current vertex being examined in the recursion. * @return A pair containing the updated vertex and the value associated with the removed key, or null if the key is not found. */ private fun removeRec( @@ -144,16 +145,21 @@ open class SimpleBinarySearchTree : AbstractBinarySearchTree?` type, `null `by default; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. */ constructor(comparator: Comparator? = null) : super(comparator) /** - * Constructs a new binary search tree and initializes it with the mappings from the specified map. - * @param map the map whose mappings are to be added to this tree - * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it - * @param comparator the comparator to use for comparing keys, or null to use natural ordering + * Constructs a new binary search tree and puts all key-value pairs from the specified map to this tree + * + * @param map `Map` type + * @param replaceIfExists `Boolean` type. + * If `true` - replaces the value if the key already exists. If `false` - ignores it. + * Supplied only if a [comparator] is present. If comparator is `null`, the value is replaced + * by the last value from the key-value pair in the map, where the key is the one already existing in the tree. + * @param comparator `Comparator?` type, `null `by default; used optionally to compare keys in a tree. If `null`, it is expected that keys of comparable type. */ constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( map, From 2a57ee2c4c3d6248574f3443aea7c98bdea6e1c1 Mon Sep 17 00:00:00 2001 From: Victoria Lutsyuk Date: Mon, 8 Apr 2024 00:59:20 +0300 Subject: [PATCH 219/227] docs(Iterator): refactor descriptions --- lib/src/main/kotlin/iterator/TreeIterator.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/iterator/TreeIterator.kt b/lib/src/main/kotlin/iterator/TreeIterator.kt index a64b2f8..1365945 100644 --- a/lib/src/main/kotlin/iterator/TreeIterator.kt +++ b/lib/src/main/kotlin/iterator/TreeIterator.kt @@ -5,7 +5,9 @@ import java.util.Stack /** * Iterator iterates over the vertices of the tree, visiting each vertex in the order of a depth-first traversal. - * Iterator interface implementation. + * + * [Iterator] interface implementation. + * * @param K the type of keys in the tree * @param V the type of values associated with the keys * @param N the type of tree vertices implementing InterfaceBSTVertex @@ -22,7 +24,9 @@ open class TreeIterator>( /** * Returns true if the iterator has more elements. + * * This method checks if there are more vertices to traverse in the tree. + * * @return true if the iterator has more elements, otherwise false */ override fun hasNext(): Boolean { @@ -31,7 +35,9 @@ open class TreeIterator>( /** * Returns the next element in the iteration. + * * This method returns the next vertex in the depth-first traversal of the tree. + * * @return the next element in the iteration as a Pair containing the key and value of the vertex */ override fun next(): Pair { From 4f0bcb275fb2720e48590814a3e10b0dc2248da7 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 8 Apr 2024 01:16:57 +0300 Subject: [PATCH 220/227] ci: add right path to xml --- .github/workflows/coverage.yml | 2 +- lib/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bcd858c..8e40a86 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -45,7 +45,7 @@ jobs: uses: madrapps/jacoco-report@v1.6.1 with: paths: | - ${{ github.workspace }}/**/build/reports/jacoco/prodNormalDebugCoverage/prodNormalDebugCoverage.xml, + ${{ github.workspace }}/lib/build/reports/jacoco/test/jacocoTestReport.xml, ${{ github.workspace }}/**/build/reports/jacoco/**/debugCoverage.xml token: ${{ secrets.GITHUB_TOKEN }} title: '# 🇷🇺 Coverage Report' diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index aa9fc85..0d9f8ce 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -49,7 +49,7 @@ tasks.named("jacocoTestReport") { dependsOn(tasks.test) reports { csv.required = true - xml.required = false + xml.required = true html.outputLocation = layout.buildDirectory.dir("jacocoHtml") } } From aa35352f4bb5a1de8095c7b862ad77c4b3a4942d Mon Sep 17 00:00:00 2001 From: Kostya Date: Sat, 6 Apr 2024 23:49:15 +0300 Subject: [PATCH 221/227] feat: add class enum for color --- lib/src/main/kotlin/trees/RBSearchTree.kt | 104 +++++++++++----------- lib/src/main/kotlin/vertexes/RBVertex.kt | 10 ++- 2 files changed, 61 insertions(+), 53 deletions(-) diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index dfaaa7e..37dda32 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -32,6 +32,9 @@ import main.vertexes.RBVertex * @property root The root vertex of the tree. */ class RBSearchTree : AbstractBinarySearchTree> { + private val red = RBVertex.Color.RED + private val black = RBVertex.Color.BLACK + /** * This method removes the vertex with the given key from the tree and returns its associated value, * maintaining the properties of the red-black tree. @@ -75,7 +78,7 @@ class RBSearchTree : AbstractBinarySearchTree> { private fun needToBalance(vertex: RBVertex): Boolean { when (countChildren(vertex)) { 0 -> { - if (vertex.isRed) { + if (vertex.color == red) { replaceVertexBy(vertex, null) return false } @@ -127,37 +130,37 @@ class RBSearchTree : AbstractBinarySearchTree> { */ private fun balanceAfterRemove(vertex: RBVertex?) { var currentVertex = vertex - while (currentVertex != root && (currentVertex?.isRed == false || currentVertex == null)) { + while (currentVertex != root && (currentVertex?.color == black || currentVertex == null)) { var brother: RBVertex? if (currentVertex == currentVertex?.parent?.leftSon) { brother = currentVertex?.parent?.rightSon - if (brother?.isRed == true) { - brother.isRed = false - currentVertex?.parent?.isRed = true + if (brother?.color == red) { + brother.color = black + currentVertex?.parent?.color = red val vertexForRotate = currentVertex?.parent vertexForRotate?.let { rotateLeft(vertexForRotate) } brother = currentVertex?.parent?.rightSon } - if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null) + if ((brother?.leftSon?.color == black || brother?.leftSon == null) && + (brother?.rightSon?.color == black || brother?.rightSon == null) ) { - brother?.isRed = true + brother?.color = red currentVertex = currentVertex?.parent if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null } else { - if (brother.rightSon?.isRed == false || brother.rightSon == null) { - brother.leftSon?.isRed = false - brother.isRed = true + if (brother.rightSon?.color == black || brother.rightSon == null) { + brother.leftSon?.color = black + brother.color = red rotateRight(brother) brother = currentVertex?.parent?.rightSon } - val parentColor = currentVertex?.parent?.isRed - parentColor?.let { brother?.isRed = parentColor } - currentVertex?.parent?.isRed = false - brother?.rightSon?.isRed = false + val parentColor = currentVertex?.parent?.color + parentColor?.let { brother?.color = parentColor } + currentVertex?.parent?.color = black + brother?.rightSon?.color = black val vertexForRotate = currentVertex?.parent vertexForRotate?.let { rotateLeft(vertexForRotate) } if (currentVertex == vertex) currentVertex?.parent?.leftSon = null @@ -166,32 +169,32 @@ class RBSearchTree : AbstractBinarySearchTree> { } else { brother = currentVertex?.parent?.leftSon - if (brother?.isRed == true) { - brother.isRed = false - currentVertex?.parent?.isRed = true + if (brother?.color == red) { + brother.color = black + currentVertex?.parent?.color = red val vertexForRotate = currentVertex?.parent vertexForRotate?.let { rotateRight(vertexForRotate) } brother = currentVertex?.parent?.leftSon } - if ((brother?.leftSon?.isRed == false || brother?.leftSon == null) && - (brother?.rightSon?.isRed == false || brother?.rightSon == null) + if ((brother?.leftSon?.color == black || brother?.leftSon == null) && + (brother?.rightSon?.color == black || brother?.rightSon == null) ) { - brother?.isRed = true + brother?.color = red currentVertex = currentVertex?.parent if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null } else { - if (brother.leftSon?.isRed == false || brother.leftSon == null) { - brother.rightSon?.isRed = false - brother.isRed = true + if (brother.leftSon?.color == black || brother.leftSon == null) { + brother.rightSon?.color = black + brother.color = red rotateLeft(brother) brother = currentVertex?.parent?.leftSon } - val parentColor = currentVertex?.parent?.isRed - parentColor?.let { brother?.isRed = parentColor } - currentVertex?.parent?.isRed = false - brother?.leftSon?.isRed = false + val parentColor = currentVertex?.parent?.color + parentColor?.let { brother?.color = parentColor } + currentVertex?.parent?.color = black + brother?.leftSon?.color = black val vertexForRotate = currentVertex?.parent vertexForRotate?.let { rotateRight(vertexForRotate) } if (currentVertex == vertex) currentVertex?.parent?.rightSon = null @@ -199,7 +202,7 @@ class RBSearchTree : AbstractBinarySearchTree> { } } } - currentVertex?.isRed = false + currentVertex?.color = black } /** @@ -265,7 +268,7 @@ class RBSearchTree : AbstractBinarySearchTree> { } if (currentVertex == null) { - currentVertex = RBVertex(key, value, null, null, true, parent) + currentVertex = RBVertex(key, value, null, null, red, parent) if (root == null) { root = currentVertex } else if (isLeft) { @@ -295,16 +298,16 @@ class RBSearchTree : AbstractBinarySearchTree> { private fun balanceAfterPut(vertex: RBVertex) { var currentVertex = vertex - while (currentVertex.parent?.isRed == true) { + while (currentVertex.parent?.color == red) { val grandparent = currentVertex.parent?.parent if (currentVertex.parent == grandparent?.leftSon) { val uncle = grandparent?.rightSon - if (uncle?.isRed == true) { - currentVertex.parent?.isRed = false - uncle.isRed = false - grandparent.isRed = true + if (uncle?.color == red) { + currentVertex.parent?.color = black + uncle.color = black + grandparent.color = red currentVertex = grandparent } else { if (currentVertex == currentVertex.parent?.rightSon) { @@ -312,18 +315,18 @@ class RBSearchTree : AbstractBinarySearchTree> { rotateLeft(currentVertex) } - currentVertex.parent?.isRed = false - currentVertex.parent?.parent?.isRed = true + currentVertex.parent?.color = black + currentVertex.parent?.parent?.color = red val vertexForRightRotate = currentVertex.parent?.parent vertexForRightRotate?.let { rotateRight(vertexForRightRotate) } } } else { val uncle = grandparent?.leftSon - if (uncle?.isRed == true) { - currentVertex.parent?.isRed = false - uncle.isRed = false - grandparent.isRed = true + if (uncle?.color == red) { + currentVertex.parent?.color = black + uncle.color = black + grandparent.color = red currentVertex = grandparent } else { if (currentVertex == currentVertex.parent?.leftSon) { @@ -331,14 +334,14 @@ class RBSearchTree : AbstractBinarySearchTree> { rotateRight(currentVertex) } - currentVertex.parent?.isRed = false - currentVertex.parent?.parent?.isRed = true + currentVertex.parent?.color = black + currentVertex.parent?.parent?.color = red val vertexForLeftRotate = currentVertex.parent?.parent vertexForLeftRotate?.let { rotateLeft(vertexForLeftRotate) } } } } - root?.isRed = false + root?.color = black } /** @@ -421,7 +424,9 @@ class RBSearchTree : AbstractBinarySearchTree> { * Constructs a new binary search tree with the specified comparator. * @param comparator the comparator to use for comparing keys, or null to use natural ordering */ - constructor(comparator: Comparator? = null) : super(comparator) + constructor(comparator: Comparator? = null) { + this.comparator = comparator + } /** * Constructs a new binary search tree and initializes it with the mappings from the specified map. @@ -429,9 +434,8 @@ class RBSearchTree : AbstractBinarySearchTree> { * @param replaceIfExists if true, replaces the value if the key already exists, otherwise ignores it * @param comparator the comparator to use for comparing keys, or null to use natural ordering */ - constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) : super( - map, - replaceIfExists, - comparator, - ) + constructor(map: Map, replaceIfExists: Boolean = true, comparator: Comparator? = null) { + this.comparator = comparator + putAll(map, replaceIfExists) + } } diff --git a/lib/src/main/kotlin/vertexes/RBVertex.kt b/lib/src/main/kotlin/vertexes/RBVertex.kt index 4a4e06c..fe69a14 100644 --- a/lib/src/main/kotlin/vertexes/RBVertex.kt +++ b/lib/src/main/kotlin/vertexes/RBVertex.kt @@ -15,7 +15,11 @@ class RBVertex( override var key: K, override var value: V, ) : InterfaceBSTVertex> { - var isRed = true + enum class Color { + RED, + BLACK + } + var color: Color = Color.RED var parent: RBVertex? = null override var leftSon: RBVertex? = null override var rightSon: RBVertex? = null @@ -34,12 +38,12 @@ class RBVertex( value: V, leftSon: RBVertex?, rightSon: RBVertex?, - isRed: Boolean, + color: Color, parent: RBVertex?, ) : this(key, value) { this.leftSon = leftSon this.rightSon = rightSon this.parent = parent - this.isRed = isRed + this.color = color } } From fb9776cbdcfa911a0e247762fd6cb1acffca1358 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 14:50:45 +0300 Subject: [PATCH 222/227] fix: reuse code in balanceAfterPut, delete extra code --- lib/src/main/kotlin/trees/RBSearchTree.kt | 56 ++++++++--------------- 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 37dda32..21c0b31 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -300,45 +300,29 @@ class RBSearchTree : AbstractBinarySearchTree> { while (currentVertex.parent?.color == red) { val grandparent = currentVertex.parent?.parent - - if (currentVertex.parent == grandparent?.leftSon) { - val uncle = grandparent?.rightSon - - if (uncle?.color == red) { - currentVertex.parent?.color = black - uncle.color = black - grandparent.color = red - currentVertex = grandparent - } else { - if (currentVertex == currentVertex.parent?.rightSon) { - currentVertex = currentVertex.parent ?: currentVertex - rotateLeft(currentVertex) - } - - currentVertex.parent?.color = black - currentVertex.parent?.parent?.color = red - val vertexForRightRotate = currentVertex.parent?.parent - vertexForRightRotate?.let { rotateRight(vertexForRightRotate) } - } + val isUncleRightSon = (currentVertex.parent == grandparent?.leftSon) + val uncle = if (isUncleRightSon) grandparent?.rightSon else grandparent?.leftSon + + if (uncle?.color == red) { + currentVertex.parent?.color = black + uncle.color = black + grandparent?.color = red + currentVertex = grandparent ?: currentVertex } else { - val uncle = grandparent?.leftSon - - if (uncle?.color == red) { - currentVertex.parent?.color = black - uncle.color = black - grandparent.color = red - currentVertex = grandparent - } else { - if (currentVertex == currentVertex.parent?.leftSon) { - currentVertex = currentVertex.parent ?: currentVertex - rotateRight(currentVertex) - } + if ((isUncleRightSon) && (currentVertex == currentVertex.parent?.rightSon)) { + currentVertex = currentVertex.parent ?: currentVertex + rotateLeft(currentVertex) + } - currentVertex.parent?.color = black - currentVertex.parent?.parent?.color = red - val vertexForLeftRotate = currentVertex.parent?.parent - vertexForLeftRotate?.let { rotateLeft(vertexForLeftRotate) } + else if ((!isUncleRightSon) && (currentVertex == currentVertex.parent?.leftSon)) { + currentVertex = currentVertex.parent ?: currentVertex + rotateRight(currentVertex) } + + currentVertex.parent?.color = black + currentVertex.parent?.parent?.color = red + val vertexForRotate = currentVertex.parent?.parent + vertexForRotate?.let { if (isUncleRightSon) rotateRight(vertexForRotate) else rotateLeft(vertexForRotate) } } } root?.color = black From da11d49f823fa90023e1405e62b1d9547fdb2111 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 16:45:54 +0300 Subject: [PATCH 223/227] fix: reuse code in BalanceAfterRemove, delete extra code --- lib/src/main/kotlin/trees/RBSearchTree.kt | 110 ++++++++++------------ 1 file changed, 51 insertions(+), 59 deletions(-) diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 21c0b31..63518a8 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -41,14 +41,14 @@ class RBSearchTree : AbstractBinarySearchTree> { * * 4 cases we need to look at: * - * 1) remove red vertex with 0 children -> just remove vetrex + * 1) remove red vertex with 0 children -> just remove vertex * * 2) remove red or black vertex with 2 children -> * find min vertex on the right subtree and swap it's key and value with * key and value of vertex that we need to remove. * Now we can work with vertex which has 1 or 0 children * - * 3) remove black vetrex with 1 child -> child can be only red + * 3) remove black vertex with 1 child -> child can be only red * so we just swap child's key and value with key and value that we need to remove * and look at case 1) * @@ -131,75 +131,67 @@ class RBSearchTree : AbstractBinarySearchTree> { private fun balanceAfterRemove(vertex: RBVertex?) { var currentVertex = vertex while (currentVertex != root && (currentVertex?.color == black || currentVertex == null)) { - var brother: RBVertex? - if (currentVertex == currentVertex?.parent?.leftSon) { - brother = currentVertex?.parent?.rightSon - - if (brother?.color == red) { - brother.color = black - currentVertex?.parent?.color = red - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateLeft(vertexForRotate) } - brother = currentVertex?.parent?.rightSon - } + val isBrotherRightSon = (currentVertex == currentVertex?.parent?.leftSon) + var brother: RBVertex? = if (isBrotherRightSon) currentVertex?.parent?.rightSon else currentVertex?.parent?.leftSon + + if (brother?.color == red) { + brother.color = black + currentVertex?.parent?.color = red + val vertexForRotate = currentVertex?.parent - if ((brother?.leftSon?.color == black || brother?.leftSon == null) && - (brother?.rightSon?.color == black || brother?.rightSon == null) - ) { - brother?.color = red - currentVertex = currentVertex?.parent - if (vertex == currentVertex?.leftSon) currentVertex?.leftSon = null - } else { - if (brother.rightSon?.color == black || brother.rightSon == null) { - brother.leftSon?.color = black - brother.color = red - rotateRight(brother) + when (isBrotherRightSon) { + true -> { + vertexForRotate?.let { rotateLeft(vertexForRotate) } brother = currentVertex?.parent?.rightSon + } else -> { + vertexForRotate?.let { rotateRight(vertexForRotate) } + brother = currentVertex?.parent?.leftSon } + } + } - val parentColor = currentVertex?.parent?.color - parentColor?.let { brother?.color = parentColor } - currentVertex?.parent?.color = black - brother?.rightSon?.color = black - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateLeft(vertexForRotate) } - if (currentVertex == vertex) currentVertex?.parent?.leftSon = null - currentVertex = root + if ((brother?.leftSon?.color == black || brother?.leftSon == null) && + (brother?.rightSon?.color == black || brother?.rightSon == null) + ) { + brother?.color = red + currentVertex = currentVertex?.parent + + when (vertex) { + currentVertex?.leftSon -> currentVertex?.leftSon = null + currentVertex?.rightSon -> currentVertex?.rightSon = null } } else { - brother = currentVertex?.parent?.leftSon + if ((isBrotherRightSon) && (brother.rightSon?.color == black || brother.rightSon == null)) { + brother.leftSon?.color = black + brother.color = red + rotateRight(brother) + brother = currentVertex?.parent?.rightSon + } - if (brother?.color == red) { - brother.color = black - currentVertex?.parent?.color = red - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateRight(vertexForRotate) } + else if ((!isBrotherRightSon) && (brother.leftSon?.color == black || brother.leftSon == null)) { + brother.rightSon?.color = black + brother.color = red + rotateLeft(brother) brother = currentVertex?.parent?.leftSon } - if ((brother?.leftSon?.color == black || brother?.leftSon == null) && - (brother?.rightSon?.color == black || brother?.rightSon == null) - ) { - brother?.color = red - currentVertex = currentVertex?.parent - if (vertex == currentVertex?.rightSon) currentVertex?.rightSon = null - } else { - if (brother.leftSon?.color == black || brother.leftSon == null) { - brother.rightSon?.color = black - brother.color = red - rotateLeft(brother) - brother = currentVertex?.parent?.leftSon + val parentColor = currentVertex?.parent?.color + parentColor?.let { brother?.color = parentColor } + currentVertex?.parent?.color = black + val vertexForRotate = currentVertex?.parent + + when (isBrotherRightSon) { + true -> { + brother?.rightSon?.color = black + vertexForRotate?.let { rotateLeft(vertexForRotate) } + if (currentVertex == vertex) currentVertex?.parent?.leftSon = null + } else -> { + brother?.leftSon?.color = black + vertexForRotate?.let { rotateRight(vertexForRotate) } + if (currentVertex == vertex) currentVertex?.parent?.rightSon = null } - - val parentColor = currentVertex?.parent?.color - parentColor?.let { brother?.color = parentColor } - currentVertex?.parent?.color = black - brother?.leftSon?.color = black - val vertexForRotate = currentVertex?.parent - vertexForRotate?.let { rotateRight(vertexForRotate) } - if (currentVertex == vertex) currentVertex?.parent?.rightSon = null - currentVertex = root } + currentVertex = root } } currentVertex?.color = black From 97e0fcd4d48ffd08d5d1e347882f147298409b64 Mon Sep 17 00:00:00 2001 From: Kostya Date: Sun, 7 Apr 2024 21:55:08 +0300 Subject: [PATCH 224/227] docs: replace property isRed with a color --- lib/src/main/kotlin/vertexes/RBVertex.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/main/kotlin/vertexes/RBVertex.kt b/lib/src/main/kotlin/vertexes/RBVertex.kt index fe69a14..9576ddb 100644 --- a/lib/src/main/kotlin/vertexes/RBVertex.kt +++ b/lib/src/main/kotlin/vertexes/RBVertex.kt @@ -6,7 +6,7 @@ package main.vertexes * @param V Type of values. * @property key The key associated with this vertex. * @property value The value associated with this vertex. - * @property isRed A boolean indicating whether this vertex is red. + * @property color The color of this vertex (red or black). * @property parent The parent vertex of this vertex. * @property leftSon The left child vertex of this vertex. * @property rightSon The right child vertex of this vertex. @@ -30,7 +30,7 @@ class RBVertex( * @param value The value associated with this vertex. * @param leftSon The left child vertex of this vertex. * @param rightSon The right child vertex of this vertex. - * @param isRed A boolean indicating whether this vertex is red. + * @param color The color of this vertex (red or black). * @param parent The parent vertex of this vertex. */ constructor( From 6626c080ba331c7da1bea4c9a8b82ecff0765914 Mon Sep 17 00:00:00 2001 From: Kostya Oreshin <84198636+TerrMen@users.noreply.github.com> Date: Mon, 8 Apr 2024 01:59:32 +0300 Subject: [PATCH 225/227] docs: add description of replaceSubtreeSRootByLargestInItsLeftSubtree() in AVL --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 3e68906..74fd70c 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -289,10 +289,11 @@ open class AVLSearchTree : AbstractBinarySearchTree> } /** - * Prepares the largest lower vertex to replace the specified vertex + * Replaces the initially subtree's root by the its left subtree's vertex with largest key, + * having previously removed that vertex * - * @param subtreeSInitiallyRoot `AVLVertex` type; the vertex to be replaced - * @return the substitute vertex prepared to replace the specified vertex + * @param subtreeSInitiallyRoot `AVLVertex` type; initially root of the subtree + * @return vertex that is the subtree's root after function was executed */ private fun replaceSubtreeSRootByLargestInItsLeftSubtree (subtreeSInitiallyRoot: AVLVertex): AVLVertex { val substitute = getMaxKeyNodeRec(subtreeSInitiallyRoot.leftSon) as AVLVertex From ba602df0265e0c7635412bf284a8941830fe1d60 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 8 Apr 2024 09:30:56 +0300 Subject: [PATCH 226/227] style: changes according to linter --- lib/src/main/kotlin/trees/AVLSearchTree.kt | 13 +- .../kotlin/trees/AbstractBinarySearchTree.kt | 6 +- lib/src/main/kotlin/trees/RBSearchTree.kt | 8 +- lib/src/main/kotlin/vertexes/RBVertex.kt | 3 +- lib/src/test/kotlin/AbstractTreeTest.kt | 241 ------------------ lib/src/test/kotlin/TestTree.kt | 31 --- .../trees/abstractTree/AbstractTreeTest.kt | 9 +- .../kotlin/trees/abstractTree/TestTree.kt | 6 +- .../trees/avlTree/AuxiliaryFunctions.kt | 28 +- .../avlTree/putTest/HaveToDoBigRotation.kt | 144 +++++------ .../trees/avlTree/putTest/HaveToRotateLeft.kt | 37 +-- .../avlTree/putTest/HaveToRotateRight.kt | 36 +-- .../kotlin/trees/avlTree/putTest/Other.kt | 2 +- .../trees/avlTree/putTest/WithoutBalancing.kt | 1 - .../avlTree/removeTest/HaveToDoBigRotation.kt | 42 +-- .../avlTree/removeTest/HaveToRotateLeft.kt | 55 ++-- .../avlTree/removeTest/HaveToRotateRight.kt | 56 ++-- .../removeTest/withoutBalancing/Other.kt | 6 +- .../withoutBalancing/VertexHadTwoSons.kt | 97 ++++--- .../trees/simpleBSTree/SimpleBSTForTest.kt | 16 +- 20 files changed, 282 insertions(+), 555 deletions(-) delete mode 100644 lib/src/test/kotlin/AbstractTreeTest.kt delete mode 100644 lib/src/test/kotlin/TestTree.kt diff --git a/lib/src/main/kotlin/trees/AVLSearchTree.kt b/lib/src/main/kotlin/trees/AVLSearchTree.kt index 74fd70c..0fb1771 100644 --- a/lib/src/main/kotlin/trees/AVLSearchTree.kt +++ b/lib/src/main/kotlin/trees/AVLSearchTree.kt @@ -226,8 +226,8 @@ open class AVLSearchTree : AbstractBinarySearchTree> val valueOfVertex = vertex.value Triple( RemovalStage.B, - replaceSubtreeSRootByLargestInItsLeftSubtree(vertex), - valueOfVertex, + replaceSubtreeSRootByLargestInItsLeftSubtree(vertex), + valueOfVertex, ) } } @@ -295,13 +295,16 @@ open class AVLSearchTree : AbstractBinarySearchTree> * @param subtreeSInitiallyRoot `AVLVertex` type; initially root of the subtree * @return vertex that is the subtree's root after function was executed */ - private fun replaceSubtreeSRootByLargestInItsLeftSubtree (subtreeSInitiallyRoot: AVLVertex): AVLVertex { + private fun replaceSubtreeSRootByLargestInItsLeftSubtree(subtreeSInitiallyRoot: AVLVertex): AVLVertex { val substitute = getMaxKeyNodeRec(subtreeSInitiallyRoot.leftSon) as AVLVertex val removeRecReturned = removeRec(substitute.key, subtreeSInitiallyRoot) subtreeSInitiallyRoot.key = substitute.key subtreeSInitiallyRoot.value = substitute.value - return if (removeRecReturned.component1() == RemovalStage.A) subtreeSInitiallyRoot - else removeRecReturned.component2() + return if (removeRecReturned.component1() == RemovalStage.A) { + subtreeSInitiallyRoot + } else { + removeRecReturned.component2() + } } /** diff --git a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt index fc06e5b..c16753c 100644 --- a/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt +++ b/lib/src/main/kotlin/trees/AbstractBinarySearchTree.kt @@ -19,7 +19,6 @@ import vertexes.InterfaceBSTVertex * @property root `N?` type, `null` by default */ abstract class AbstractBinarySearchTree> { - protected var comparator: Comparator? = null protected var size: Long = 0L protected var root: N? = null @@ -244,8 +243,9 @@ abstract class AbstractBinarySearchTree> { else -> 1 } } else { - val comparableKey = firstKey as? Comparable ?: - throw Exception("Key's type is incomparable and comparator wasn't given") + val comparableKey = + firstKey as? Comparable + ?: throw Exception("Key's type is incomparable and comparator wasn't given") when (comparableKey.compareTo(secondKey)) { in Int.MIN_VALUE..-1 -> -1 0 -> 0 diff --git a/lib/src/main/kotlin/trees/RBSearchTree.kt b/lib/src/main/kotlin/trees/RBSearchTree.kt index 07e0f88..96e16d1 100644 --- a/lib/src/main/kotlin/trees/RBSearchTree.kt +++ b/lib/src/main/kotlin/trees/RBSearchTree.kt @@ -165,9 +165,7 @@ class RBSearchTree : AbstractBinarySearchTree> { brother.color = red rotateRight(brother) brother = currentVertex?.parent?.rightSon - } - - else if ((!isBrotherRightSon) && (brother.leftSon?.color == black || brother.leftSon == null)) { + } else if ((!isBrotherRightSon) && (brother.leftSon?.color == black || brother.leftSon == null)) { brother.rightSon?.color = black brother.color = red rotateLeft(brother) @@ -306,9 +304,7 @@ class RBSearchTree : AbstractBinarySearchTree> { if ((isUncleRightSon) && (currentVertex == currentVertex.parent?.rightSon)) { currentVertex = currentVertex.parent ?: currentVertex rotateLeft(currentVertex) - } - - else if ((!isUncleRightSon) && (currentVertex == currentVertex.parent?.leftSon)) { + } else if ((!isUncleRightSon) && (currentVertex == currentVertex.parent?.leftSon)) { currentVertex = currentVertex.parent ?: currentVertex rotateRight(currentVertex) } diff --git a/lib/src/main/kotlin/vertexes/RBVertex.kt b/lib/src/main/kotlin/vertexes/RBVertex.kt index 7cd5106..af5602e 100644 --- a/lib/src/main/kotlin/vertexes/RBVertex.kt +++ b/lib/src/main/kotlin/vertexes/RBVertex.kt @@ -17,8 +17,9 @@ class RBVertex( ) : InterfaceBSTVertex> { enum class Color { RED, - BLACK + BLACK, } + var color: Color = Color.RED var parent: RBVertex? = null override var leftSon: RBVertex? = null diff --git a/lib/src/test/kotlin/AbstractTreeTest.kt b/lib/src/test/kotlin/AbstractTreeTest.kt deleted file mode 100644 index 8410621..0000000 --- a/lib/src/test/kotlin/AbstractTreeTest.kt +++ /dev/null @@ -1,241 +0,0 @@ -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test -import vertexes.SimpleBSTVertex - -class AbstractTreeTest { - - private fun makeEmptyTree() : TestTree { - return TestTree() - } - - @Test - fun `isEmpty() returns true if tree is empty `() { - val tree = makeEmptyTree() - assert(tree.isEmpty()) - } - - @Test - fun `size() returns 0 if tree is empty`() { - val tree = makeEmptyTree() - assert(tree.size() == 0L) - } - - @Test - fun `get() returns null if tree is empty`() { - val tree = makeEmptyTree() - assertNull(tree.get(intArrayOf(0))) - } - - @Test - fun `getMax() returns null if tree is empty`() { - val tree = makeEmptyTree() - assertNull(tree.getMax()) - } - - @Test - fun `getMin() returns null if tree is empty`() { - val tree = makeEmptyTree() - assertNull(tree.getMin()) - } - - @Test - fun `getMaxKeyPair() returns null if tree is empty`() { - val tree = makeEmptyTree() - assertNull(tree.getMaxKeyPair()) - } - - @Test - fun `getMinKeyPair() returns null if tree is empty`() { - val tree = makeEmptyTree() - assertNull(tree.getMinKeyPair()) - } - - private fun makeTreeWithBothRootSSons() : TestTree { - val leftSon = SimpleBSTVertex('1', "!", SimpleBSTVertex('0', ")"), null) - val rightSon = SimpleBSTVertex('4', "$", SimpleBSTVertex('3', "#"), null) - return TestTree(SimpleBSTVertex('2', "@", leftSon, rightSon), 5L) - } - - @Test - fun `isEmpty() returns false if tree is not empty `() { - val tree = makeTreeWithBothRootSSons() - assertFalse(tree.isEmpty()) - } - - @Test - fun `size() returns not 0 if tree is not empty`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.size() != 0L) - } - - @Test - fun `get() returns null when tree doesn'n contains given key`() { - val tree = makeTreeWithBothRootSSons() - assertNull(tree.get('z')) - } - - @Test - fun `getPair() returns null when tree doesn'n contains given key`() { - val tree = makeTreeWithBothRootSSons() - assertNull(tree.getPair('z')) - } - - @Test - fun `get() returns correct value when tree contains given key in left subtree`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.get('1') == "!") - } - - @Test - fun `getPair() returns correct value when tree contains given key in left subtree`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.getPair('1') == ('1' to "!")) - } - - @Test - fun `get() returns correct value when tree contains given key in right subtree`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.get('4') == "$") - } - - @Test - fun `get() returns correct value when root's key was given`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.get('2') == "@") - } - - @Test - fun `get() returns correct value when leaf's key was given`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.get('3') == "#") - } - - @Test - fun `getMin() returns correct value when root has two sons`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.getMin() == ")") - } - - @Test - fun `getMax() returns correct value when root has two sons`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.getMax() == "$") - } - - @Test - fun `getMinKeyPair() returns correct value when root has two sons`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.getMinKeyPair() == ('0' to ")")) - } - - @Test - fun `getMaxKeyPair() returns correct value when root has two sons`() { - val tree = makeTreeWithBothRootSSons() - assert(tree.getMaxKeyPair() == ('4' to "$")) - } - - private fun makeTreeWithOnlyLeftRootSSon() : TestTree { - val leftSon = SimpleBSTVertex('1', "!", SimpleBSTVertex('0', ")"), SimpleBSTVertex('2', "@")) - return TestTree(SimpleBSTVertex('3', "#", leftSon, null), 4L) - } - - @Test - fun `getMax() returns correct value when root has only left son`() { - val tree = makeTreeWithOnlyLeftRootSSon() - assert(tree.getMax() == "#") - } - - private fun makeTreeWithOnlyRightRootSSon() : TestTree { - val rightSon = SimpleBSTVertex('6', "^", SimpleBSTVertex('5', "%"), SimpleBSTVertex('8', "*")) - return TestTree(SimpleBSTVertex('3', "#", null, rightSon), 4L) - } - - @Test - fun `getMin() returns correct value when root has only right son`() { - val tree = makeTreeWithOnlyRightRootSSon() - assert(tree.getMin() == "#") - } - - @Test - fun `removeAndReturnPair() returns null when remove() returned null`() { - val tree = TestTree(removeShouldReturns = null) - assertNull(tree.removeAndReturnPair(1)) - } - - @Test - fun `removeAndReturnPair() returns (given key) to (value that remove() returned) pair`() { - val tree = TestTree(removeShouldReturns = '1') - assert (tree.removeAndReturnPair(3) == (3 to '1')) - } - - @Test - fun `putAll() do correct put() call for each map element (1)`() { - val tree = TestTree() - val map = hashMapOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'a' to 'A') - tree.putAll(map) - for (pair in map) - assertNotNull(tree.putWasCalledWithParams.remove(Triple(pair.component1(), pair.component2(), true))) - } - - @Test - fun `putAll() do correct put() call for each map element (2)`() { - val tree = TestTree() - val map = hashMapOf('a' to 'A', 'b' to 'B', 'c' to 'C', 'a' to 'A') - tree.putAll(map, false) - for (pair in map) - assertNotNull(tree.putWasCalledWithParams.remove(Triple(pair.component1(), pair.component2(), false))) - } - - @Test - fun `compareKeys return 1 when key1 larger than key2 (keys are comparable)`() { - val tree = TestTree() - assert (tree.compareKeysT(18, 14) == 1) - } - - @Test - fun `compareKeys return 0 when key1 equals key2 (keys are comparable)`() { - val tree = TestTree() - assert (tree.compareKeysT(18, 18) == 0) - } - - @Test - fun `compareKeys return -1 when key1 lesser than key2 (keys are comparable)`() { - val tree = TestTree() - assert (tree.compareKeysT(14, 18) == -1) - } - - class cmp : Comparator { - override fun compare(o1 : IntArray, o2 : IntArray) : Int { - return o1.sum() - o2.sum() - } - } - - - @Test - fun `compareKeys return 1 when key1 larger than key2 (comparator was given)`() { - val tree = TestTree(cmp()) - assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(-1)) == 1) - } - - @Test - fun `compareKeys return 0 when key1 equals key2 (comparator was given)`() { - val tree = TestTree(cmp()) - assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(0)) == 0) - } - - @Test - fun `compareKeys return -1 when key1 lesser than key2 (comparator was given)`() { - val tree = TestTree(cmp()) - assert (tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1)) == -1) - } - - - @Test - fun `compareKeys fall when keys type doesn't implement compareble && comparator wasn't given`() { - var didItFall = false - val tree = TestTree() - try {tree.compareKeysT(intArrayOf(-18, 18), intArrayOf(1))} - catch (e : Exception) {didItFall = true} - assert(didItFall) - } -} diff --git a/lib/src/test/kotlin/TestTree.kt b/lib/src/test/kotlin/TestTree.kt deleted file mode 100644 index cbaa74a..0000000 --- a/lib/src/test/kotlin/TestTree.kt +++ /dev/null @@ -1,31 +0,0 @@ -import trees.AbstractBinarySearchTree -import vertexes.SimpleBSTVertex - -class TestTree : AbstractBinarySearchTree> { - - var removeShouldReturns : V? = null - var getShouldReturns : V? = null - val putWasCalledWithParams : MutableList> = mutableListOf() - - override fun put(key: K, value: V, replaceIfExists : Boolean) { - putWasCalledWithParams.add(Triple(key, value, replaceIfExists)) - } - - override fun remove(key: K) : V? {return removeShouldReturns} - - fun compareKeysT(firstKey: K, secondKey: K): Int { - return super.compareKeys(firstKey, secondKey) - } - constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : - super(comparator) { - this.root = root - this.size = size - } - - constructor (removeShouldReturns : V?) : super() {this.removeShouldReturns = removeShouldReturns} - - constructor (comparator: Comparator? = null) : super(comparator) - - constructor (map: Map, replaceIfExists: Boolean = true, - comparator: Comparator? = null) : super(map, replaceIfExists, comparator) -} diff --git a/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt b/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt index 177c166..02e80d2 100644 --- a/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt +++ b/lib/src/test/kotlin/trees/abstractTree/AbstractTreeTest.kt @@ -1,6 +1,8 @@ package trees.abstractTree -import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Test import vertexes.SimpleBSTVertex @@ -20,6 +22,7 @@ class AbstractTreeTest { val tree = makeEmptyTree() assertFalse(tree.isNotEmpty()) } + @Test fun `size() returns 0 if tree is empty`() { val tree = makeEmptyTree() @@ -218,8 +221,8 @@ class AbstractTreeTest { class CMP : Comparator { override fun compare( - o1: IntArray, - o2: IntArray, + o1: IntArray, + o2: IntArray, ): Int { return o1.sum() - o2.sum() } diff --git a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt index c74b3c0..578bb8d 100644 --- a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt +++ b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt @@ -28,9 +28,9 @@ class TestTree : AbstractBinarySearchTree> { } constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : super(comparator) { - this.root = root - this.size = size - } + this.root = root + this.size = size + } constructor (removeShouldReturns: V?) : super() { this.removeShouldReturns = removeShouldReturns diff --git a/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt b/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt index 3584853..3e932ea 100644 --- a/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt +++ b/lib/src/test/kotlin/trees/avlTree/AuxiliaryFunctions.kt @@ -4,8 +4,8 @@ import vertexes.AVLVertex object AuxiliaryFunctions { fun isTreeConsistsOf( - expectedContent: Set>, - tree: AVLTreeForTest, + expectedContent: Set>, + tree: AVLTreeForTest, ): Boolean { val vertexes = tree.getVertexesInDFSOrder() val pairsFromVertexes = (Array(vertexes.size) { i -> (vertexes[i].key to vertexes[i].value) }).toSet() @@ -13,9 +13,9 @@ object AuxiliaryFunctions { } fun isTreeSStructureThat( - tree: AVLTreeForTest, - order: Array, - deps: List>, + tree: AVLTreeForTest, + order: Array, + deps: List>, ): Boolean { // Triple consists of indexes in order of (1)vertex, one's (2)leftSon and (3)RightSon val vertexes = tree.getVertexesInDFSOrder() @@ -43,16 +43,16 @@ object AuxiliaryFunctions { if (vertexes.size != heights.size) return false for (vertex in vertexes) { val expectedSonsHeightDiff = - when ((vertex.leftSon == null) to (vertex.rightSon == null)) { - true to true -> 0 - true to false -> -1 - (heights[(vertex.rightSon as AVLVertex).key] ?: return false) - false to true -> 1 + (heights[(vertex.leftSon as AVLVertex).key] ?: return false) - else -> { - val heightOfLeftSubtree = heights[(vertex.leftSon as AVLVertex).key] ?: return false - val heightOfRightSubtree = heights[(vertex.rightSon as AVLVertex).key] ?: return false - heightOfLeftSubtree - heightOfRightSubtree - } + when ((vertex.leftSon == null) to (vertex.rightSon == null)) { + true to true -> 0 + true to false -> -1 - (heights[(vertex.rightSon as AVLVertex).key] ?: return false) + false to true -> 1 + (heights[(vertex.leftSon as AVLVertex).key] ?: return false) + else -> { + val heightOfLeftSubtree = heights[(vertex.leftSon as AVLVertex).key] ?: return false + val heightOfRightSubtree = heights[(vertex.rightSon as AVLVertex).key] ?: return false + heightOfLeftSubtree - heightOfRightSubtree } + } if (expectedSonsHeightDiff != vertex.sonsHeightDiff) return false } return true diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt index e133fcf..7beabd4 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToDoBigRotation.kt @@ -21,17 +21,17 @@ class HaveToDoBigRotation { val tree = makeTreeForHaveToDoBigLeftRotationPutTest() tree.put('f', 'F') val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'e' to 'E', - 'g' to 'G', - 'f' to 'F', - 'i' to 'I', - 'j' to 'J', - ) + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'g' to 'G', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -40,17 +40,17 @@ class HaveToDoBigRotation { val tree = makeTreeForHaveToDoBigLeftRotationPutTest() tree.put('h', 'H') val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'e' to 'E', - 'h' to 'H', - 'g' to 'G', - 'i' to 'I', - 'j' to 'J', - ) + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'g' to 'G', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -73,13 +73,13 @@ class HaveToDoBigRotation { val tree = makeTreeForHaveToDoBigLeftRotationPutTest() tree.put('f', 'F') val expectedDependencies = - listOf( - Triple(0, 1, 3), - Triple(1, 2, null), - Triple(3, 4, 7), - Triple(4, 5, 6), - Triple(7, null, 8), - ) + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 7), + Triple(4, 5, 6), + Triple(7, null, 8), + ) val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'f', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } @@ -89,13 +89,13 @@ class HaveToDoBigRotation { val tree = makeTreeForHaveToDoBigLeftRotationPutTest() tree.put('h', 'H') val expectedDependencies = - listOf( - Triple(0, 1, 3), - Triple(1, 2, null), - Triple(3, 4, 6), - Triple(4, 5, null), - Triple(6, 7, 8), - ) + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 6), + Triple(4, 5, null), + Triple(6, 7, 8), + ) val expectedOrder = arrayOf('c', 'b', 'a', 'g', 'e', 'd', 'i', 'h', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } @@ -127,17 +127,17 @@ class HaveToDoBigRotation { val tree = makeTreeForHaveToDoBigRightRotationPutTest() tree.put('c', 'C') val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'h' to 'H', - 'g' to 'G', - 'f' to 'F', - 'i' to 'I', - 'j' to 'J', - ) + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'h' to 'H', + 'g' to 'G', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -146,17 +146,17 @@ class HaveToDoBigRotation { val tree = makeTreeForHaveToDoBigRightRotationPutTest() tree.put('e', 'E') val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'f' to 'F', - 'd' to 'D', - 'e' to 'E', - 'h' to 'H', - 'g' to 'G', - 'i' to 'I', - 'j' to 'J', - ) + setOf( + 'a' to 'A', + 'b' to 'B', + 'f' to 'F', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'g' to 'G', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -179,13 +179,13 @@ class HaveToDoBigRotation { val tree = makeTreeForHaveToDoBigRightRotationPutTest() tree.put('c', 'C') val expectedDependencies = - listOf( - Triple(0, 1, 7), - Triple(7, null, 8), - Triple(1, 2, 5), - Triple(5, null, 6), - Triple(2, 3, 4), - ) + listOf( + Triple(0, 1, 7), + Triple(7, null, 8), + Triple(1, 2, 5), + Triple(5, null, 6), + Triple(2, 3, 4), + ) val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'c', 'f', 'g', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } @@ -195,13 +195,13 @@ class HaveToDoBigRotation { val tree = makeTreeForHaveToDoBigRightRotationPutTest() tree.put('e', 'E') val expectedDependencies = - listOf( - Triple(0, 1, 7), - Triple(7, null, 8), - Triple(1, 2, 4), - Triple(2, 3, null), - Triple(4, 5, 6), - ) + listOf( + Triple(0, 1, 7), + Triple(7, null, 8), + Triple(1, 2, 4), + Triple(2, 3, null), + Triple(4, 5, 6), + ) val expectedOrder = arrayOf('h', 'd', 'b', 'a', 'f', 'e', 'g', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt index f29c7d4..afc2ac4 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateLeft.kt @@ -14,22 +14,23 @@ class HaveToRotateLeft { val root = AVLVertex('c', 'C', AVLVertex('b', 'B', AVLVertex('a', 'A'), null, 1), rightSon, -1) return AVLTreeForTest(root, 8L) } + @Test fun `content is correct after entry was added`() { val tree = makeTreeForHaveToRotateLeftPutTest() tree.put('j', 'J') val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'e' to 'E', - 'h' to 'H', - 'f' to 'F', - 'i' to 'I', - 'j' to 'J', - ) + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -45,13 +46,13 @@ class HaveToRotateLeft { val tree = makeTreeForHaveToRotateLeftPutTest() tree.put('j', 'J') val expectedDependencies = - listOf( - Triple(0, 1, 3), - Triple(1, 2, null), - Triple(3, 4, 7), - Triple(4, 5, 6), - Triple(7, null, 8), - ) + listOf( + Triple(0, 1, 3), + Triple(1, 2, null), + Triple(3, 4, 7), + Triple(4, 5, 6), + Triple(7, null, 8), + ) val expectedOrder = arrayOf('c', 'b', 'a', 'h', 'e', 'd', 'f', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt index fadb7f4..a03fb71 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/HaveToRotateRight.kt @@ -20,17 +20,17 @@ class HaveToRotateRight { val tree = makeTreeForHaveToRotateRightPutTest() tree.put('a', 'A') val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'd' to 'D', - 'e' to 'E', - 'h' to 'H', - 'f' to 'F', - 'i' to 'I', - 'j' to 'J', - ) + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'd' to 'D', + 'e' to 'E', + 'h' to 'H', + 'f' to 'F', + 'i' to 'I', + 'j' to 'J', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -46,13 +46,13 @@ class HaveToRotateRight { val tree = makeTreeForHaveToRotateRightPutTest() tree.put('a', 'A') val expectedDependencies = - listOf( - Triple(0, 1, 7), - Triple(1, 2, 4), - Triple(2, 3, null), - Triple(4, 5, 6), - Triple(7, null, 8), - ) + listOf( + Triple(0, 1, 7), + Triple(1, 2, 4), + Triple(2, 3, null), + Triple(4, 5, 6), + Triple(7, null, 8), + ) val expectedOrder = arrayOf('h', 'c', 'b', 'a', 'f', 'd', 'e', 'i', 'j') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt b/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt index 0a7bb63..2793296 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/Other.kt @@ -24,4 +24,4 @@ class Other { val expectedContent = setOf('a' to 'A', 'b' to 'B') assert(isTreeConsistsOf(expectedContent, tree)) } -} \ No newline at end of file +} diff --git a/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt b/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt index 5787a46..d8cbb0c 100644 --- a/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt +++ b/lib/src/test/kotlin/trees/avlTree/putTest/WithoutBalancing.kt @@ -110,4 +110,3 @@ class WithoutBalancing { assert(isSonsHeightDiffCorrect(tree)) } } - diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt index 0738668..5ea88b7 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToDoBigRotation.kt @@ -1,11 +1,11 @@ package trees.avlTree.removeTest +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import vertexes.AVLVertex -import org.junit.jupiter.api.Test -import trees.avlTree.AVLTreeForTest class HaveToDoBigRotation { private fun makeTreeForBigLeftRotationChangesRootRemoveTest(): AVLTreeForTest { @@ -26,15 +26,15 @@ class HaveToDoBigRotation { val tree = makeTreeForBigLeftRotationChangesRootRemoveTest() tree.remove(' ') val expectedContent = - setOf( - 'd' to 'D', - 'c' to 'C', - 'e' to 'E', - 'f' to 'F', - 'g' to 'G', - 'b' to 'B', - 'a' to 'A', - ) + setOf( + 'd' to 'D', + 'c' to 'C', + 'e' to 'E', + 'f' to 'F', + 'g' to 'G', + 'b' to 'B', + 'a' to 'A', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -79,15 +79,15 @@ class HaveToDoBigRotation { val tree = makeTreeForBigRightRotationChangesRootRemoveTest() tree.remove('k') val expectedContent = - setOf( - 'a' to 1, - 'b' to 2, - 'c' to 3, - 'd' to 4, - 'e' to 5, - 'i' to 9, - 'f' to 8, - ) + setOf( + 'a' to 1, + 'b' to 2, + 'c' to 3, + 'd' to 4, + 'e' to 5, + 'i' to 9, + 'f' to 8, + ) assert(isTreeConsistsOf(expectedContent, tree)) } diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt index 9931ebd..a56fbd9 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateLeft.kt @@ -1,11 +1,11 @@ package trees.avlTree.removeTest +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import vertexes.AVLVertex -import org.junit.jupiter.api.Test -import trees.avlTree.AVLTreeForTest class HaveToRotateLeft { private fun makeTreeForRemoveWithLeftRotation1Test(): AVLTreeForTest { @@ -40,14 +40,14 @@ class HaveToRotateLeft { val tree = makeTreeForRemoveWithLeftRotation1Test() tree.remove('l') val expectedContent = - setOf( - 'k' to true, - 'i' to false, - 'm' to true, - 'o' to false, - 'p' to true, - 'a' to false, - ) + setOf( + 'k' to true, + 'i' to false, + 'm' to true, + 'o' to false, + 'p' to true, + 'a' to false, + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -56,15 +56,15 @@ class HaveToRotateLeft { val tree = makeTreeForRemoveWithLeftRotation2Test() tree.remove('l') val expectedContent = - setOf( - 'k' to true, - 'i' to false, - 'm' to true, - 'o' to false, - 'p' to true, - 'n' to true, - 'a' to false, - ) + setOf( + 'k' to true, + 'i' to false, + 'm' to true, + 'o' to false, + 'p' to true, + 'n' to true, + 'a' to false, + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -96,12 +96,12 @@ class HaveToRotateLeft { val tree = makeTreeForRemoveWithLeftRotation2Test() tree.remove('l') val expectedDependencies = - listOf( - Triple(0, 1, 3), - Triple(3, 4, 6), - Triple(4, null, 5), - Triple(1, 2, null), - ) + listOf( + Triple(0, 1, 3), + Triple(3, 4, 6), + Triple(4, null, 5), + Triple(1, 2, null), + ) val expectedOrder = arrayOf('k', 'i', 'a', 'o', 'm', 'n', 'p') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } @@ -161,5 +161,4 @@ class HaveToRotateLeft { tree.remove(0) assert(isSonsHeightDiffCorrect(tree)) } - -} \ No newline at end of file +} diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt index e4db51e..b30628b 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/HaveToRotateRight.kt @@ -1,11 +1,11 @@ package trees.avlTree.removeTest +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import vertexes.AVLVertex -import org.junit.jupiter.api.Test -import trees.avlTree.AVLTreeForTest class HaveToRotateRight { private fun makeTreeForRemoveWithRightRotation1Test(): AVLTreeForTest { @@ -40,14 +40,14 @@ class HaveToRotateRight { val tree = makeTreeForRemoveWithRightRotation1Test() tree.remove('e') val expectedContent = - setOf( - 'k' to true, - 'b' to true, - 'm' to true, - 'o' to false, - 'd' to true, - 'a' to false, - ) + setOf( + 'k' to true, + 'b' to true, + 'm' to true, + 'o' to false, + 'd' to true, + 'a' to false, + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -56,15 +56,15 @@ class HaveToRotateRight { val tree = makeTreeForRemoveWithRightRotation2Test() tree.remove('e') val expectedContent = - setOf( - 'k' to true, - 'b' to true, - 'm' to true, - 'o' to false, - 'd' to true, - 'a' to false, - 'c' to true, - ) + setOf( + 'k' to true, + 'b' to true, + 'm' to true, + 'o' to false, + 'd' to true, + 'a' to false, + 'c' to true, + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -96,12 +96,12 @@ class HaveToRotateRight { val tree = makeTreeForRemoveWithRightRotation2Test() tree.remove('e') val expectedDependencies = - listOf( - Triple(0, 1, 5), - Triple(1, 2, 3), - Triple(5, null, 6), - Triple(3, 4, null), - ) + listOf( + Triple(0, 1, 5), + Triple(1, 2, 3), + Triple(5, null, 6), + Triple(3, 4, null), + ) val expectedOrder = arrayOf('k', 'b', 'a', 'd', 'c', 'm', 'o') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } @@ -120,8 +120,6 @@ class HaveToRotateRight { assert(isSonsHeightDiffCorrect(tree)) } - - private fun makeTreeForRightRotationChangesRootRemoveTest(): AVLTreeForTest { val root = AVLVertex(-1, 1, AVLVertex(-3, 3, AVLVertex(-5, 5), AVLVertex(-2, 2)), AVLVertex(0, 0), 1) return AVLTreeForTest(root, 5L) @@ -163,4 +161,4 @@ class HaveToRotateRight { tree.remove(0) assert(isSonsHeightDiffCorrect(tree)) } -} \ No newline at end of file +} diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt index 0e714f6..bb47e57 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/Other.kt @@ -1,11 +1,11 @@ package trees.avlTree.removeTest.withoutBalancing +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import vertexes.AVLVertex -import org.junit.jupiter.api.Test -import trees.avlTree.AVLTreeForTest class Other { private fun makeEmptyTree(): AVLTreeForTest { diff --git a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt index 3e3516f..e793753 100644 --- a/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt +++ b/lib/src/test/kotlin/trees/avlTree/removeTest/withoutBalancing/VertexHadTwoSons.kt @@ -1,14 +1,13 @@ package trees.avlTree.removeTest.withoutBalancing +import org.junit.jupiter.api.Test +import trees.avlTree.AVLTreeForTest +import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import trees.avlTree.AuxiliaryFunctions.isTreeConsistsOf import trees.avlTree.AuxiliaryFunctions.isTreeSStructureThat -import trees.avlTree.AuxiliaryFunctions.isSonsHeightDiffCorrect import vertexes.AVLVertex -import org.junit.jupiter.api.Test -import trees.avlTree.AVLTreeForTest class VertexHadTwoSons { - private fun makeTreeForRemoveSonWithBothSons(): AVLTreeForTest { val eVrt = AVLVertex('e', 'E', AVLVertex('c', 'C'), null, 1) val bVrt = AVLVertex('b', 'B', AVLVertex('a', 'A'), eVrt, -1) @@ -30,20 +29,20 @@ class VertexHadTwoSons { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('f') val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'e' to 'E', - 'i' to 'I', - 'z' to 'Z', - 'k' to 'K', - 'n' to 'N', - 'u' to 'U', - 'q' to 'Q', - 's' to 'S', - 'w' to 'W', - ) + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'e' to 'E', + 'i' to 'I', + 'z' to 'Z', + 'k' to 'K', + 'n' to 'N', + 'u' to 'U', + 'q' to 'Q', + 's' to 'S', + 'w' to 'W', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -59,14 +58,14 @@ class VertexHadTwoSons { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('f') val expectedDependencies = - listOf( - Triple(0, 1, 7), - Triple(1, 2, 5), - Triple(2, 3, 4), - Triple(5, null, 6), - Triple(7, 8, 10), - Triple(10, null, 11), - ) + listOf( + Triple(0, 1, 7), + Triple(1, 2, 5), + Triple(2, 3, 4), + Triple(5, null, 6), + Triple(7, 8, 10), + Triple(10, null, 11), + ) val expectedOrder = arrayOf('n', 'e', 'b', 'a', 'c', 'i', 'k', 'u', 'q', 's', 'w', 'z') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } @@ -89,20 +88,20 @@ class VertexHadTwoSons { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('u') val expectedContent = - setOf( - 'a' to 'A', - 'b' to 'B', - 'c' to 'C', - 'e' to 'E', - 'i' to 'I', - 'z' to 'Z', - 'k' to 'K', - 'n' to 'N', - 'f' to 'F', - 'q' to 'Q', - 's' to 'S', - 'w' to 'W', - ) + setOf( + 'a' to 'A', + 'b' to 'B', + 'c' to 'C', + 'e' to 'E', + 'i' to 'I', + 'z' to 'Z', + 'k' to 'K', + 'n' to 'N', + 'f' to 'F', + 'q' to 'Q', + 's' to 'S', + 'w' to 'W', + ) assert(isTreeConsistsOf(expectedContent, tree)) } @@ -118,15 +117,15 @@ class VertexHadTwoSons { val tree = makeTreeForRemoveSonWithBothSons() tree.remove('u') val expectedDependencies = - listOf( - Triple(0, 1, 8), - Triple(1, 2, 6), - Triple(2, 3, 4), - Triple(6, null, 7), - Triple(4, 5, null), - Triple(8, 9, 10), - Triple(10, null, 11), - ) + listOf( + Triple(0, 1, 8), + Triple(1, 2, 6), + Triple(2, 3, 4), + Triple(6, null, 7), + Triple(4, 5, null), + Triple(8, 9, 10), + Triple(10, null, 11), + ) val expectedOrder = arrayOf('n', 'f', 'b', 'a', 'e', 'c', 'i', 'k', 's', 'q', 'w', 'z') assert(isTreeSStructureThat(tree, expectedOrder, expectedDependencies)) } diff --git a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt index afd94d4..2161bc6 100644 --- a/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt +++ b/lib/src/test/kotlin/trees/simpleBSTree/SimpleBSTForTest.kt @@ -214,8 +214,8 @@ class SimpleBSTForTest { mapOf( Pair(5, "five"), Pair(0, "zero"), - Pair(4, "four") - ) + Pair(4, "four"), + ), ) // 5 @@ -237,8 +237,8 @@ class SimpleBSTForTest { mapOf( Pair(5, "five"), Pair(0, "zero"), - Pair(-1, "minus_one") - ) + Pair(-1, "minus_one"), + ), ) // 5 @@ -262,8 +262,8 @@ class SimpleBSTForTest { Pair(0, "zero"), Pair(-1, "minus_one"), Pair(4, "four"), - Pair(3, "three") - ) + Pair(3, "three"), + ), ) // 5 @@ -337,8 +337,8 @@ class SimpleBSTForTest { Pair(5, "five"), Pair(10, "ten"), Pair(2, "two"), - Pair(6, "six") - ) + Pair(6, "six"), + ), ) // 1 From ac74e9d2d524936d32b666900a6fd05b1bd2a9cb Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 8 Apr 2024 09:33:15 +0300 Subject: [PATCH 227/227] style: final changes according to linter --- lib/src/test/kotlin/trees/abstractTree/TestTree.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt index 578bb8d..9974358 100644 --- a/lib/src/test/kotlin/trees/abstractTree/TestTree.kt +++ b/lib/src/test/kotlin/trees/abstractTree/TestTree.kt @@ -26,11 +26,12 @@ class TestTree : AbstractBinarySearchTree> { ): Int { return super.compareKeys(firstKey, secondKey) } + constructor (root: SimpleBSTVertex, size: Long, comparator: Comparator? = null) : super(comparator) { - this.root = root - this.size = size - } + this.root = root + this.size = size + } constructor (removeShouldReturns: V?) : super() { this.removeShouldReturns = removeShouldReturns