生命不止,繼續 go go go !!!
今天跟大家分享一下資料介紹相關的實現吧,那就以連結串列為例吧。
golang中為我們提供了一個list,我們先了解一下container/list。
container/list功能:Package list implements a doubly linked list.
看清楚了吧,是雙向連結串列。
一些方法:func (e *Element) Next() *Element返回該元素的下一個元素,如果沒有下一個元素則返回nil
func (e *Element) Prev() *Element返回該元素的前一個元素,如果沒有前一個元素則返回nil。
func New() *List返回一個初始化的list
func (l *List) Back() *Element獲取list l的最後一個元素
func (l *List) Front() *Element獲取list l的第一個元素
func (l *List) Init() *Listlist l初始化或者清除list l
func (l *List) InsertAfter(v interface{}, mark *Element) *Element在list l中元素mark之後插入一個值為v的元素,並返回該元素,如果mark不是list中元素,則list不改變。
func (l *List) InsertBefore(v interface{}, mark *Element) *Element在list l中元素mark之前插入一個值為v的元素,並返回該元素,如果mark不是list中元素,則list不改變。
func (l *List) Len() int獲取list l的長度
func (l *List) MoveAfter(e, mark *Element)將元素e移動到元素mark之後,如果元素e或者mark不屬於list l,或者e==mark,則list l不改變。
func (l *List) MoveBefore(e, mark *Element)將元素e移動到元素mark之前,如果元素e或者mark不屬於list l,或者e==mark,則list l不改變。
func (l *List) MoveToBack(e *Element)將元素e移動到list l的末尾,如果e不屬於list l,則list不改變。
func (l *List) MoveToFront(e *Element)將元素e移動到list l的首部,如果e不屬於list l,則list不改變。
func (l *List) PushBack(v interface{}) *Element在list l的末尾插入值為v的元素,並返回該元素。
func (l *List) PushBackList(other *List)在list l的尾部插入另外一個list,其中l和other可以相等。
func (l *List) PushFront(v interface{}) *Element在list l的首部插入值為v的元素,並返回該元素。
func (l *List) PushFrontList(other *List)在list l的首部插入另外一個list,其中l和other可以相等。
簡單的應用:
package main import ( "container/list" "fmt" ) func main() { // 建立一個連結串列 alist := list.New() fmt.Println("Size before : ", alist.Len()) //向連結串列中新增元素 alist.PushBack("a") alist.PushBack("b") alist.PushBack("c") fmt.Println("Size after insert(push): ", alist.Len()) // 遍歷 for e := alist.Front(); e != nil; e = e.Next() { fmt.Println(e.Value.(string)) } //移除元素 alist.Remove(alist.Front()) alist.Remove(alist.Front()) alist.Remove(alist.Front()) fmt.Println("Size after remove(pop) : ", alist.Len()) }123456789101112131415161718192021222324252627282930313233
輸出:Size before : 0Size after insert(push): 3abcSize after remove(pop) : 0
實現一個單向連結串列go為我們提供的list是一個雙向連結串列,那麼我們自己實現一個單向連結串列吧。
宣告節點
package singly_linked_listtype Node struct { Value interface{} next *Node}func (n *Node) Next() *Node { return n.next}1234567891011
type SinglyLinkedList struct { front *Node length int}1234
初始化這個不是main中的init
func (s *SinglyLinkedList) Init() *SinglyLinkedList { s.length = 0 return s}1234
New一個連結串列
func New() *SinglyLinkedList { return new(SinglyLinkedList).Init()}123
返回頭結點
func (s *SinglyLinkedList) Front() *Node { return s.front}123
返回尾結點
func (s *SinglyLinkedList) Back() *Node { currentNode := s.front for currentNode != nil && currentNode.next != nil { currentNode = currentNode.next } return currentNode}1234567
新增尾結點
func (s *SinglyLinkedList) Append(n *Node) { if s.front == nil { s.front = n } else { currentNode := s.front for currentNode.next != nil { currentNode = currentNode.next } currentNode.next = n } s.length++}123456789101112131415
新增頭結點
func (s *SinglyLinkedList) Prepend(n *Node) { if s.front == nil { s.front = n } else { n.next = s.front s.front = n } s.length++}12345678910
在指定結點前新增結點
func (s *SinglyLinkedList) InsertBefore(insert *Node, before *Node) { if s.front == before { insert.next = before s.front = insert s.length++ } else { currentNode := s.front for currentNode != nil && currentNode.next != nil && currentNode.next != before { currentNode = currentNode.next } if currentNode.next == before { insert.next = before currentNode.next = insert s.length++ } }}123456789101112131415161718
在指定結點後新增結點
func (s *SinglyLinkedList) InsertAfter(insert *Node, after *Node) { currentNode := s.front for currentNode != nil && currentNode != after && currentNode.next != nil { currentNode = currentNode.next } if currentNode == after { insert.next = after.next after.next = insert s.length++ }}123456789101112
刪除指定結點
func (s *SinglyLinkedList) Remove(n *Node) { if s.front == n { s.front = n.next s.length-- } else { currentNode := s.front // search for node n for currentNode != nil && currentNode.next != nil && currentNode.next != n { currentNode = currentNode.next } // see if current's next node is n // if it's not n, then node n wasn't found in list s if currentNode.next == n { currentNode.next = currentNode.next.next s.length-- } }}1234567891011121314151617181920