From 28fbb1c559c62dcca8aef7d3d6a7ef0da9f76126 Mon Sep 17 00:00:00 2001 From: HossamSaberr Date: Fri, 27 Feb 2026 18:40:05 +0200 Subject: [PATCH 1/2] Optimize copy method from O(N log N) to O(N) --- .../CTAVLTreeTest.class.st | 72 +++++++++++++++++++ src/Containers-AVL-Tree/CTAVLNilNode.class.st | 5 ++ src/Containers-AVL-Tree/CTAVLNode.class.st | 13 ++++ src/Containers-AVL-Tree/CTAVLTree.class.st | 15 ++-- 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/src/Containers-AVL-Tree-Tests/CTAVLTreeTest.class.st b/src/Containers-AVL-Tree-Tests/CTAVLTreeTest.class.st index 5b11674..a4726f4 100644 --- a/src/Containers-AVL-Tree-Tests/CTAVLTreeTest.class.st +++ b/src/Containers-AVL-Tree-Tests/CTAVLTreeTest.class.st @@ -119,6 +119,78 @@ CTAVLTreeTest >> testCopy [ self assert: (copiedTree includes: 99) ] +{ #category : 'tests' } +CTAVLTreeTest >> testCopyEmptyTree [ + | copiedTree | + + copiedTree := tree copy. + + self assert: copiedTree isEmpty. + self assert: copiedTree size equals: 0. + self assert: copiedTree height equals: 0. + + self deny: copiedTree == tree. +] + +{ #category : 'tests' } +CTAVLTreeTest >> testCopyLargeTree [ + | copiedTree elements | + + elements := (1 to: 1000) asArray shuffled. + tree addAll: elements. + + copiedTree := tree copy. + + self assert: copiedTree size equals: 1000. + self assert: copiedTree height equals: tree height. + self assert: copiedTree validate. + + self assert: copiedTree asArray equals: tree asArray. +] + +{ #category : 'tests' } +CTAVLTreeTest >> testCopySingleNode [ + | copiedTree | + + tree add: 42. + copiedTree := tree copy. + + self assert: copiedTree size equals: 1. + self assert: copiedTree height equals: 1. + self assert: copiedTree root contents equals: 42. + + self deny: copiedTree root == tree root. + self assert: copiedTree validate. +] + +{ #category : 'tests' } +CTAVLTreeTest >> testCopyStructureAndIsolation [ + | copiedTree | + + tree addAll: #(50 30 70 20 40 60 80). + copiedTree := tree copy. + + self assert: copiedTree size equals: tree size. + self assert: copiedTree height equals: tree height. + self assert: copiedTree asArray equals: tree asArray. + self assert: copiedTree validate. + + self deny: copiedTree root == tree root. + self deny: copiedTree root left == tree root left. + + copiedTree add: 99. + copiedTree remove: 20. + + self assert: (copiedTree includes: 99). + self deny: (tree includes: 99). + + self deny: (copiedTree includes: 20). + self assert: (tree includes: 20). + + self assert: tree validate. + self assert: copiedTree validate. +] + { #category : 'tests' } CTAVLTreeTest >> testDetect [ diff --git a/src/Containers-AVL-Tree/CTAVLNilNode.class.st b/src/Containers-AVL-Tree/CTAVLNilNode.class.st index 109ad48..5fc8d42 100644 --- a/src/Containers-AVL-Tree/CTAVLNilNode.class.st +++ b/src/Containers-AVL-Tree/CTAVLNilNode.class.st @@ -37,6 +37,11 @@ CTAVLNilNode >> contents: anObject [ "Do nothing for nil node" ] +{ #category : 'copying' } +CTAVLNilNode >> copy [ + ^ self class new +] + { #category : 'enumerating' } CTAVLNilNode >> elementsFrom: min to: max into: aCollection [ diff --git a/src/Containers-AVL-Tree/CTAVLNode.class.st b/src/Containers-AVL-Tree/CTAVLNode.class.st index 7e36f2d..79d1875 100644 --- a/src/Containers-AVL-Tree/CTAVLNode.class.st +++ b/src/Containers-AVL-Tree/CTAVLNode.class.st @@ -60,6 +60,19 @@ CTAVLNode >> contents: anObject [ contents := anObject ] +{ #category : 'copying' } +CTAVLNode >> copy [ + | newNode | + newNode := self class new. + newNode contents: contents. + newNode left: left copy. + newNode right: right copy. + + newNode instVarNamed: 'height' put: height. + + ^ newNode +] + { #category : 'enumerating' } CTAVLNode >> elementsFrom: min to: max into: aCollection [ diff --git a/src/Containers-AVL-Tree/CTAVLTree.class.st b/src/Containers-AVL-Tree/CTAVLTree.class.st index 300c453..c48ec65 100644 --- a/src/Containers-AVL-Tree/CTAVLTree.class.st +++ b/src/Containers-AVL-Tree/CTAVLTree.class.st @@ -92,15 +92,6 @@ CTAVLTree >> collect: aBlock [ ^ result ] -{ #category : 'copying' } -CTAVLTree >> copy [ - - | newTree | - newTree := self class new. - self inOrderDo: [ :each | newTree add: each ]. - ^ newTree -] - { #category : 'enumerating' } CTAVLTree >> detect: aBlock ifNone: absentBlock [ @@ -236,6 +227,12 @@ CTAVLTree >> last [ ^ self findMax ] +{ #category : 'copying' } +CTAVLTree >> postCopy [ + super postCopy. + root := root copy. +] + { #category : 'enumerating' } CTAVLTree >> postOrderDo: aBlock [ From da9dc6744cf479f410c51b14ac2533519837c255 Mon Sep 17 00:00:00 2001 From: HossamSaberr Date: Sun, 1 Mar 2026 14:38:37 +0200 Subject: [PATCH 2/2] fix: Refactor CTAVLNode copy to postCopy and add testCopyLeafNode --- .../CTAVLTreeTest.class.st | 15 +++++++++++++ src/Containers-AVL-Tree/CTAVLNode.class.st | 21 +++++++------------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/Containers-AVL-Tree-Tests/CTAVLTreeTest.class.st b/src/Containers-AVL-Tree-Tests/CTAVLTreeTest.class.st index a4726f4..3a28b5f 100644 --- a/src/Containers-AVL-Tree-Tests/CTAVLTreeTest.class.st +++ b/src/Containers-AVL-Tree-Tests/CTAVLTreeTest.class.st @@ -148,6 +148,21 @@ CTAVLTreeTest >> testCopyLargeTree [ self assert: copiedTree asArray equals: tree asArray. ] +{ #category : 'tests' } +CTAVLTreeTest >> testCopyLeafNode [ + | node copiedNode | + node := CTAVLNode new contents: 42. + + copiedNode := node copy. + + self assert: copiedNode contents equals: 42. + self deny: node == copiedNode. + + self assert: copiedNode height equals: 1. + self assert: copiedNode left isNilNode. + self assert: copiedNode right isNilNode +] + { #category : 'tests' } CTAVLTreeTest >> testCopySingleNode [ | copiedTree | diff --git a/src/Containers-AVL-Tree/CTAVLNode.class.st b/src/Containers-AVL-Tree/CTAVLNode.class.st index 79d1875..232b2b5 100644 --- a/src/Containers-AVL-Tree/CTAVLNode.class.st +++ b/src/Containers-AVL-Tree/CTAVLNode.class.st @@ -60,19 +60,6 @@ CTAVLNode >> contents: anObject [ contents := anObject ] -{ #category : 'copying' } -CTAVLNode >> copy [ - | newNode | - newNode := self class new. - newNode contents: contents. - newNode left: left copy. - newNode right: right copy. - - newNode instVarNamed: 'height' put: height. - - ^ newNode -] - { #category : 'enumerating' } CTAVLNode >> elementsFrom: min to: max into: aCollection [ @@ -186,6 +173,14 @@ CTAVLNode >> left: aNode [ aNode ifNotNil: [ aNode parent: self ] ] +{ #category : 'copying' } +CTAVLNode >> postCopy [ + super postCopy. + + left isNilNode ifFalse: [ left := left copy ]. + right isNilNode ifFalse: [ right := right copy ] +] + { #category : 'enumerating' } CTAVLNode >> postOrderDo: aBlock [