IntList / IntListElt CS 313 Smalltalk linked list example Also serves as an example for how you could organize your code for the printed submission of homework 5 part 2. Class IntListElt ================ Object subclass:#IntListElt instanceVariableNames:'val next' classVariableNames:'' poolDictionaries:'' category:'DanielsClasses' Class methods ------------- none (the accessor methods val: and next: will be used to initialize the instance variables) Instance methods ---------------- val: anInt "set the value of the instance variable 'val'" val := anInt. val "return the value of the instance variable 'val'" ^ val. next: anIntListElt "set the value of the instance variable 'next'" next := anIntListElt. next "return the value of the instance variable 'next'" ^ next. lengthR "returns length of list (recursive version)" "called by IntList's instance method lengthR" (next == nil) ifTrue: [ ^ 1 ]. ^ 1 + (next lengthR). maxR "returns maximum value in list (recursive version)" "called by IntList's instance method maxR" (next == nil) ifTrue: [ ^ val ]. ^ val max: (next maxR). do: aBlock "execute aBlock for all elements in list" aBlock value: val. next ~~ nil ifTrue: [ next do: aBlock ] Class IntList ============= Object subclass:#IntList instanceVariableNames:'head' classVariableNames:'' poolDictionaries:'' category:'DanielsClasses' Class methods ------------- none ("new" will initialize "head" to nil, which is just what we want) Instance methods ---------------- isEmpty "returns whether list is empty" ^ (head == nil). head "returns first integer in the list" "assert: list not empty" self isEmpty ifTrue: [self error: 'cannot get head of empty list']. ^ head val. add: anInt "inserts anInt at the head of the list" | e | e := IntListElt new. e val: anInt. e next: head. head := e. remove "removes first element in the list and returns its value" "assert: list not empty" | v | self isEmpty ifTrue: [self error: 'cannot remove from empty list']. v := head val. head := head next. ^ v. length "returns length of list" | n e | n := 0. e := head. [ e ~~ nil ] whileTrue: [ n := n + 1. e := e next ]. ^n. lengthR "returns length of list (recursive version)" "most of the work is done by IntListElt's instance method lengthR" self isEmpty ifTrue: [ ^ 0 ]. ^ head lengthR. max "returns maximum value in list" "assert: list not empty" | m e | self isEmpty ifTrue: [self error: 'cannot compute max of empty list']. m := head val. e := head next. [ e ~~ nil ] whileTrue: [ (e val > m) ifTrue: [ m := e val ]. e := e next ]. ^m. maxR "returns maximum value in list (recursive version)" "all of the work is done by IntListElt's instance method maxR" "assert: list not empty" self isEmpty ifTrue: [self error: 'cannot compute max of empty list']. ^ head maxR. do: aBlock "execute aBlock for all elements in list" self isEmpty ifFalse: [ head do: aBlock ] Testing and sample output ========================= |t| t:= IntList new. 'Testing IntList methods on list (0, 4, 2, 3)' printCR. t add: 3. t add: 2. t add: 4. t add: 0. 'max: ' print. t max printCR. 'isEmpty: ' print. t isEmpty printCR. 'length: ' print. t length printCR. 'remove: ' print. t remove printCR. 'lengthR: ' print. t lengthR printCR. 'do: [:x | x printCR ]' printCR. t do: [:x | x printCR ]. 'remove: ' print. t remove printCR. 'max: ' print. t max printCR. 'maxR: ' print. t maxR printCR. 'remove: ' print. t remove printCR. 'isEmpty: ' print. t isEmpty printCR. 'remove: ' print. t remove printCR. 'isEmpty: ' print. t isEmpty printCR. output (produced using "doIt" on the code above): ------------------------------------------------- Testing IntList methods on list (0, 4, 2, 3) max: 4 isEmpty: false length: 4 remove: 0 lengthR: 3 do: [:x | x printCR ] 4 2 3 remove: 4 max: 3 maxR: 3 remove: 2 isEmpty: false remove: 3 isEmpty: true