您好,登錄后才能下訂單哦!
棧是限制插入和刪除只能在一個位置上進行的表,該位置是表的末端,叫做棧頂。
棧有時又叫LIFO(先進后出)表。
對棧的操作有Push(進棧)和Pop(出棧),前者相當于插入,后者相當于刪除最后插入的元素。
以下用雙向鏈表和切片實現分別實現棧操作
//stack //用雙向鏈表實現stack type Element interface {} var header *entry //鏈表表頭 var size int //棧的長度 type entry struct { previous *entry next *entry element Element } func newEntry(prev,next *entry,e Element) *entry { return &entry{prev,next,e} } //初始化header 表頭 func NewStack() *entry { header = newEntry(nil,nil,nil) header.previous =header header.next = header return header } type Stack interface { Push(e Element) //向棧頂添加元素 Pop() Element //移除棧頂元素 Top() Element //獲取棧頂元素(不刪除) Clear() bool //清空棧 Size() int //獲取棧的元素個數 IsEmpty() bool //判斷棧是否是空棧 } //向棧頂添加元素 func (e *entry) Push(element Element) { addBefore(header,element) } //移除棧頂元素 func (e *entry) Pop() Element { if e.IsEmpty() { fmt.Println("stack is empty!") return nil } prevEntry := header.previous prevEntry.previous.next = header header.previous = prevEntry.previous size-- return prevEntry.element } //獲取棧頂元素(不刪除) func (e *entry) Top() Element { if e.IsEmpty() { fmt.Println("stack is empty!") return nil } return header.previous.element } //清空棧 func (e *entry) Clear() bool { if e.IsEmpty() { fmt.Println("stack is empty!") return false } entry := header.next for entry != header { nextEntry := entry.next entry.next = nil entry.previous = nil entry.element = nil entry = nextEntry } header.next = header header.previous = header size =0 return true } func (e *entry) Size() int { return size } func (e *entry) IsEmpty() bool { if size == 0 { return true } return false } //在entry節點之前添加 func addBefore(e *entry,element Element) Element{ newEntry := newEntry(e.previous,e,element) newEntry.previous.next = newEntry newEntry.next.previous = newEntry size++ return newEntry } //**************************************** //**************************************** //用切片實現Stack type sliceEntry struct{ element []Element } func NewSliceEntry() *sliceEntry { return &sliceEntry{} } func (entry *sliceEntry)Push(e Element) { entry.element = append(entry.element,e) } func (entry *sliceEntry)Pop() Element { size := entry.Size() if size == 0 { fmt.Println("stack is empty!") return nil } lastElement := entry.element[size-1] entry.element[size-1] = nil entry.element = entry.element[:size-1] return lastElement } func (entry *sliceEntry)Top() Element { size := entry.Size() if size == 0 { fmt.Println("stack is empty!") return nil } return entry.element[size-1] } func (entry *sliceEntry)Clear() bool { if entry.IsEmpty() { fmt.Println("stack is empty!") return false } for i :=0;i<entry.Size();i++ { entry.element[i] = nil } entry.element = make([]Element,0) return true } func (entry *sliceEntry)Size() int { return len(entry.element) } func (entry *sliceEntry)IsEmpty() bool { if len(entry.element) == 0 { return true } return false } func main() { test1() } //測試雙向鏈表實現的Stack func test1() { stack := NewStack() for i := 0;i<50;i++ { stack.Push(i) } fmt.Println(stack.Top()) fmt.Println(stack.Size()) fmt.Println(stack.Pop()) fmt.Println(stack.Top()) fmt.Println(stack.Clear()) fmt.Println(stack.IsEmpty()) for i := 0;i<50;i++ { stack.Push(i) } fmt.Println(stack.Top()) } //測試切片實現的Stack func test2() { entry := NewSliceEntry() for i:= 0;i<50;i++ { entry.Push(i) } fmt.Println(entry.Size()) fmt.Println(entry.Top()) fmt.Println(entry.Pop()) fmt.Println(entry.Top(),entry.Size()) fmt.Println(entry.Clear()) for i:= 0;i<50;i++ { entry.Push(i) } fmt.Println(entry.Size()) } //兩種方法性能比較 func test3() { t := time.Now() sliceStack := NewSliceEntry() for i:= 0;i<500000;i++ { sliceStack.Push(i) } fmt.Println(time.Since(t)) t = time.Now() stack := NewStack() for i:=0;i<500000;i++ { stack.Push(i) } fmt.Println(time.Since(t)) }
以上就是golang 怎么設計一個棧的詳細內容,更多請關注億速云其它相關文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。