From 0d85520d4f0f7689c22ee13416efa58b2c4659d7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 6 Apr 2024 14:21:20 +0300 Subject: [PATCH 01/52] 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 02/52] 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 03/52] 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 04/52] 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 05/52] 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 06/52] 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 07/52] 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 08/52] 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 09/52] 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 10/52] 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 11/52] 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 12/52] 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 13/52] 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 14/52] 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 15/52] 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 16/52] 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 17/52] 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 18/52] 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 19/52] 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 20/52] 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 21/52] 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 22/52] 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 23/52] 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 24/52] 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 25/52] 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 26/52] 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 27/52] 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 28/52] 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 29/52] 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 30/52] 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 31/52] 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 32/52] 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 33/52] 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 34/52] 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 35/52] 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 36/52] 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 37/52] 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 38/52] 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 39/52] 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 40/52] 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 41/52] 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 42/52] 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 43/52] 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 44/52] 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 45/52] 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 46/52] 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 47/52] 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 48/52] 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 49/52] 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 50/52] 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 51/52] 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 52/52] 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