golang實現簡單的棧
阿新 • • 發佈:2019-01-06
棧的ADT
資料
棧的資料物件集合為{a1,a2,a3...an},具有相同資料型別,有唯一前驅後續
操作
- InitStack() *Stack //初始化操作,建立一個空棧
- Clear() //清空棧
- IsEmpty() bool //棧是否為空,若棧為空,返回 true,否則 返回 false。
- Peek() interface{} //若棧存在且非空,返回棧頂元素。
- Push(data interface{}) //將資料data壓入棧
- Pop() //若棧不為空,出棧
- Length() int //返回棧中元素個數
程式碼實現
stack.go
package stack import ( "sync" ) type Stack struct { data []interface{} length int capacity int sync.Mutex } // 構建一個空棧 func InitStack() *Stack { return &Stack{data: make([]interface{}, 8), length: 0, capacity: 8} } // 壓棧操作 func (s *Stack) Push(data interface{}) { s.Lock() defer s.Unlock() if s.length+1 >= s.capacity { s.capacity <<= 1 t := s.data s.data = make([]interface{}, s.capacity) copy(s.data, t) } s.data[s.length] = data s.length++ } // 出棧操作 func (s *Stack) Pop() interface{} { s.Lock() defer s.Unlock() if s.length <= 0 { panic("int stack pop: index out of range") } t := s.data[s.length-1] s.data = s.data[:s.length-1] s.length-- return t } // 返回棧頂元素 func (s *Stack) Peek() interface{} { s.Lock() defer s.Unlock() if s.length <= 0 { panic("empty stack") } return s.data[s.length-1] } // 返回當前棧元素個數 func (s *Stack) Count() int { s.Lock() defer s.Unlock() t := s.length return t } // 清空棧 func (s *Stack) Clear() { s.Lock() defer s.Unlock() s.data = make([]interface{}, 8) s.length = 0 s.capacity = 8 } // 棧是否為空 func (s *Stack) IsEmpty() bool { s.Lock() defer s.Unlock() b := s.length == 0 return b }
stack_test.go
package stack import ( "testing" gcv "github.com/smartystreets/goconvey/convey" ) func TestInitStack(t *testing.T) { s := InitStack() gcv.Convey("棧不應該為空", t, func() { gcv.So(s, gcv.ShouldNotBeNil) }) } func TestPush(t *testing.T) { s := InitStack() for i := 0; i < 100; i++ { s.Push(i) } gcv.Convey("入棧測試", t, func() { gcv.Convey("棧大小應該為100", func() { gcv.So(s.length, gcv.ShouldEqual, 100) }) gcv.Convey("棧中元素應該為0-99", func() { gcv.So(func() bool { for i := 0; i < 100; i++ { if s.data[i] != i { return false } } return true }(), gcv.ShouldEqual, true) }) }) } func TestPop(t *testing.T) { gcv.Convey("出棧測試", t, func() { gcv.Convey("棧中元素應該為99-0", func() { gcv.So(func() bool { s := InitStack() for i := 0; i < 100; i++ { s.Push(i) } for i := 99; i > -1; i-- { t := s.Pop().(int) if t != i { return false } } return true }(), gcv.ShouldEqual, true) }) }) } func TestPeek(t *testing.T) { gcv.Convey("棧頂操作", t, func() { s := InitStack() s.Push(1) s.Push(2) tmp := s.Peek().(int) gcv.So(tmp, gcv.ShouldEqual, 2) }) }