首頁  >  文章  >  後端開發  >  golang 怎麼設計一個堆疊

golang 怎麼設計一個堆疊

(*-*)浩
(*-*)浩原創
2019-12-31 13:01:002508瀏覽

golang 怎麼設計一個堆疊

#堆疊是限制插入和刪除只能在一個位置上進行的表,該位置是表的末端,稱為堆疊頂部。

堆疊有時又叫LIFO(先進後出)表。                                                           中下嘗試((),()(D),為對堆疊插入的操作中找到之前,刪除最後插入的元素。

以下用雙向鍊錶和切片實作分別實作堆疊操作

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