Maison >développement back-end >Golang >Comment concevoir une pile en Golang

Comment concevoir une pile en Golang

(*-*)浩
(*-*)浩original
2019-12-31 13:01:002584parcourir

Comment concevoir une pile en Golang

Une pile est un tableau qui limite l'insertion et la suppression à une seule position, qui est la fin du tableau et est appelée le haut de la pile.

La pile est parfois appelée table LIFO (premier entré, dernier sorti). (Apprentissage recommandé : GO )

Le fonctionnement de la pile est PUSH (entrée) et POP (hors de la pile). Le premier équivaut à insérer Supprimer. le dernier élément inséré.

Ce qui suit utilise des listes et des tranches doublement liées pour implémenter respectivement les opérations de pile

//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))
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn