golang之樹的遍歷
go語言在區塊鏈程式設計中有巨大的優勢,其中fabric和ethereum都是基於go語言編寫的。為了能更好的學習區塊鏈的底層技術,先將go的基礎打好。
本篇文章使用golang來實現樹的遍歷
樹的定義
package tree type Node struct { Val int Left *Node Right *Node }
深度優先遍歷
深度優先遍歷需要優先使用棧
棧的定義
type Stack struct { list *list.List } func NewStack() *Stack { list := list.New() return &Stack{list} } func (stack *Stack) Push(value interface{}) { stack.list.PushBack(value) } func (stack *Stack) Pop() interface{} { if e := stack.list.Back(); e!= nil { stack.list.Remove(e) return e.Value } return nil } func (stack *Stack) Len() int { return stack.list.Len() } func (stack *Stack) Empty() bool { return stack.Len() == 0 }
前序遍歷
為Stack結構體新增前序遍歷的方法,前序遍歷的思路是通過棧,將右子樹先行壓棧,然後左子樹壓棧
func (root *Node) PreTravesal() { if root == nil { return } s := stack.NewStack() s.push(root) for !s.Empty() { cur := s.Pop().(*Node) fmt.Println(cur.Val) if cur.Right != nil { s.Push(cur.Right) } if cur.Left != nil { s.Push(cur.Left) } } }
中序遍歷
func (root *Node) InTravesal() { if root == nil { return } s := stack.NewStack() cur := root for { for cur != nil { s.Push(cur) cur = cur.Left } if s.Empty() { break } cur = s.Pop().(*Node) fmt.Println(cur.Val) cur = cur.right } }
後序遍歷
func (root *Node) PostTravesal() { if root == nil { return } s := stack.NewStack() out := stack.NewStack() s.Push(root) for !s.Empty() { cur := s.Pop().(*Node) out.Push(cur) if cur.Left != nil { s.Push(cur.Left) } if cur.Right != nil { s.Push(cur.Right) } } for !out.Empty() { cur := out.Pop().(*Node) fmt.Println(cur.Val) } }
廣度優先遍歷
廣度優先遍歷需要使用到佇列
實現佇列
使用切片實現佇列
package queue import ( "fmt" ) type Queue interface { Offer(e interface{}) Poll() interface{} Clear() bool Size() int IsEmpty() bool } type LinkedList struct { elements []interface{} } func New() *LinkedList { return &LinkedList{} } func (queue *LinkedList) Offer(e interface{}) { queue.elements = append(queue.elements, e) } func (queue *LinkedList) Poll() interface{} { if queue.IsEmpty() { fmt.Println("Poll error : queue is Empty") return nil } firstElement := queue.elements[0] queue.elements = queue.elements[1:] return firstElement } func (queue *LinkedList) Size() int { return len(queue.elements) } func (queue *LinkedList) IsEmpty() bool { return len(queue.elements) == 0 } func (queue *LinkedList) Clear() bool{ if queue.IsEmpty() { fmt.Println("queue is Empty!") return false } for i := 0; i < queue.Size(); i++ { queue.elements[i] = nil } queue.elements = nil return true }
層序遍歷
func (root *Node) LevelTravesal() { if root == nil { return } linkedList := queue.New() linkedList.Offer(root) for !linkedList.IsEmpty(){ cur := linkedList.Poll().(*Node) fmt.Println(cur.Val) if cur.Left != nil { linkedList.Offer(cur.Left) } if cur.Right != nil { linkedList.Offer(cur.Right) } } }