>백엔드 개발 >Golang >golang에서 스택을 디자인하는 방법

golang에서 스택을 디자인하는 방법

(*-*)浩
(*-*)浩원래의
2019-12-31 13:01:002564검색

golang에서 스택을 디자인하는 방법

스택은 삽입과 삭제를 한 위치로만 제한하는 테이블로, 테이블의 끝이자 스택의 탑(Top)이라고 부른다 .

스택을 LIFO(선입선출) 테이블이라고도 합니다.                                                                     (배우는 것이 좋습니다: go #🎜🎜 #

스택에 대한 작업에는 전자인 Push(푸시)와 P op(팝)가 포함됩니다. 삽입은 마지막으로 삽입된 요소를 삭제하는 것과 같습니다.

다음은 이중 연결 목록과 슬라이스를 사용하여 각각 스택 작업을 구현합니다

//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에서 스택을 디자인하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.