Solution Review: Implement Stack Data Structure
This lesson discusses the solution to the challenge given in the previous lesson.
We'll cover the following...
package mainimport ("fmt""strconv")const LIMIT = 4 // DONOT CHANGE IT!type Stack struct {ix int // first free position, so data[ix] == 0data [LIMIT]int}func (st *Stack) Push(n int) {if st.ix == LIMIT {return // stack is full!}st.data[st.ix] = nst.ix++ // increment total no. of elements present}func (st *Stack) Pop() int {if st.ix >0{ // if stack not emptyst.ix-- // decrease amount of elements presentelement := st.data[st.ix]st.data[st.ix] = 0return element}return -1 // if stack already empty}func (st Stack) String() string {str := ""for ix := 0; ix < st.ix; ix++ {str += "[" + strconv.Itoa(ix) + ":" + strconv.Itoa(st.data[ix]) + "]"}return str}func main() {st1 := new(Stack)fmt.Printf("%v\n", st1)st1.Push(3) // function call to Pushfmt.Printf("%v\n", st1)st1.Push(7) // function call to Pushfmt.Printf("%v\n", st1)st1.Push(10) // function call to Pushfmt.Printf("%v\n", st1)st1.Push(99) // function call to Pushfmt.Printf("%v\n", st1)p := st1.Pop() // function call to Popfmt.Printf("Popped %d\n", p)fmt.Printf("%v\n", st1)p = st1.Pop() // function call to Popfmt.Printf("Popped %d\n", p)fmt.Printf("%v\n", st1)p = st1.Pop() // function call to Popfmt.Printf("Popped %d\n", p)fmt.Printf("%v\n", st1)p = st1.Pop() // function call to Popfmt.Printf("Popped %d\n", p)fmt.Printf("%v\n", st1)}
In the above code, look at line 8. As per the requirement to generalize the implementation, we make a constant LIMIT
and set its value to 4. This means that our stack can, at maximum hold four values. Now that we have defined the limit of the stack, we make a struct of type Stack
at line 10. It has two fields. The first field is an integer field ix
that keeps track of how many elements are currently in the stack. The next field is an array of integers data
of capacity LIMIT
. It keeps track of the elements that are present in a stack. When you declare a Stack
type variable, ix
will be 0 and the data
array will hold four zeros, initially. Now, let’s see how the basic functionalities (push and pop) of the stack are implemented.
Look at the header of method Push
at line 15: func (st *Stack) Push(n int)
. The header makes it clear that only the pointer to the stack object can call this method, and n
is the element that is to be pushed in the stack. Now, the question is, would you push every time? No, you can’t push every single time because what if the stack is full (ix
equals LIMIT
) and you are trying to push an element at the top. In that case, it would give an error. Look at line 16, we start the implementation from this condition: if st.ix == LIMIT
. If this condition is satisfied( ix
of the stack st
is equal to LIMIT
), then control will ...