添加优先链表
This commit is contained in:
parent
979b01e251
commit
a07c58bef4
18
priority_list/plist_node.go
Normal file
18
priority_list/plist_node.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package plist
|
||||
|
||||
// NodeInt plist 现成的Int节点, 可以作为例子
|
||||
type NodeInt struct {
|
||||
Node
|
||||
}
|
||||
|
||||
// Compare plist 现成的Int节点Compare覆盖
|
||||
func (fl *NodeInt) Compare(v INode) bool {
|
||||
return fl.GetValue().(int) > v.GetValue().(int)
|
||||
}
|
||||
|
||||
// NewNodeInt plist 现成的Int节点, New一个NodeInt
|
||||
func NewNodeInt(v int) (fl *NodeInt) {
|
||||
fl = new(NodeInt)
|
||||
fl.SetValue(v)
|
||||
return fl
|
||||
}
|
270
priority_list/priority_list.go
Normal file
270
priority_list/priority_list.go
Normal file
|
@ -0,0 +1,270 @@
|
|||
package plist
|
||||
|
||||
import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// INode 比较的必须继承的接口
|
||||
type INode interface {
|
||||
Compare(v INode) bool
|
||||
|
||||
// GetValue 获取值
|
||||
GetValue() interface{}
|
||||
// SetValue 设置值
|
||||
SetValue(v interface{})
|
||||
|
||||
GetPrev() INode
|
||||
SetPrev(INode)
|
||||
GetNext() INode
|
||||
SetNext(INode)
|
||||
}
|
||||
|
||||
// Node 优先链表的节点
|
||||
type Node struct {
|
||||
INode
|
||||
prev, next INode
|
||||
// isrelease bool
|
||||
value interface{}
|
||||
}
|
||||
|
||||
// NewNode 创建一个PriorityList 节点
|
||||
func NewNode(v interface{}) *Node {
|
||||
n := new(Node)
|
||||
n.SetValue(v)
|
||||
return n
|
||||
}
|
||||
|
||||
// GetValue 获取值
|
||||
func (node *Node) GetValue() interface{} {
|
||||
return node.value
|
||||
}
|
||||
|
||||
// SetValue 设置值
|
||||
func (node *Node) SetValue(v interface{}) {
|
||||
node.value = v
|
||||
}
|
||||
|
||||
// GetPrev 获取left值
|
||||
func (node *Node) GetPrev() INode {
|
||||
return node.prev
|
||||
}
|
||||
|
||||
// SetPrev 设置left值
|
||||
func (node *Node) SetPrev(n INode) {
|
||||
node.prev = n
|
||||
}
|
||||
|
||||
// GetNext 设置right值
|
||||
func (node *Node) GetNext() INode {
|
||||
return node.next
|
||||
}
|
||||
|
||||
// SetNext 获取left值
|
||||
func (node *Node) SetNext(n INode) {
|
||||
node.next = n
|
||||
}
|
||||
|
||||
func (node *Node) String() string {
|
||||
return spew.Sprint(node.value)
|
||||
}
|
||||
|
||||
// PriorityList 优先列表
|
||||
type PriorityList struct {
|
||||
head INode
|
||||
tail INode
|
||||
|
||||
size int
|
||||
}
|
||||
|
||||
// Size 长度
|
||||
func (pl *PriorityList) Size() int {
|
||||
return pl.size
|
||||
}
|
||||
|
||||
// Clear 清空链表, 如果外部有引用其中一个节点 要把节点Prev Next值为nil, 三色标记
|
||||
func (pl *PriorityList) Clear() {
|
||||
pl.head = nil
|
||||
pl.tail = nil
|
||||
pl.size = 0
|
||||
}
|
||||
|
||||
// Get 获取索引长度
|
||||
func (pl *PriorityList) Get(idx int) INode {
|
||||
if idx >= pl.size {
|
||||
return nil
|
||||
}
|
||||
cur := pl.head
|
||||
for i := 0; i < idx; i++ {
|
||||
cur = cur.GetNext()
|
||||
}
|
||||
return cur
|
||||
}
|
||||
|
||||
// GetReverse 腻序获取索引长度
|
||||
func (pl *PriorityList) GetReverse(idx int) INode {
|
||||
if idx >= pl.size {
|
||||
return nil
|
||||
}
|
||||
cur := pl.tail
|
||||
for i := 0; i < idx; i++ {
|
||||
cur = cur.GetPrev()
|
||||
}
|
||||
return cur
|
||||
}
|
||||
|
||||
// Remove 删除节点
|
||||
func (pl *PriorityList) Remove(node INode) {
|
||||
|
||||
if pl.size <= 1 {
|
||||
pl.head = nil
|
||||
pl.tail = nil
|
||||
if pl.size == 0 {
|
||||
panic("the node is not in this list, node:" + spew.Sprint(node))
|
||||
}
|
||||
pl.size = 0
|
||||
return
|
||||
}
|
||||
|
||||
pl.size--
|
||||
prev := node.GetPrev()
|
||||
next := node.GetNext()
|
||||
|
||||
if prev == nil {
|
||||
pl.head = next
|
||||
next.SetPrev(nil)
|
||||
node.SetNext(nil)
|
||||
} else if next == nil {
|
||||
pl.tail = prev
|
||||
prev.SetNext(nil)
|
||||
node.SetPrev(nil)
|
||||
} else {
|
||||
prev.SetNext(next)
|
||||
next.SetPrev(prev)
|
||||
|
||||
node.SetPrev(nil)
|
||||
node.SetNext(nil)
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveIndex 删除节点 并获取该节点
|
||||
func (pl *PriorityList) RemoveIndex(idx int) INode {
|
||||
result := pl.Get(idx)
|
||||
pl.Remove(result)
|
||||
return result
|
||||
// if idx >= pl.size {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// pl.size--
|
||||
|
||||
// var cur INode
|
||||
// if pl.size == 1 {
|
||||
// cur = pl.head
|
||||
// pl.head = nil
|
||||
// pl.tail = nil
|
||||
|
||||
// if cur == nil {
|
||||
// panic("why cur == nil?")
|
||||
// }
|
||||
|
||||
// return cur
|
||||
// }
|
||||
|
||||
// cur = pl.head
|
||||
// for i := 0; i < idx; i++ {
|
||||
// cur = cur.GetNext()
|
||||
// }
|
||||
|
||||
// prev := cur.GetPrev()
|
||||
// next := cur.GetNext()
|
||||
|
||||
// if prev == nil {
|
||||
// pl.head = next
|
||||
// pl.head.SetPrev(nil)
|
||||
// } else if next == nil {
|
||||
// pl.tail = prev
|
||||
// pl.tail.SetNext(nil)
|
||||
// } else {
|
||||
// prev.SetNext(next)
|
||||
// next.SetPrev(prev)
|
||||
// }
|
||||
|
||||
// cur.SetNext(nil)
|
||||
// cur.SetPrev(nil)
|
||||
|
||||
// if cur == nil {
|
||||
// panic("why cur == nil?")
|
||||
// }
|
||||
|
||||
// return cur
|
||||
}
|
||||
|
||||
// RemoveReverseIndex 逆顺序删除节点 并获取该节点
|
||||
func (pl *PriorityList) RemoveReverseIndex(idx int) INode {
|
||||
result := pl.GetReverse(idx)
|
||||
pl.Remove(result)
|
||||
return result
|
||||
}
|
||||
|
||||
func (pl *PriorityList) String() string {
|
||||
content := "["
|
||||
|
||||
cur := pl.head
|
||||
for cur != nil {
|
||||
content += spew.Sprint(cur.GetValue()) + ","
|
||||
cur = cur.GetNext()
|
||||
}
|
||||
|
||||
if content[len(content)-1:] == "," {
|
||||
content = content[:len(content)-1]
|
||||
}
|
||||
|
||||
content += "]"
|
||||
return content
|
||||
}
|
||||
|
||||
// Insert 插入节点
|
||||
func (pl *PriorityList) Insert(node INode) {
|
||||
pl.size++
|
||||
if pl.head == nil {
|
||||
pl.head = node
|
||||
pl.tail = node
|
||||
return
|
||||
}
|
||||
|
||||
cur := pl.head
|
||||
for {
|
||||
if !cur.Compare(node) {
|
||||
// 插入该值
|
||||
prev := cur.GetPrev()
|
||||
if prev == nil {
|
||||
pl.head.SetPrev(node)
|
||||
node.SetNext(pl.head)
|
||||
pl.head = node
|
||||
} else {
|
||||
prev.SetNext(node)
|
||||
node.SetNext(cur)
|
||||
cur.SetPrev(node)
|
||||
node.SetPrev(prev)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
next := cur.GetNext()
|
||||
if next == nil {
|
||||
cur.SetNext(node)
|
||||
node.SetPrev(cur)
|
||||
pl.tail = node
|
||||
return
|
||||
}
|
||||
cur = next
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// New 创建 PriorityList
|
||||
func New() *PriorityList {
|
||||
return new(PriorityList)
|
||||
}
|
77
priority_list/priority_list_test.go
Normal file
77
priority_list/priority_list_test.go
Normal file
|
@ -0,0 +1,77 @@
|
|||
package plist
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestPriority(t *testing.T) {
|
||||
pl := New()
|
||||
|
||||
pl.Insert(NewNodeInt(1))
|
||||
pl.Insert(NewNodeInt(2))
|
||||
pl.Insert(NewNodeInt(3))
|
||||
if pl.String() != "[3,2,1]" {
|
||||
t.Error("Insert or String error", pl.String())
|
||||
}
|
||||
|
||||
if pl.Get(0).GetValue() != 3 {
|
||||
t.Error(pl.Get(0).GetValue())
|
||||
}
|
||||
|
||||
if pl.Get(pl.Size()-1).GetValue() != 1 {
|
||||
t.Error(pl.Get(pl.Size() - 1).GetValue())
|
||||
}
|
||||
|
||||
if pl.Size() != 3 {
|
||||
t.Error("size error, current is", pl.Size())
|
||||
}
|
||||
|
||||
pl.Remove(pl.Get(2))
|
||||
if pl.String() != "[3,2]" || pl.Size() != 2 {
|
||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
||||
}
|
||||
|
||||
pl.Remove(pl.GetReverse(0))
|
||||
if pl.String() != "[3]" || pl.Size() != 1 {
|
||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
||||
}
|
||||
|
||||
pl.Remove(pl.Get(0))
|
||||
if pl.String() != "[]" || pl.Size() != 0 {
|
||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
||||
}
|
||||
|
||||
pl.Insert(NewNodeInt(6))
|
||||
pl.Insert(NewNodeInt(5))
|
||||
pl.Insert(NewNodeInt(7))
|
||||
pl.Insert(NewNodeInt(12))
|
||||
pl.Insert(NewNodeInt(8))
|
||||
if pl.String() != "[12,8,7,6,5]" || pl.Size() != 5 {
|
||||
t.Error("Insert or String error, current is ", pl.String(), pl.Size())
|
||||
}
|
||||
|
||||
pl.RemoveReverseIndex(3)
|
||||
if pl.String() != "[12,7,6,5]" || pl.Size() != 4 {
|
||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
||||
}
|
||||
|
||||
t.Log("size is", pl.Size())
|
||||
size := pl.Size()
|
||||
for i := 0; i < size; i++ {
|
||||
pl.RemoveReverseIndex(0)
|
||||
t.Log(i)
|
||||
}
|
||||
if pl.String() != "[]" || pl.Size() != 0 {
|
||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
||||
}
|
||||
|
||||
pl.Insert(NewNodeInt(6))
|
||||
pl.Insert(NewNodeInt(5))
|
||||
pl.Insert(NewNodeInt(7))
|
||||
pl.Insert(NewNodeInt(12))
|
||||
pl.Insert(NewNodeInt(8))
|
||||
|
||||
pl.Clear()
|
||||
|
||||
if pl.String() != "[]" || pl.Size() != 0 {
|
||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user