Go语言数据结构与算法-栈

先进后出

应用

示例代码:

container/list标准库实现
package main

import (
	"container/list"
	"fmt"
	"sync"
)

type Stack struct {
	l    *list.List
	lock *sync.RWMutex
}

// NewStack 初始化
func NewStack() *Stack {
	l := list.New()
	lock := &sync.RWMutex{}
	return &Stack{l: l, lock: lock}
}

// Push 向栈内添加元素
func (s *Stack) Push(value interface{}) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.l.PushBack(value)
}

// Pop 删除栈顶元素
func (s *Stack) Pop() interface{} {
	s.lock.Lock()
	defer s.lock.Unlock()
	back := s.l.Back()
	if back == nil {
		return nil
	}
	return s.l.Remove(back)
}

// Peak 获取栈顶元素
func (s *Stack) Peak() interface{} {
	s.lock.RLock()
	defer s.lock.RUnlock()
	back := s.l.Back()
	if back == nil {
		return nil
	}
	return back.Value
}

// Len 获取栈长度
func (s *Stack) Len() int {
	s.lock.RLock()
	defer s.lock.RUnlock()
	return s.l.Len()
}

// Empty 栈是否为空
func (s *Stack) Empty() bool {
	s.lock.RLock()
	defer s.lock.RUnlock()
	return s.l.Len() == 0
}

// TraversList 展开栈元素
func (s *Stack) TraversList() {
	s.lock.RLock()
	defer s.lock.RUnlock()
	tail := s.l.Back()
	for tail != nil {
		fmt.Printf("%v ", tail.Value)
		tail = tail.Prev()
	}
	fmt.Println()
}

func main() {
	l := NewStack()
	l.Push(1)
	l.Push(2)
	l.Push(3)
	l.TraversList()
	l.Pop()
	l.TraversList()
}


>>>>>>
3 2 1 
2 1 
自己动手实现
package main

import (
	"fmt"
	"sync"
)

type (
	node struct {
		value interface{}
		prev  *node
	}
	MyStack struct {
		top    *node
		lock   *sync.RWMutex
		length int
	}
)

func NewMyStack() *MyStack {
	return &MyStack{nil, &sync.RWMutex{}, 0}
}

func (s *MyStack) Push(value interface{}) {
	s.lock.Lock()
	defer s.lock.Unlock()
	n := &node{value, s.top}
	s.top = n
	s.length++
}

func (s *MyStack) Pop() interface{} {
	s.lock.Lock()
	defer s.lock.Unlock()
	if s.length == 0 {
		return nil
	}
	n := s.top
	s.top = n.prev
	s.length--
	return n.value
}

func (s *MyStack) Peak() interface{} {
	s.lock.RLock()
	defer s.lock.RUnlock()
	if s.length == 0 {
		return nil
	}
	return s.top.value
}

func (s *MyStack) Len() int {
	return s.length
}

func (s *MyStack) Empty() bool {
	return s.length == 0
}

func (s *MyStack) Traverse() {
	s.lock.RLock()
	defer s.lock.RUnlock()
	prev := s.top
	for prev != nil {
		fmt.Printf("%v ", prev.value)
		prev = prev.prev
	}
	fmt.Println()
}

func main() {
	l := NewMyStack()
	l.Push(1)
	l.Push(2)
	l.Push(3)
	l.Traverse()
	l.Pop()
	l.Traverse()
}


>>>>>>
3 2 1 
2 1 
基准性能测试
package main

import "testing"

func BenchmarkStackPush(b *testing.B) {
	stack := NewStack()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		stack.Push(i)
	}
}

func BenchmarkStackPop(b *testing.B) {
	stack := NewStack()
	for i := 0; i < b.N; i++ {
		stack.Push(i)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		stack.Pop()
	}
}

func BenchmarkMyStackPush(b *testing.B) {
	stack := NewMyStack()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		stack.Push(i)
	}
}

func BenchmarkMyStackPop(b *testing.B) {
	stack := NewMyStack()
	for i := 0; i < b.N; i++ {
		stack.Push(i)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		stack.Pop()
	}
}


>>>>>>>go test -bench=.
goos: windows
goarch: amd64
pkg: stack
cpu: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
BenchmarkStackPush-8             4805720               262.1 ns/op
BenchmarkStackPop-8             32913938                79.80 ns/op
BenchmarkMyStackPush-8           8849811               152.2 ns/op
BenchmarkMyStackPop-8           36459424                32.58 ns/op
PASS
ok      stack   24.069s

通过上述性能测试可以看出自己实现性能更优

posted @ 2022-02-17 21:51  自己有自己的调调、  阅读(64)  评论(0编辑  收藏  举报