package imitate import ( "log" "strings" "github.com/davecgh/go-spew/spew" ) // Node 循环链表 三色标记 不确定是否会清除循环引用, 网上说会 type Node struct { value interface{} prev *Node next *Node } // GetValue 获取到Node的值 func (node *Node) GetValue() interface{} { return node.value } // SetValue 获取到Node的值 func (node *Node) SetValue(value interface{}) { node.value = value } // CircularLinked 循环链表 type CircularLinked struct { cursor *Node head *Node tail *Node size uint64 } // NewCircularLinked create a CircularLinked func NewCircularLinked(values ...interface{}) *CircularLinked { list := &CircularLinked{} if len(values) > 0 { list.Append(values...) } return list } // Cursor get current Cursor func (list *CircularLinked) Cursor() *Node { if list.cursor == nil { list.cursor = list.head } return list.cursor } // CursorNext get next Cursor func (list *CircularLinked) CursorNext() *Node { if list.cursor == nil { list.cursor = list.head } list.cursor = list.cursor.next return list.cursor } // CursorPrev get prev Cursor func (list *CircularLinked) CursorPrev() *Node { if list.cursor == nil { list.cursor = list.head } list.cursor = list.cursor.prev return list.cursor } // CursorToHead cursor move to head func (list *CircularLinked) CursorToHead() *Node { list.cursor = list.head return list.cursor } // CursorToTail cursor move to tail func (list *CircularLinked) CursorToTail() *Node { list.cursor = list.tail return list.cursor } // GetLoopValues 获取从头到尾的值 func (list *CircularLinked) GetLoopValues() []*Node { var result []*Node if list.head != nil { result = append(result, list.head) for cur := list.head.next; cur != list.head; cur = cur.next { result = append(result, cur) } } return result } // Append a value (one or more) at the end of the list (same as Append()) func (list *CircularLinked) Append(values ...interface{}) { for _, value := range values { node := &Node{value: value} if list.size == 0 { list.head = node list.tail = node node.next = node node.prev = node } else { list.tail.next = node node.next = list.head node.prev = list.tail list.tail = node } list.size++ } } // Remove 移除一些节点 func (list *CircularLinked) Remove(node *Node) { switch list.size { case 0: list.errorNotInList(node) case 1: if list.head == node { list.head = nil list.tail = nil node.next = nil node.prev = nil list.cursor = nil list.size-- } else { list.errorNotInList(node) } case 2: node.prev = nil node.next = nil switch node { case list.head: list.head = list.tail list.tail.prev = list.head list.head.next = list.tail list.cursor = list.head list.size-- case list.tail: list.tail = list.head list.tail.prev = list.head list.head.next = list.tail list.cursor = list.head list.size-- default: list.errorNotInList(node) } default: switch node { case list.head: _, next := list.cutAndSplice(node) list.size-- list.head = next if list.cursor == node { list.cursor = next } case list.tail: prev, _ := list.cutAndSplice(node) list.size-- list.tail = prev if list.cursor == node { list.cursor = prev } default: _, next := list.cutAndSplice(node) list.size-- if list.cursor == node { list.cursor = next } } } } // LookCursor for list show func (list *CircularLinked) LookCursor() string { cursor := list.Cursor() content := "->[" cur := list.head if list.size != 0 { for size := uint64(0); size < list.size; size++ { if cursor == cur { content += "(" + spew.Sprint(cur.value) + ")" + ", " } else { content += spew.Sprint(cur.value) + ", " } cur = cur.next } } content = strings.TrimRight(content, ", ") showlen := len(content) if showlen >= 64 { showlen = 64 } content += "]" + content[0:showlen] + " ..." return content } // Clear for list show func (list *CircularLinked) Clear() { if list.size != 0 { list.head.prev = nil list.tail.next = nil list.head = nil list.tail = nil list.cursor = nil list.size = 0 } } // Size for list show func (list *CircularLinked) Size() uint64 { return list.size } func (list *CircularLinked) errorNotInList(node *Node) { log.Println("the node value ", spew.Sprint(node), " is not in list") } // cutAndSplice 不考虑边界情况 上层使用的是否判断 func (list *CircularLinked) cutAndSplice(node *Node) (prev, next *Node) { prev = node.prev next = node.next prev.next = next next.prev = prev node.prev = nil node.next = nil return prev, next }